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:
-rw-r--r--CMakeLists.txt4
-rw-r--r--Makefile21
-rw-r--r--SConstruct1
-rw-r--r--blenderplayer/CMakeLists.txt1
-rw-r--r--config/linux2-config.py1
-rw-r--r--extern/CMakeLists.txt5
-rw-r--r--extern/Makefile4
-rw-r--r--extern/SConscript4
-rw-r--r--extern/bFTGL/src/Makefile14
-rw-r--r--extern/binreloc/Makefile5
-rw-r--r--extern/bullet2/Makefile4
-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/glew/src/Makefile14
-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--extern/ode/Makefile110
-rw-r--r--extern/ode/dist/INSTALL44
-rw-r--r--extern/ode/dist/LICENSE-BSD.TXT34
-rw-r--r--extern/ode/dist/LICENSE.TXT502
-rw-r--r--extern/ode/dist/Makefile280
-rw-r--r--extern/ode/dist/Makefile.deps456
-rw-r--r--extern/ode/dist/README30
-rw-r--r--extern/ode/dist/README_BLENDER18
-rw-r--r--extern/ode/dist/config/README41
-rw-r--r--extern/ode/dist/config/makefile.cygwin28
-rw-r--r--extern/ode/dist/config/makefile.mingw28
-rw-r--r--extern/ode/dist/config/makefile.msvc27
-rw-r--r--extern/ode/dist/config/makefile.msvc-dll29
-rw-r--r--extern/ode/dist/config/makefile.osx26
-rw-r--r--extern/ode/dist/config/makefile.unix-gcc29
-rw-r--r--extern/ode/dist/config/makefile.unix-generic24
-rw-r--r--extern/ode/dist/config/msvcdefs.def228
-rw-r--r--extern/ode/dist/config/user-settings31
-rw-r--r--extern/ode/dist/config/user-settings.example31
-rw-r--r--extern/ode/dist/configurator.c437
-rw-r--r--extern/ode/dist/include/ode/README18
-rw-r--r--extern/ode/dist/include/ode/common.h307
-rw-r--r--extern/ode/dist/include/ode/contact.h91
-rw-r--r--extern/ode/dist/include/ode/error.h64
-rw-r--r--extern/ode/dist/include/ode/geom.h153
-rw-r--r--extern/ode/dist/include/ode/mass.h98
-rw-r--r--extern/ode/dist/include/ode/matrix.h195
-rw-r--r--extern/ode/dist/include/ode/memory.h64
-rw-r--r--extern/ode/dist/include/ode/misc.h86
-rw-r--r--extern/ode/dist/include/ode/objects.h202
-rw-r--r--extern/ode/dist/include/ode/ode.h45
-rw-r--r--extern/ode/dist/include/ode/odecpp.h797
-rw-r--r--extern/ode/dist/include/ode/odecpp_old.h317
-rw-r--r--extern/ode/dist/include/ode/odemath.h217
-rw-r--r--extern/ode/dist/include/ode/rotation.h65
-rw-r--r--extern/ode/dist/include/ode/space.h78
-rw-r--r--extern/ode/dist/include/ode/timer.h77
-rw-r--r--extern/ode/dist/ode/README158
-rw-r--r--extern/ode/dist/ode/fbuild/BuildDot148
-rw-r--r--extern/ode/dist/ode/fbuild/BuildLDLT654
-rw-r--r--extern/ode/dist/ode/fbuild/BuildMultidot174
-rw-r--r--extern/ode/dist/ode/fbuild/BuildUtil99
-rw-r--r--extern/ode/dist/ode/fbuild/Dependencies16
-rw-r--r--extern/ode/dist/ode/fbuild/Makefile77
-rw-r--r--extern/ode/dist/ode/fbuild/OptimizeDot71
-rw-r--r--extern/ode/dist/ode/fbuild/OptimizeLDLT91
-rw-r--r--extern/ode/dist/ode/fbuild/OptimizeLSolve76
-rw-r--r--extern/ode/dist/ode/fbuild/OptimizeLTSolve76
-rw-r--r--extern/ode/dist/ode/fbuild/OptimizeMultidot73
-rw-r--r--extern/ode/dist/ode/fbuild/OptimizeUtil86
-rw-r--r--extern/ode/dist/ode/fbuild/ParametersD.example32
-rw-r--r--extern/ode/dist/ode/fbuild/ParametersF.example30
-rw-r--r--extern/ode/dist/ode/fbuild/ParametersM.example32
-rw-r--r--extern/ode/dist/ode/fbuild/ParametersS.example30
-rw-r--r--extern/ode/dist/ode/fbuild/ParametersT.example30
-rw-r--r--extern/ode/dist/ode/fbuild/README41
-rw-r--r--extern/ode/dist/ode/fbuild/ldlt.m26
-rw-r--r--extern/ode/dist/ode/fbuild/test_dot.cpp124
-rw-r--r--extern/ode/dist/ode/fbuild/test_ldlt.cpp299
-rw-r--r--extern/ode/dist/ode/fbuild/test_multidot.cpp144
-rw-r--r--extern/ode/dist/ode/src/array.cpp80
-rw-r--r--extern/ode/dist/ode/src/array.h135
-rw-r--r--extern/ode/dist/ode/src/error.cpp172
-rw-r--r--extern/ode/dist/ode/src/fastdot.c30
-rw-r--r--extern/ode/dist/ode/src/fastldlt.c381
-rw-r--r--extern/ode/dist/ode/src/fastlsolve.c298
-rw-r--r--extern/ode/dist/ode/src/fastltsolve.c199
-rw-r--r--extern/ode/dist/ode/src/geom.cpp2207
-rw-r--r--extern/ode/dist/ode/src/geom_internal.h83
-rw-r--r--extern/ode/dist/ode/src/joint.cpp2160
-rw-r--r--extern/ode/dist/ode/src/joint.h260
-rw-r--r--extern/ode/dist/ode/src/lcp.cpp1455
-rw-r--r--extern/ode/dist/ode/src/lcp.h59
-rw-r--r--extern/ode/dist/ode/src/mass.cpp261
-rw-r--r--extern/ode/dist/ode/src/mat.cpp230
-rw-r--r--extern/ode/dist/ode/src/mat.h72
-rw-r--r--extern/ode/dist/ode/src/matrix.cpp358
-rw-r--r--extern/ode/dist/ode/src/memory.cpp278
-rw-r--r--extern/ode/dist/ode/src/misc.cpp147
-rw-r--r--extern/ode/dist/ode/src/objects.h91
-rw-r--r--extern/ode/dist/ode/src/obstack.cpp130
-rw-r--r--extern/ode/dist/ode/src/obstack.h69
-rw-r--r--extern/ode/dist/ode/src/ode.cpp1341
-rw-r--r--extern/ode/dist/ode/src/odemath.cpp173
-rw-r--r--extern/ode/dist/ode/src/rotation.cpp283
-rw-r--r--extern/ode/dist/ode/src/scrapbook.cpp270
-rw-r--r--extern/ode/dist/ode/src/space.cpp621
-rw-r--r--extern/ode/dist/ode/src/stack.cpp114
-rw-r--r--extern/ode/dist/ode/src/stack.h139
-rw-r--r--extern/ode/dist/ode/src/step.cpp1085
-rw-r--r--extern/ode/dist/ode/src/step.h37
-rw-r--r--extern/ode/dist/ode/src/testing.cpp243
-rw-r--r--extern/ode/dist/ode/src/testing.h66
-rw-r--r--extern/ode/dist/ode/src/timer.cpp397
-rwxr-xr-xextern/ode/dist/tools/build442
-rwxr-xr-xextern/ode/dist/tools/build4.bat43
-rwxr-xr-xextern/ode/dist/tools/make_distribution45
-rwxr-xr-xextern/ode/dist/tools/process_deps11
-rw-r--r--extern/ode/patchfile.FreeBSD22
-rw-r--r--extern/qhull/src/Makefile15
-rw-r--r--extern/solid/Makefile15
-rw-r--r--intern/SoundSystem/Makefile15
-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/bmfont/Makefile15
-rw-r--r--intern/boolop/Makefile15
-rw-r--r--intern/bsp/Makefile17
-rw-r--r--intern/container/Makefile12
-rw-r--r--intern/decimation/Makefile15
-rw-r--r--intern/decimation/SConscript2
-rw-r--r--intern/elbeem/Makefile15
-rw-r--r--intern/ghost/Makefile15
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp48
-rw-r--r--intern/ghost/intern/Makefile6
-rw-r--r--intern/guardedalloc/Makefile15
-rw-r--r--intern/iksolver/Makefile15
-rw-r--r--intern/memutil/Makefile15
-rw-r--r--intern/moto/Makefile15
-rw-r--r--intern/opennl/Makefile24
-rw-r--r--intern/opennl/SConscript4
-rw-r--r--intern/opennl/superlu/get_perm_c.c4
-rw-r--r--intern/string/Makefile15
-rw-r--r--po/Makefile41
-rw-r--r--projectfiles_vc9/blender/blender.vcproj4
-rw-r--r--projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj2
-rw-r--r--projectfiles_vc9/blender/editors/ED_editors.vcproj36
-rw-r--r--projectfiles_vc9/blender/imbuf/BL_imbuf.vcproj8
-rw-r--r--projectfiles_vc9/blender/makesdna/DNA_makesdna.vcproj6
-rw-r--r--projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj4
-rw-r--r--projectfiles_vc9/blender/makesrna/RNA_rna.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/datafiles/blenderbuttonsbin123869 -> 131097 bytes
-rw-r--r--release/datafiles/prviconsbin13732 -> 9534 bytes
-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/Makefile101
-rw-r--r--source/blender/Makefile5
-rw-r--r--source/blender/blenfont/BLF_api.h3
-rw-r--r--source/blender/blenfont/intern/blf.c35
-rw-r--r--source/blender/blenfont/intern/blf_font.c12
-rw-r--r--source/blender/blenfont/intern/blf_font_helv10.h487
-rw-r--r--source/blender/blenfont/intern/blf_internal.c290
-rw-r--r--source/blender/blenfont/intern/blf_internal.h2
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h18
-rw-r--r--source/blender/blenkernel/BKE_brush.h2
-rw-r--r--source/blender/blenkernel/BKE_context.h97
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h32
-rw-r--r--source/blender/blenkernel/BKE_ipo.h2
-rw-r--r--source/blender/blenkernel/BKE_node.h44
-rw-r--r--source/blender/blenkernel/BKE_screen.h46
-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/anim.c27
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c15
-rw-r--r--source/blender/blenkernel/intern/constraint.c12
-rw-r--r--source/blender/blenkernel/intern/context.c228
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c2
-rw-r--r--source/blender/blenkernel/intern/exotic.c4
-rw-r--r--source/blender/blenkernel/intern/fcurve.c398
-rw-r--r--source/blender/blenkernel/intern/ipo.c50
-rw-r--r--source/blender/blenkernel/intern/modifier.c23
-rw-r--r--source/blender/blenkernel/intern/node.c14
-rw-r--r--source/blender/blenkernel/intern/object.c29
-rw-r--r--source/blender/blenkernel/intern/particle_system.c4
-rw-r--r--source/blender/blenkernel/intern/scene.c2
-rw-r--r--source/blender/blenkernel/intern/screen.c28
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c28
-rw-r--r--source/blender/blenkernel/intern/sequence.c21
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c11
-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/BLI_string.h6
-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/blenlib/intern/storage.c35
-rw-r--r--source/blender/blenlib/intern/string.c19
-rw-r--r--source/blender/blenloader/intern/readfile.c108
-rw-r--r--source/blender/blenloader/intern/writefile.c43
-rw-r--r--source/blender/blenpluginapi/iff.h6
-rw-r--r--source/blender/editors/CMakeLists.txt4
-rw-r--r--source/blender/editors/animation/anim_channels.c62
-rw-r--r--source/blender/editors/animation/anim_filter.c22
-rw-r--r--source/blender/editors/animation/anim_markers.c49
-rw-r--r--source/blender/editors/animation/anim_ops.c8
-rw-r--r--source/blender/editors/animation/keyframes_draw.c4
-rw-r--r--source/blender/editors/animation/keyframes_general.c10
-rw-r--r--source/blender/editors/animation/keyframing.c55
-rw-r--r--source/blender/editors/armature/BIF_generate.h45
-rw-r--r--source/blender/editors/armature/BIF_retarget.h160
-rw-r--r--source/blender/editors/armature/armature_intern.h46
-rw-r--r--source/blender/editors/armature/armature_ops.c65
-rw-r--r--source/blender/editors/armature/editarmature.c522
-rw-r--r--source/blender/editors/armature/editarmature_generate.c329
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c2961
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c3368
-rw-r--r--source/blender/editors/armature/poseobject.c4
-rw-r--r--source/blender/editors/armature/reeb.c3725
-rw-r--r--source/blender/editors/armature/reeb.h39
-rw-r--r--source/blender/editors/curve/curve_intern.h28
-rw-r--r--source/blender/editors/curve/curve_ops.c50
-rw-r--r--source/blender/editors/curve/editcurve.c100
-rw-r--r--source/blender/editors/curve/editfont.c20
-rw-r--r--source/blender/editors/datafiles/blenderbuttons.c7970
-rw-r--r--source/blender/editors/datafiles/prvicons.c732
-rw-r--r--source/blender/editors/gpencil/gpencil.c2
-rw-r--r--source/blender/editors/include/BIF_transform.h32
-rw-r--r--source/blender/editors/include/ED_anim_api.h13
-rw-r--r--source/blender/editors/include/ED_armature.h26
-rw-r--r--source/blender/editors/include/ED_fileselect.h33
-rw-r--r--source/blender/editors/include/ED_mesh.h6
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_view3d.h1
-rw-r--r--source/blender/editors/include/UI_interface.h106
-rw-r--r--source/blender/editors/include/UI_interface_icons.h1
-rw-r--r--source/blender/editors/include/UI_resources.h26
-rw-r--r--source/blender/editors/include/UI_view2d.h3
-rw-r--r--source/blender/editors/interface/interface.c177
-rw-r--r--source/blender/editors/interface/interface_draw.c374
-rw-r--r--source/blender/editors/interface/interface_handlers.c353
-rw-r--r--source/blender/editors/interface/interface_intern.h9
-rw-r--r--source/blender/editors/interface/interface_layout.c1004
-rw-r--r--source/blender/editors/interface/interface_panel.c8
-rw-r--r--source/blender/editors/interface/interface_regions.c41
-rw-r--r--source/blender/editors/interface/interface_utils.c128
-rw-r--r--source/blender/editors/interface/interface_widgets.c1046
-rw-r--r--source/blender/editors/interface/resources.c55
-rw-r--r--source/blender/editors/interface/view2d.c29
-rw-r--r--source/blender/editors/interface/view2d_ops.c102
-rw-r--r--source/blender/editors/mesh/editdeform.c42
-rw-r--r--source/blender/editors/mesh/editmesh.c29
-rw-r--r--source/blender/editors/mesh/editmesh_add.c57
-rw-r--r--source/blender/editors/mesh/editmesh_loop.c13
-rw-r--r--source/blender/editors/mesh/editmesh_mods.c150
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c155
-rw-r--r--source/blender/editors/mesh/mesh_intern.h26
-rw-r--r--source/blender/editors/mesh/mesh_ops.c63
-rw-r--r--source/blender/editors/object/editgroup.c10
-rw-r--r--source/blender/editors/object/object_edit.c232
-rw-r--r--source/blender/editors/object/object_intern.h39
-rw-r--r--source/blender/editors/object/object_ops.c62
-rw-r--r--source/blender/editors/physics/editparticle.c23
-rw-r--r--source/blender/editors/screen/area.c44
-rw-r--r--source/blender/editors/screen/glutil.c4
-rw-r--r--source/blender/editors/screen/screen_context.c31
-rw-r--r--source/blender/editors/screen/screen_intern.h2
-rw-r--r--source/blender/editors/screen/screen_ops.c165
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c21
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c92
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c14
-rw-r--r--source/blender/editors/space_action/action_edit.c14
-rw-r--r--source/blender/editors/space_action/action_intern.h12
-rw-r--r--source/blender/editors/space_action/action_ops.c38
-rw-r--r--source/blender/editors/space_action/action_select.c20
-rw-r--r--source/blender/editors/space_buttons/SConscript10
-rw-r--r--source/blender/editors/space_buttons/buttons_header.c34
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h9
-rw-r--r--source/blender/editors/space_buttons/buttons_object.c216
-rw-r--r--source/blender/editors/space_buttons/buttons_scene.c12
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c82
-rw-r--r--source/blender/editors/space_file/Makefile5
-rw-r--r--source/blender/editors/space_file/file_draw.c599
-rw-r--r--source/blender/editors/space_file/file_header.c109
-rw-r--r--source/blender/editors/space_file/file_intern.h8
-rw-r--r--source/blender/editors/space_file/file_ops.c185
-rw-r--r--source/blender/editors/space_file/filelist.c477
-rw-r--r--source/blender/editors/space_file/filelist.h24
-rw-r--r--source/blender/editors/space_file/filesel.c112
-rw-r--r--source/blender/editors/space_file/fsmenu.c239
-rw-r--r--source/blender/editors/space_file/fsmenu.h48
-rw-r--r--source/blender/editors/space_file/space_file.c54
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c580
-rw-r--r--source/blender/editors/space_graph/graph_draw.c500
-rw-r--r--source/blender/editors/space_graph/graph_edit.c169
-rw-r--r--source/blender/editors/space_graph/graph_intern.h16
-rw-r--r--source/blender/editors/space_graph/graph_ops.c33
-rw-r--r--source/blender/editors/space_graph/graph_select.c17
-rw-r--r--source/blender/editors/space_graph/space_graph.c19
-rw-r--r--source/blender/editors/space_image/image_draw.c2
-rw-r--r--source/blender/editors/space_image/image_header.c10
-rw-r--r--source/blender/editors/space_image/image_intern.h2
-rw-r--r--source/blender/editors/space_image/image_ops.c4
-rw-r--r--source/blender/editors/space_image/image_panels.c10
-rw-r--r--source/blender/editors/space_image/space_image.c42
-rw-r--r--source/blender/editors/space_info/Makefile1
-rw-r--r--source/blender/editors/space_info/SConscript12
-rw-r--r--source/blender/editors/space_info/info_header.c2
-rw-r--r--source/blender/editors/space_nla/Makefile1
-rw-r--r--source/blender/editors/space_nla/SConscript2
-rw-r--r--source/blender/editors/space_node/node_edit.c4
-rw-r--r--source/blender/editors/space_node/node_header.c8
-rw-r--r--source/blender/editors/space_node/node_intern.h8
-rw-r--r--source/blender/editors/space_node/node_ops.c18
-rw-r--r--source/blender/editors/space_node/node_select.c9
-rw-r--r--source/blender/editors/space_node/node_state.c4
-rw-r--r--source/blender/editors/space_node/space_node.c8
-rw-r--r--source/blender/editors/space_outliner/outliner.c10
-rw-r--r--source/blender/editors/space_outliner/outliner_header.c151
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c2
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c29
-rw-r--r--source/blender/editors/space_script/space_script.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_header.c6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c18
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c16
-rw-r--r--source/blender/editors/space_sound/Makefile1
-rw-r--r--source/blender/editors/space_sound/SConscript2
-rw-r--r--source/blender/editors/space_text/SConscript2
-rw-r--r--source/blender/editors/space_text/space_text.c97
-rw-r--r--source/blender/editors/space_text/text_header.c244
-rw-r--r--source/blender/editors/space_text/text_intern.h14
-rw-r--r--source/blender/editors/space_text/text_ops.c22
-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/space_view3d.c91
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c283
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c24
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c46
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h10
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c45
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c12
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c35
-rw-r--r--source/blender/editors/transform/transform.c177
-rw-r--r--source/blender/editors/transform/transform.h37
-rw-r--r--source/blender/editors/transform/transform_constraints.c48
-rw-r--r--source/blender/editors/transform/transform_conversions.c89
-rw-r--r--source/blender/editors/transform/transform_generics.c105
-rw-r--r--source/blender/editors/transform/transform_numinput.c7
-rw-r--r--source/blender/editors/transform/transform_ops.c409
-rw-r--r--source/blender/editors/transform/transform_orientations.c6
-rw-r--r--source/blender/editors/transform/transform_snap.c1056
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c52
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c186
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c73
-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/IMB_imbuf_types.h2
-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/openexr/openexr_api.cpp1
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c18
-rw-r--r--source/blender/makesdna/DNA_anim_types.h51
-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_outliner_types.h (renamed from source/blender/makesdna/DNA_oops_types.h)33
-rw-r--r--source/blender/makesdna/DNA_scene_types.h46
-rw-r--r--source/blender/makesdna/DNA_screen_types.h5
-rw-r--r--source/blender/makesdna/DNA_sensor_types.h1
-rw-r--r--source/blender/makesdna/DNA_space_types.h53
-rw-r--r--source/blender/makesdna/intern/SConscript10
-rw-r--r--source/blender/makesdna/intern/makesdna.c4
-rw-r--r--source/blender/makesrna/RNA_access.h16
-rw-r--r--source/blender/makesrna/RNA_define.h11
-rw-r--r--source/blender/makesrna/RNA_enum_types.h37
-rw-r--r--source/blender/makesrna/RNA_types.h34
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt3
-rw-r--r--source/blender/makesrna/intern/Makefile8
-rw-r--r--source/blender/makesrna/intern/SConscript18
-rw-r--r--source/blender/makesrna/intern/makesrna.c395
-rw-r--r--source/blender/makesrna/intern/rna_ID.c12
-rw-r--r--source/blender/makesrna/intern/rna_access.c183
-rw-r--r--[-rwxr-xr-x]source/blender/makesrna/intern/rna_action.c10
-rw-r--r--source/blender/makesrna/intern/rna_actuator.c2
-rw-r--r--source/blender/makesrna/intern/rna_animation.c8
-rw-r--r--source/blender/makesrna/intern/rna_armature.c6
-rw-r--r--source/blender/makesrna/intern/rna_brush.c2
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c2
-rw-r--r--source/blender/makesrna/intern/rna_color.c10
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c12
-rw-r--r--source/blender/makesrna/intern/rna_context.c150
-rw-r--r--source/blender/makesrna/intern/rna_controller.c2
-rw-r--r--source/blender/makesrna/intern/rna_curve.c158
-rw-r--r--source/blender/makesrna/intern/rna_define.c80
-rw-r--r--source/blender/makesrna/intern/rna_dependency.c92
-rw-r--r--source/blender/makesrna/intern/rna_fluidsim.c6
-rw-r--r--source/blender/makesrna/intern/rna_image.c15
-rw-r--r--source/blender/makesrna/intern/rna_internal.h1
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h12
-rw-r--r--source/blender/makesrna/intern/rna_key.c9
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c4
-rw-r--r--source/blender/makesrna/intern/rna_lattice.c10
-rw-r--r--source/blender/makesrna/intern/rna_main.c2
-rw-r--r--source/blender/makesrna/intern/rna_material.c4
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c131
-rw-r--r--source/blender/makesrna/intern/rna_meta.c4
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c4
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c483
-rw-r--r--source/blender/makesrna/intern/rna_nodetree_types.h131
-rw-r--r--source/blender/makesrna/intern/rna_object.c36
-rw-r--r--source/blender/makesrna/intern/rna_packedfile.c4
-rw-r--r--source/blender/makesrna/intern/rna_particle.c232
-rw-r--r--[-rwxr-xr-x]source/blender/makesrna/intern/rna_pose.c22
-rw-r--r--source/blender/makesrna/intern/rna_property.c4
-rw-r--r--source/blender/makesrna/intern/rna_radio.c2
-rw-r--r--source/blender/makesrna/intern/rna_rna.c66
-rw-r--r--source/blender/makesrna/intern/rna_scene.c84
-rw-r--r--source/blender/makesrna/intern/rna_sensor.c12
-rw-r--r--source/blender/makesrna/intern/rna_sequence.c30
-rw-r--r--source/blender/makesrna/intern/rna_space.c21
-rw-r--r--source/blender/makesrna/intern/rna_text.c43
-rw-r--r--source/blender/makesrna/intern/rna_texture.c444
-rw-r--r--[-rwxr-xr-x]source/blender/makesrna/intern/rna_timeline.c0
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c2
-rw-r--r--source/blender/makesrna/intern/rna_vfont.c2
-rw-r--r--source/blender/makesrna/intern/rna_vpaint.c14
-rw-r--r--source/blender/makesrna/intern/rna_wm.c2
-rw-r--r--source/blender/makesrna/intern/rna_world.c5
-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/python/epy_doc_gen.py209
-rw-r--r--source/blender/python/intern/bpy_compat.h14
-rw-r--r--source/blender/python/intern/bpy_interface.c50
-rw-r--r--source/blender/python/intern/bpy_operator.c381
-rw-r--r--source/blender/python/intern/bpy_operator.h13
-rw-r--r--source/blender/python/intern/bpy_opwrapper.c403
-rw-r--r--source/blender/python/intern/bpy_opwrapper.h7
-rw-r--r--source/blender/python/intern/bpy_rna.c448
-rw-r--r--source/blender/python/intern/bpy_rna.h30
-rw-r--r--source/blender/python/intern/bpy_ui.c301
-rw-r--r--source/blender/python/intern/bpy_util.c84
-rw-r--r--source/blender/python/intern/bpy_util.h10
-rw-r--r--source/blender/python/rna_dump.py136
-rw-r--r--source/blender/python/simple_enum_gen.py65
-rw-r--r--source/blender/quicktime/apple/quicktime_import.c1
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c32
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c12
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c17
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c9
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c8
-rw-r--r--source/blender/windowmanager/wm_cursors.h1
-rw-r--r--source/blender/windowmanager/wm_event_system.h1
-rw-r--r--source/blender/windowmanager/wm_window.h2
-rw-r--r--source/creator/CMakeLists.txt3
-rw-r--r--source/creator/Makefile4
-rw-r--r--source/creator/SConscript2
-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.cpp40
-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_compile.mk4
-rw-r--r--source/nan_definitions.mk40
-rw-r--r--source/nan_link.mk4
-rw-r--r--source/nan_subdirs.mk4
-rw-r--r--source/nan_warn.mk4
-rw-r--r--tools/Blender.py6
-rwxr-xr-xtools/btools.py3
937 files changed, 48582 insertions, 43491 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/Makefile b/Makefile
index b983779fb31..7c883c41741 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
# $Id$
#
# ***** BEGIN GPL LICENSE BLOCK *****
@@ -21,7 +23,7 @@
#
# The Original Code is: revision 1.1
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
#
@@ -31,12 +33,11 @@
# If the user wants to override some of the build
# vars they can put it in the file user-def.mk which
# will get included if it exists (please do not commit
-# user-def.mk to cvs).
-
+# user-def.mk to the revision control server).
sinclude user-def.mk
-# To build without openAL, uncomment the following line, or set it as
-# an environment variable, or put it uncommented in user-def.mk:
+# To build without openAL, set it as an environment variable,
+# or put it uncommented in user-def.mk:
# export NAN_NO_OPENAL=true
export NANBLENDERHOME=$(shell pwd)
@@ -44,13 +45,9 @@ MAKEFLAGS=-I$(NANBLENDERHOME)/source --no-print-directory
SOURCEDIR =
ifeq ($(FREE_WINDOWS),true)
- DIRS ?= dlltool extern intern source
-endif
-
-DIRS ?= extern intern source
-
-ifneq ($(INTERNATIONAL),false)
- DIRS += po
+ DIRS ?= dlltool extern intern source po
+else
+ DIRS ?= extern intern source po
endif
include source/nan_subdirs.mk
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/config/linux2-config.py b/config/linux2-config.py
index b2ca4c1822b..45363f16cb0 100644
--- a/config/linux2-config.py
+++ b/config/linux2-config.py
@@ -2,6 +2,7 @@ LCGDIR = '../lib/linux2'
LIBDIR = "${LCGDIR}"
BF_PYTHON = '/usr'
+BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib'
BF_PYTHON_VERSION = '2.5'
WITH_BF_STATICPYTHON = False
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
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/bFTGL/src/Makefile b/extern/bFTGL/src/Makefile
index 17c6016ad03..d91bcb2559d 100644
--- a/extern/bFTGL/src/Makefile
+++ b/extern/bFTGL/src/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
#
@@ -46,15 +48,13 @@ CPPFLAGS += -I../include
CPPFLAGS += -I$(NAN_FREETYPE)/include -I$(NAN_FREETYPE)/include/freetype2
CPPFLAGS += -I$(OPENGL_HEADERS)
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_FTGL) ] || mkdir -p $(NAN_FTGL)
@[ -d $(NAN_FTGL)/include ] || mkdir -p $(NAN_FTGL)/include
- @[ -d $(NAN_FTGL)/lib ] || mkdir -p $(NAN_FTGL)/lib
- @[ -d $(NAN_FTGL)/lib/debug ] || mkdir -p $(NAN_FTGL)/lib/debug
- @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/lib$(LIBNAME).a $(NAN_FTGL)/lib/
-# @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/debug/lib$(LIBNAME).a $(NAN_FTGL)/lib/debug/
+ @[ -d $(NAN_FTGL)/lib/$(DEBUG_DIR) ] || mkdir -p $(NAN_FTGL)/lib/$(DEBUG_DIR)
+ @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)lib$(LIBNAME).a $(NAN_FTGL)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_FTGL)/lib/lib$(LIBNAME).a
+ ranlib $(NAN_FTGL)/lib/$(DEBUG_DIR)lib$(LIBNAME).a
endif
@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh ../include/*.h $(NAN_FTGL)/include/
diff --git a/extern/binreloc/Makefile b/extern/binreloc/Makefile
index dbd093500a1..d303ab3afcc 100644
--- a/extern/binreloc/Makefile
+++ b/extern/binreloc/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
@@ -30,8 +32,7 @@ CPPFLAGS += -I./include
include nan_compile.mk
-
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(DIR) ] || mkdir $(DIR)
@[ -d $(DIR)/include ] || mkdir $(DIR)/include
@../../intern/tools/cpifdiff.sh include/*.h $(DIR)/include/
diff --git a/extern/bullet2/Makefile b/extern/bullet2/Makefile
index f3abb86e404..d974569e63d 100644
--- a/extern/bullet2/Makefile
+++ b/extern/bullet2/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -48,7 +50,7 @@ include nan_subdirs.mk
CP = $(NANBLENDERHOME)/intern/tools/cpifdiff.sh
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_BULLET2) ] || mkdir -p $(NAN_BULLET2)
@[ -d $(NAN_BULLET2)/include ] || mkdir -p $(NAN_BULLET2)/include
@for i in $(BULLETDIRS); do \
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/glew/src/Makefile b/extern/glew/src/Makefile
index 55cc7cfccad..ebcecae45c8 100644
--- a/extern/glew/src/Makefile
+++ b/extern/glew/src/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -25,7 +27,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL/BL DUAL LICENSE BLOCK *****
#
@@ -42,15 +44,13 @@ CSRCS = glew.c
CCSRCS =
include nan_compile.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_GLEW) ] || mkdir -p $(NAN_GLEW)
@[ -d $(NAN_GLEW)/include/GL ] || mkdir -p $(NAN_GLEW)/include/GL
- @[ -d $(NAN_GLEW)/lib ] || mkdir -p $(NAN_GLEW)/lib
- @[ -d $(NAN_GLEW)/lib/debug ] || mkdir -p $(NAN_GLEW)/lib/debug
- @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/lib$(LIBNAME).a $(NAN_GLEW)/lib/
+ @[ -d $(NAN_GLEW)/lib/$(DEBUG_DIR) ] || mkdir -p $(NAN_GLEW)/lib/$(DEBUG_DIR)
+ @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)lib$(LIBNAME).a $(NAN_GLEW)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_GLEW)/lib/lib$(LIBNAME).a
- ranlib $(NAN_GLEW)/lib/lib$(LIBNAME).a
+ ranlib $(NAN_GLEW)/lib/$(DEBUG_DIR)lib$(LIBNAME).a
endif
@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh ../include/GL/*.h $(NAN_GLEW)/include/GL
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/extern/ode/Makefile b/extern/ode/Makefile
deleted file mode 100644
index 51be666aa69..00000000000
--- a/extern/ode/Makefile
+++ /dev/null
@@ -1,110 +0,0 @@
-#
-# $Id$
-#
-# ***** 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) 2002 by Hans Lambermont
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-
-include nan_definitions.mk
-
-DISTDIR = dist
-CP = ../../intern/tools/cpifdiff.sh
-USERSETTINGS = ./dist/config/user-settings
-TEMPSETTINGS = ./user-settings
-
-all:
- [ -d $(DISTDIR)/lib ] || mkdir $(DISTDIR)/lib
- # prepare settings for patching, clean in case of interruption
- ifeq ($(OS),$(findstring $(OS), "darwin windows"))
- [ ! -f $(TEMPSETTINGS) ] || mv $(TEMPSETTINGS) $(USERSETTINGS)
- cp $(USERSETTINGS) $(TEMPSETTINGS)
- endif
- ifeq ($(OS),freebsd)
- (grep FreeBSD $(DISTDIR)/Makefile >/dev/null ; \
- [ $$? -eq 0 ] || patch < patchfile.FreeBSD )
- endif
- ifeq ($(OS),darwin)
- cat $(TEMPSETTINGS) | sed s/unix-gcc/osx/ > $(USERSETTINGS)
- endif
- ifeq ($(OS),windows)
- # compile with MSVC
- cat $(TEMPSETTINGS) | sed s/unix-gcc/msvc/ > $(USERSETTINGS)
- env PATH=".:$(PATH)" $(MAKE) -C $(DISTDIR)
- endif
- ifeq ($(OS),$(findstring $(OS), "freebsd linux darwin"))
- $(MAKE) -C $(DISTDIR)
- endif
- # restore settings
- ifeq ($(OS),$(findstring $(OS), "darwin windows"))
- mv $(TEMPSETTINGS) $(USERSETTINGS)
- endif
-
-# fake debug target
-debug:
-
-install: all
- ifeq ($(OS),$(findstring $(OS), "freebsd linux darwin"))
- [ -d $(LCGDIR) ] || mkdir $(LCGDIR)
- [ -d $(NAN_ODE) ] || mkdir $(NAN_ODE)
- [ -d $(NAN_ODE)/include ] || mkdir $(NAN_ODE)/include
- [ -d $(NAN_ODE)/include/ode ] || mkdir $(NAN_ODE)/include/ode
- [ -d $(NAN_ODE)/lib ] || mkdir $(NAN_ODE)/lib
- [ -d $(NAN_ODE)/ode ] || mkdir $(NAN_ODE)/ode
- [ -d $(NAN_ODE)/ode/src ] || mkdir $(NAN_ODE)/ode/src
- @$(CP) $(DISTDIR)/lib/libode.a $(NAN_ODE)/lib/
- @$(CP) $(DISTDIR)/include/ode/*.h $(NAN_ODE)/include/ode/
- @$(CP) $(DISTDIR)/ode/src/array.h $(NAN_ODE)/ode/src/
- @$(CP) $(DISTDIR)/ode/src/joint.h $(NAN_ODE)/ode/src/
- @$(CP) $(DISTDIR)/ode/src/objects.h $(NAN_ODE)/ode/src/
- @$(CP) $(DISTDIR)/ode/src/obstack.h $(NAN_ODE)/ode/src/
- ifeq ($(OS),darwin)
- ranlib $(NAN_ODE)/lib/libode.a
- endif
- endif
- ifeq ($(OS),windows)
- @echo "====> $(MAKE) $@ in $(SOURCEDIR)"
- [ -d $(LCGDIR) ] || mkdir $(LCGDIR)
- [ -d $(NAN_ODE) ] || mkdir $(NAN_ODE)
- [ -d $(NAN_ODE)/include ] || mkdir $(NAN_ODE)/include
- [ -d $(NAN_ODE)/include/ode ] || mkdir $(NAN_ODE)/include/ode
- [ -d $(NAN_ODE)/lib ] || mkdir $(NAN_ODE)/lib
- [ -d $(NAN_ODE)/ode ] || mkdir $(NAN_ODE)/ode
- [ -d $(NAN_ODE)/ode/src ] || mkdir $(NAN_ODE)/ode/src
- cp $(DISTDIR)/lib/ode.lib $(NAN_ODE)/lib/libode.a
- cp $(DISTDIR)/include/ode/*.h $(NAN_ODE)/include/ode/
- cp $(DISTDIR)/ode/src/array.h $(NAN_ODE)/ode/src/
- cp $(DISTDIR)/ode/src/joint.h $(NAN_ODE)/ode/src/
- cp $(DISTDIR)/ode/src/objects.h $(NAN_ODE)/ode/src/
- cp $(DISTDIR)/ode/src/obstack.h $(NAN_ODE)/ode/src/
- endif
-
-clean:
- ifeq ($(OS),$(findstring $(OS), "freebsd linux darwin"))
- [ ! -f dist/Makefile ] || $(MAKE) -C dist clean
- endif
- ifeq ($(OS),freebsd)
- (grep FreeBSD $(DISTDIR)/Makefile >/dev/null ; \
- [ $$? -ne 0 ] || patch -R < patchfile.FreeBSD )
- endif
-
diff --git a/extern/ode/dist/INSTALL b/extern/ode/dist/INSTALL
deleted file mode 100644
index f82285db1b2..00000000000
--- a/extern/ode/dist/INSTALL
+++ /dev/null
@@ -1,44 +0,0 @@
-
-here are the steps to buid ODE:
-
-(1) get the GNU 'make' tool. many unix platforms come with this, although
- sometimes it is called 'gmake'. i have provided a version of GNU make
- for windows at: http://q12.org/ode/bin/make.exe
-
-(2) edit the settings in the file config/user-settings. the list of supported
- platforms is given in that file.
-
-(3) run 'make' to configure and build ODE and the graphical test programs.
- to build parts of ODE the make targets are:
-
- make configure create configuration file include/ode/config.h
- make ode-lib build the core ODE library
- make drawstuff-lib build the OpenGL-based graphics library
- make ode-test build some ODE tests (they need drawstuff)
- make drawstuff-test build a test app for the drawstuff library
-
- all of these targets will do an implicit 'make configure'. if the
- configurator screws up then you can edit the settings directly in
- include/ode/config.h.
-
-(4) to install the ODE library onto your system you should copy the 'lib' and
- 'include' directories to a suitable place, e.g. on unix:
-
- include/ode --> /usr/local/include/ode
- lib/libode.a --> /usr/local/lib/libode.a
-
-ODE has been verified to build on the following platforms:
-
- config ode-lib ode-test
- ------ ------- --------
- windows
- MSVC msvc * *
- MinGW mingw * *
- CygWin cygwin * *
- linux (x86, mandrake 8.1) unix-gcc * *
- linux (alpha, debian 2.2) unix-gcc * ?
- linux (RS/6000, debian 2.2) unix-gcc * ?
- linux (Sparc U60, debian 2.2) unix-gcc * ?
- freebsd 4.3 unix-gcc * ?
- Mac OS-X osx * ?
- Solaris 8 (Sparc R220) unix-gcc * ?
diff --git a/extern/ode/dist/LICENSE-BSD.TXT b/extern/ode/dist/LICENSE-BSD.TXT
deleted file mode 100644
index 05929239487..00000000000
--- a/extern/ode/dist/LICENSE-BSD.TXT
+++ /dev/null
@@ -1,34 +0,0 @@
-
-This is the BSD-style license for the Open Dynamics Engine
-----------------------------------------------------------
-
-Open Dynamics Engine
-Copyright (c) 2001,2002, Russell L. Smith.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-
-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.
-
-Neither the names of ODE's copyright owner nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-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.
diff --git a/extern/ode/dist/LICENSE.TXT b/extern/ode/dist/LICENSE.TXT
deleted file mode 100644
index cfe59bcadb8..00000000000
--- a/extern/ode/dist/LICENSE.TXT
+++ /dev/null
@@ -1,502 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
diff --git a/extern/ode/dist/Makefile b/extern/ode/dist/Makefile
deleted file mode 100644
index 34fbd53f792..00000000000
--- a/extern/ode/dist/Makefile
+++ /dev/null
@@ -1,280 +0,0 @@
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-USER_SETTINGS=config/user-settings
-include $(USER_SETTINGS)
-PLATFORM_MAKEFILE=config/makefile.$(PLATFORM)
-include $(PLATFORM_MAKEFILE)
-
-##############################################################################
-# check some variables that were supposed to be defined
-
-ifneq ($(BUILD),debug)
-ifneq ($(BUILD),release)
-$(error the BUILD variable is not set properly)
-endif
-endif
-
-ifneq ($(PRECISION),SINGLE)
-ifneq ($(PRECISION),DOUBLE)
-$(error the PRECISION variable is not set properly)
-endif
-endif
-
-##############################################################################
-# package settings
-
-ODE_SRC = \
- ode/src/array.cpp \
- ode/src/error.cpp \
- ode/src/memory.cpp \
- ode/src/obstack.cpp \
- ode/src/odemath.cpp \
- ode/src/matrix.cpp \
- ode/src/misc.cpp \
- ode/src/rotation.cpp \
- ode/src/mass.cpp \
- ode/src/ode.cpp \
- ode/src/step.cpp \
- ode/src/lcp.cpp \
- ode/src/joint.cpp \
- ode/src/space.cpp \
- ode/src/geom.cpp \
- ode/src/timer.cpp \
- ode/src/mat.cpp \
- ode/src/testing.cpp
-ODE_PREGEN_SRC = \
- ode/src/fastldlt.c \
- ode/src/fastlsolve.c \
- ode/src/fastltsolve.c \
- ode/src/fastdot.c
-
-ifeq ($(WINDOWS),1)
-DRAWSTUFF_SRC = drawstuff/src/drawstuff.cpp drawstuff/src/windows.cpp
-RESOURCE_FILE=lib/resources.RES
-else
-DRAWSTUFF_SRC = drawstuff/src/drawstuff.cpp drawstuff/src/x11.cpp
-endif
-
-ODE_LIB_NAME=ode
-DRAWSTUFF_LIB_NAME=drawstuff
-
-INCPATH=include
-LIBPATH=lib
-
-ODE_TEST_SRC_CPP = \
- ode/test/test_ode.cpp \
- ode/test/test_chain2.cpp \
- ode/test/test_hinge.cpp \
- ode/test/test_slider.cpp \
- ode/test/test_collision.cpp \
- ode/test/test_boxstack.cpp \
- ode/test/test_buggy.cpp \
- ode/test/test_joints.cpp \
- ode/test/test_space.cpp \
- ode/test/test_I.cpp \
- ode/test/test_step.cpp \
- ode/test/test_friction.cpp
-ODE_TEST_SRC_C = \
- ode/test/test_chain1.c
-DRAWSTUFF_TEST_SRC_CPP = \
- drawstuff/dstest/dstest.cpp
-
-CONFIGURATOR_SRC=configurator.c
-CONFIG_H=include/ode/config.h
-
-##############################################################################
-# derived things
-
-DEFINES=
-
-# add some defines depending on the build mode
-ifeq ($(BUILD),release)
-DEFINES+=$(C_DEF)dNODEBUG
-endif
-ifeq ($(BUILD),debug)
-DEFINES+=$(C_DEF)dDEBUG_ALLOC
-endif
-
-# object file names
-ODE_PREGEN_OBJECTS=$(ODE_PREGEN_SRC:%.c=%$(OBJ))
-ODE_OBJECTS=$(ODE_SRC:%.cpp=%$(OBJ)) $(ODE_PREGEN_OBJECTS)
-DRAWSTUFF_OBJECTS=$(DRAWSTUFF_SRC:%.cpp=%$(OBJ)) $(RESOURCE_FILE)
-
-# side-effect variables causing creation of files containing lists of
-# filenames to be linked, to work around command-line-length limitations
-# on outdated 16-bit operating systems. because of command-line length
-# limitations we cannot issue a link command with all object filenames
-# specified (because this command is too long and overflows the command
-# buffer), but instead must create a file containing all object filenames
-# to be linked, and specify this list-file with @listfile on the command-line.
-#
-# the difficult part is doing this in a flexible way; we don't want to
-# hard-code the to-be-linked object filenames in a file, but instead
-# want to dynamically create a file containing a list of all object filenames
-# within the $XXX_OBJECTS makefile variables. to do this, we use side-effect
-# variables.
-#
-# idea: when these variables are EVALUATED (i.e. later during rule execution,
-# not now during variable definition), they cause a SIDE EFFECT which creates
-# a file with the list of all ODE object files. why the chicanery??? because
-# if we have a command-line length limitation, no SINGLE command we issue will
-# be able to create a file containing all object files to be linked
-# (because that command itself would need to include all filenames, making
-# it too long to be executed). instead, we must use the gnu-make "foreach"
-# function, combined - probably in an unintended way - with the "shell"
-# function. this is probably unintended because we are not using the "shell"
-# function to return a string value for variable evaluation, but are instead
-# using the "shell" function to cause a side effect (appending of each filename
-# to the filename-list-file).
-#
-# one possible snag is that, forbidding use of any external EXE utilities and
-# relying only on the facilities provided by the outdated 16-bit operating
-# system, there is no way to issue a SERIES of commands which append text to
-# the end of a file WITHOUT adding newlines. therefore, the list of to-be-
-# linked object files is separated by newlines in the list file. fortunately,
-# the linker utility for this outdated 16-bit operating system accepts
-# filenames on separate lines in the list file.
-
-# remember: when we evaluate these variables later, this causes the creation
-# of the appropriate list file.
-ifeq ($(WINDOWS16),1)
-SIDE_EFFECT_ODE_OBJLIST = $(foreach o,$(ODE_OBJECTS),$(shell echo $(o) >> odeobj.txt ))
-SIDE_EFFECT_DRAWSTUFF_OBJLIST = $(foreach o,$(DRAWSTUFF_OBJECTS),$(shell echo $(o) >> dsobj.txt ))
-endif
-
-# library file names
-ODE_LIB=$(LIBPATH)/$(LIB_PREFIX)$(ODE_LIB_NAME)$(LIB_SUFFIX)
-DRAWSTUFF_LIB=$(LIBPATH)/$(LIB_PREFIX)$(DRAWSTUFF_LIB_NAME)$(LIB_SUFFIX)
-
-# executable file names
-ODE_TEST_EXE=$(ODE_TEST_SRC_CPP:%.cpp=%.exe) $(ODE_TEST_SRC_C:%.c=%.exe)
-DRAWSTUFF_TEST_EXE=$(DRAWSTUFF_TEST_SRC_CPP:%.cpp=%.exe)
-CONFIGURATOR_EXE=$(CONFIGURATOR_SRC:%.c=%.exe)
-
-##############################################################################
-# rules
-#
-# NOTE: the '.c' files are pregenerated sources, and must be compiled with
-# -O1 optimization. that is why the rule for .c files is a bit different.
-# why should it be compiled with O1? it is numerical code that is generated
-# by fbuild. O1 optimization is used to preserve the operation orders that
-# were discovered by fbuild to be the fastest on that platform. believe it or
-# not, O2 makes this code run much slower for most compilers.
-
-debug: all
-all: ode-lib drawstuff-lib ode-test drawstuff-test
- @echo SUCCESS
-
-ode-lib: configure $(ODE_LIB)
-drawstuff-lib: configure $(DRAWSTUFF_LIB)
-ode-test: ode-lib drawstuff-lib $(ODE_TEST_EXE)
-drawstuff-test: drawstuff-lib $(DRAWSTUFF_TEST_EXE)
-
-ifndef ODE_LIB_AR_RULE
-ODE_LIB_AR_RULE=$(AR)$@
-endif
-
-$(ODE_LIB): pre_ode_lib $(ODE_OBJECTS)
-ifeq ($(WINDOWS16),1)
-# if we have a command-line-length limitation, then dynamically create
-# a file containing all object filenames, and pass this file to the linker
-# instead of directly specifying the object filenames on the command line.
-# the very evaluation of the following variable causes creation of file
-# odeobj.txt
- $(SIDE_EFFECT_ODE_OBJLIST)
- $(ODE_LIB_AR_RULE) @odeobj.txt
-else
-# if we have no command-line-length limitation, directly specify all
-# object files to be linked.
- $(ODE_LIB_AR_RULE) $(ODE_OBJECTS)
-endif
-
-ifdef RANLIB
- $(RANLIB) $@
-endif
-
-$(DRAWSTUFF_LIB): pre_drawstuff_lib $(DRAWSTUFF_OBJECTS)
-ifeq ($WINDOWS16),1)
-# if we have a command-line-length limitation, then do the same as above.
- $(SIDE_EFFECT_DRAWSTUFF_OBJLIST)
- $(AR)$@ @dsobj.txt
-else
-# if we have no command-line-length limitation, directly specify all object
-# files to be linked.
- $(AR)$@ $(DRAWSTUFF_OBJECTS)
-endif
-ifdef RANLIB
- $(RANLIB) $@
-endif
-
-# rules to be executed before library linking starts: delete list file (if one is used)
-
-pre_ode_lib:
-ifeq ($WINDOWS16),1)
- $(DEL_CMD) odeobj.txt
-endif
-
-pre_drawstuff_lib:
-ifeq ($WINDOWS16),1)
- $(DEL_CMD) dsobj.txt
-endif
-
-clean:
- -$(DEL_CMD) $(ODE_OBJECTS) $(ODE_TEST_EXE) $(ODE_LIB) $(DRAWSTUFF_OBJECTS) $(DRAWSTUFF_TEST_EXE) $(DRAWSTUFF_LIB) ode/test/*$(OBJ) drawstuff/dstest/*$(OBJ) $(CONFIGURATOR_EXE) $(CONFIG_H)
-
-%$(OBJ): %.c
- $(CC) $(C_FLAGS) $(C_INC)$(INCPATH) $(DEFINES) $(C_OPT)1 $(C_OUT)$@ $<
-
-%$(OBJ): %.cpp
- $(CC) $(C_FLAGS) $(C_INC)$(INCPATH) $(DEFINES) $(C_OPT)$(OPT) $(C_OUT)$@ $<
-
-%.exe: %$(OBJ)
- $(CC) $(C_EXEOUT)$@ $< $(ODE_LIB) $(DRAWSTUFF_LIB) $(RESOURCE_FILE) $(LINK_OPENGL) $(LINK_MATH)
-
-# windows specific rules
-
-lib/resources.RES: drawstuff/src/resources.rc
- $(RC_RULE)
-
-
-# configurator rules
-
-configure: $(CONFIG_H)
-
-$(CONFIG_H): $(CONFIGURATOR_EXE) $(USER_SETTINGS) $(PLATFORM_MAKEFILE)
- $(THIS_DIR)$(CONFIGURATOR_EXE) $(CONFIG_H) "$(CC) $(DEFINES) $(C_EXEOUT)" "$(DEL_CMD)" $(THIS_DIR)
-
-$(CONFIGURATOR_EXE): $(CONFIGURATOR_SRC) $(USER_SETTINGS) $(PLATFORM_MAKEFILE)
- $(CC) $(C_DEF)d$(PRECISION) $(DEFINES) $(C_EXEOUT)$@ $<
-
-
-# unix-gcc specific dependency making
-
-DEP_RULE=gcc -M $(C_INC)$(INCPATH) $(DEFINES)
-depend: $(ODE_SRC) $(ODE_PREGEN_SRC) $(DRAWSTUFF_SRC) $(ODE_TEST_SRC_CPP) $(ODE_TEST_SRC_C) $(DRAWSTUFF_TEST_SRC_CPP)
- $(DEP_RULE) $(ODE_SRC) $(ODE_PREGEN_SRC) | tools/process_deps ode/src/ > Makefile.deps
- $(DEP_RULE) $(DRAWSTUFF_SRC) | tools/process_deps drawstuff/src/ >> Makefile.deps
- $(DEP_RULE) $(ODE_TEST_SRC_CPP) | tools/process_deps ode/test/ >> Makefile.deps
- $(DEP_RULE) $(DRAWSTUFF_TEST_SRC_CPP) | tools/process_deps drawstuff/dstest/ >> Makefile.deps
-
-include Makefile.deps
diff --git a/extern/ode/dist/Makefile.deps b/extern/ode/dist/Makefile.deps
deleted file mode 100644
index ad11f01353f..00000000000
--- a/extern/ode/dist/Makefile.deps
+++ /dev/null
@@ -1,456 +0,0 @@
-ode/src/array.o: \
- ode/src/array.cpp \
- include/ode/config.h \
- include/ode/memory.h \
- include/ode/error.h \
- ode/src/array.h
-ode/src/error.o: \
- ode/src/error.cpp \
- include/ode/config.h \
- include/ode/error.h
-ode/src/memory.o: \
- ode/src/memory.cpp \
- include/ode/config.h \
- include/ode/memory.h \
- include/ode/error.h
-ode/src/obstack.o: \
- ode/src/obstack.cpp \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h \
- include/ode/memory.h \
- ode/src/obstack.h \
- ode/src/objects.h \
- include/ode/mass.h \
- ode/src/array.h
-ode/src/odemath.o: \
- ode/src/odemath.cpp \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h \
- include/ode/odemath.h
-ode/src/matrix.o: \
- ode/src/matrix.cpp \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h \
- include/ode/matrix.h
-ode/src/misc.o: \
- ode/src/misc.cpp \
- include/ode/config.h \
- include/ode/misc.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/matrix.h
-ode/src/rotation.o: \
- ode/src/rotation.cpp \
- include/ode/rotation.h \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h
-ode/src/mass.o: \
- ode/src/mass.cpp \
- include/ode/config.h \
- include/ode/mass.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/odemath.h \
- include/ode/matrix.h
-ode/src/ode.o: \
- ode/src/ode.cpp \
- ode/src/objects.h \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/mass.h \
- ode/src/array.h \
- include/ode/ode.h \
- include/ode/contact.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- ode/src/joint.h \
- ode/src/obstack.h \
- ode/src/step.h
-ode/src/step.o: \
- ode/src/step.cpp \
- ode/src/objects.h \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/mass.h \
- ode/src/array.h \
- ode/src/joint.h \
- include/ode/contact.h \
- ode/src/obstack.h \
- include/ode/odemath.h \
- include/ode/rotation.h \
- include/ode/timer.h \
- include/ode/matrix.h \
- ode/src/lcp.h
-ode/src/lcp.o: \
- ode/src/lcp.cpp \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h \
- ode/src/lcp.h \
- include/ode/matrix.h \
- include/ode/misc.h \
- ode/src/mat.h \
- include/ode/timer.h
-ode/src/joint.o: \
- ode/src/joint.cpp \
- include/ode/odemath.h \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h \
- include/ode/rotation.h \
- include/ode/matrix.h \
- ode/src/joint.h \
- ode/src/objects.h \
- include/ode/memory.h \
- include/ode/mass.h \
- ode/src/array.h \
- include/ode/contact.h \
- ode/src/obstack.h
-ode/src/space.o: \
- ode/src/space.cpp \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/contact.h \
- include/ode/memory.h \
- ode/src/objects.h \
- include/ode/mass.h \
- ode/src/array.h \
- ode/src/geom_internal.h
-ode/src/geom.o: \
- ode/src/geom.cpp \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h \
- include/ode/geom.h \
- include/ode/space.h \
- include/ode/contact.h \
- include/ode/rotation.h \
- include/ode/odemath.h \
- include/ode/memory.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/mass.h \
- include/ode/matrix.h \
- ode/src/objects.h \
- ode/src/array.h \
- ode/src/geom_internal.h
-ode/src/timer.o: \
- ode/src/timer.cpp \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h \
- include/ode/timer.h
-ode/src/mat.o: \
- ode/src/mat.cpp \
- include/ode/config.h \
- include/ode/misc.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/matrix.h \
- include/ode/memory.h \
- ode/src/mat.h
-ode/src/testing.o: \
- ode/src/testing.cpp \
- include/ode/config.h \
- include/ode/misc.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- ode/src/testing.h \
- ode/src/array.h
-ode/src/fastldlt.o: \
- ode/src/fastldlt.c \
- include/ode/matrix.h \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h
-ode/src/fastlsolve.o: \
- ode/src/fastlsolve.c \
- include/ode/matrix.h \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h
-ode/src/fastltsolve.o: \
- ode/src/fastltsolve.c \
- include/ode/matrix.h \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h
-ode/src/fastdot.o: \
- ode/src/fastdot.c \
- include/ode/matrix.h \
- include/ode/common.h \
- include/ode/config.h \
- include/ode/error.h
-drawstuff/src/drawstuff.o: \
- drawstuff/src/drawstuff.cpp \
- include/ode/config.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h \
- drawstuff/src/internal.h
-drawstuff/src/x11.o: \
- drawstuff/src/x11.cpp \
- include/ode/config.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h \
- drawstuff/src/internal.h
-ode/test/test_ode.o: \
- ode/test/test_ode.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h
-ode/test/test_chain2.o: \
- ode/test/test_chain2.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-ode/test/test_hinge.o: \
- ode/test/test_hinge.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-ode/test/test_slider.o: \
- ode/test/test_slider.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-ode/test/test_collision.o: \
- ode/test/test_collision.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-ode/test/test_boxstack.o: \
- ode/test/test_boxstack.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-ode/test/test_buggy.o: \
- ode/test/test_buggy.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-ode/test/test_joints.o: \
- ode/test/test_joints.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-ode/test/test_space.o: \
- ode/test/test_space.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-ode/test/test_I.o: \
- ode/test/test_I.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-ode/test/test_step.o: \
- ode/test/test_step.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-ode/test/test_friction.o: \
- ode/test/test_friction.cpp \
- include/ode/ode.h \
- include/ode/config.h \
- include/ode/contact.h \
- include/ode/common.h \
- include/ode/error.h \
- include/ode/memory.h \
- include/ode/odemath.h \
- include/ode/matrix.h \
- include/ode/timer.h \
- include/ode/rotation.h \
- include/ode/mass.h \
- include/ode/space.h \
- include/ode/geom.h \
- include/ode/misc.h \
- include/ode/objects.h \
- include/ode/odecpp.h \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
-drawstuff/dstest/dstest.o: \
- drawstuff/dstest/dstest.cpp \
- include/drawstuff/drawstuff.h \
- include/drawstuff/version.h
diff --git a/extern/ode/dist/README b/extern/ode/dist/README
deleted file mode 100644
index 6b151d1a27b..00000000000
--- a/extern/ode/dist/README
+++ /dev/null
@@ -1,30 +0,0 @@
-The Open Dynamics Engine (ODE), Copyright (C) 2001,2002 Russell L. Smith.
--------------------------------------------------------------------------
-
-ODE is a free, industrial quality library for simulating articulated
-rigid body dynamics - for example ground vehicles, legged creatures,
-and moving objects in VR environments. It is fast, flexible, robust
-and platform independent, with advanced joints, contact with friction,
-and built-in collision detection.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of EITHER:
- (1) The GNU Lesser General Public License as published by the Free
- Software Foundation; either version 2.1 of the License, or (at
- your option) any later version. The text of the GNU Lesser
- General Public License is included with this library in the
- file LICENSE.TXT.
- (2) The BSD-style license that is included with this library in
- the file LICENSE-BSD.TXT.
-
-This library 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 files
-LICENSE.TXT and LICENSE-BSD.TXT for more details.
-
- * Installation instructions are in the INSTALL file
-
- * The ODE web pages are at http://q12.org/ode/
-
- * The ODE documentation is in the file ode/doc/ode.html, or you
- can view it on the web at http://q12.org/ode/ode-docs.html
diff --git a/extern/ode/dist/README_BLENDER b/extern/ode/dist/README_BLENDER
deleted file mode 100644
index 64d97624a55..00000000000
--- a/extern/ode/dist/README_BLENDER
+++ /dev/null
@@ -1,18 +0,0 @@
-Checked out from ODE cvs (http://q12.org) on or around
-Fri Oct 18 14:24:11 GMT 2002
-
-Note that ODE has its own build system. The source/ode/
-directory is traversed by Blender's source/Makefile. However
-source/ode/config/user-settings has to be set correctly
-depending on the target platform. This needs to be done in the
-source/Makefile which determines the proper platform, then copies
-the appropriate platform-specific user-settings.platform file to
-source/ode/config/user-settings. Currently source/ode/user-settings is
-for Linux.
-
-Don't change the source in this directory. This source code is
-maintained on the CVS server at http://q12.org and is provided here
-so that Blender developers can compile ODE without having to separately
-download and install it. This source code can and should periodically
-be synchronized (manually) with the source code at http://q12.org.
-
diff --git a/extern/ode/dist/config/README b/extern/ode/dist/config/README
deleted file mode 100644
index 0fa18062a4e..00000000000
--- a/extern/ode/dist/config/README
+++ /dev/null
@@ -1,41 +0,0 @@
-
-variable names used in the per-platform makefile configuration files:
-
-platform stuff
---------------
-
-WINDOWS set to 1 if this is a microsoft windows based platform
-
-filesystem stuff and commands
------------------------------
-
-THIS_DIR prefix to run a command from the current directory
-DEL_CMD the name of the delete command
-
-compiler stuff
---------------
-
-CC the C/C++ compiler to use
-OBJ the object file extension
-C_FLAGS the standard set of compiler flags
-C_INC flag to add an include path
-C_OUT flag to specify the object file output
-C_EXEOUT flag to specify the executable file output
-C_DEF flag to add a define
-C_OPT flag to set the optimization level
-OPT the optimization level to use
-
-library archiver
-----------------
-
-AR library archiver command
-RANLIB ranlib command, if necessary
-LIB_PREFIX library file prefix
-LIB_SUFFIX library file suffix
-LINK_OPENGL link flags to link in windowing stuff and opengl
-LINK_MATH link flags to link in the system math library
-
-windows specific stuff
-----------------------
-
-RC_RULE makefile rule to use for the resource compiler
diff --git a/extern/ode/dist/config/makefile.cygwin b/extern/ode/dist/config/makefile.cygwin
deleted file mode 100644
index de23b71a29f..00000000000
--- a/extern/ode/dist/config/makefile.cygwin
+++ /dev/null
@@ -1,28 +0,0 @@
-WINDOWS=1
-THIS_DIR=./
-DEL_CMD=rm -f
-CC=gcc
-OBJ=.o
-C_FLAGS=-c -Wall -fno-exceptions -fno-rtti -DWIN32 -DCYGWIN
-C_INC=-I
-C_OUT=-o
-C_EXEOUT=-o
-C_DEF=-D
-C_OPT=-O
-AR=ar rc
-RANLIB=
-LIB_PREFIX=lib
-LIB_SUFFIX=.a
-LINK_OPENGL=-lComctl32 -lkernel32 -luser32 -lgdi32 -lOpenGL32 -lGlu32
-LINK_MATH=-lm
-RC_RULE=windres -I rc -O coff $< $@
-
-ifeq ($(BUILD),release)
-OPT=2
-C_FLAGS+=-fomit-frame-pointer -ffast-math
-endif
-
-ifeq ($(BUILD),debug)
-OPT=0
-C_FLAGS+=-g
-endif
diff --git a/extern/ode/dist/config/makefile.mingw b/extern/ode/dist/config/makefile.mingw
deleted file mode 100644
index 4b18fb6bcdc..00000000000
--- a/extern/ode/dist/config/makefile.mingw
+++ /dev/null
@@ -1,28 +0,0 @@
-WINDOWS=1
-THIS_DIR=
-DEL_CMD=tools\rm
-CC=gcc
-OBJ=.o
-C_FLAGS=-c -Wall -fno-exceptions -fno-rtti -DWIN32
-C_INC=-I
-C_OUT=-o
-C_EXEOUT=-o
-C_DEF=-D
-C_OPT=-O
-AR=ar rc
-RANLIB=
-LIB_PREFIX=lib
-LIB_SUFFIX=.a
-LINK_OPENGL=-lComctl32 -lkernel32 -luser32 -lgdi32 -lOpenGL32 -lGlu32
-LINK_MATH=-lm
-RC_RULE=windres -I rc -O coff $< $@
-
-ifeq ($(BUILD),release)
-OPT=2
-C_FLAGS+=-fomit-frame-pointer -ffast-math
-endif
-
-ifeq ($(BUILD),debug)
-OPT=0
-C_FLAGS+=-g
-endif
diff --git a/extern/ode/dist/config/makefile.msvc b/extern/ode/dist/config/makefile.msvc
deleted file mode 100644
index 9d4da0bf912..00000000000
--- a/extern/ode/dist/config/makefile.msvc
+++ /dev/null
@@ -1,27 +0,0 @@
-WINDOWS=1
-THIS_DIR=
-DEL_CMD=tools\rm
-CC=cl /nologo /DWIN32 /DMSVC /DSHAREDLIBEXPORT= /DSHAREDLIBIMPORT=
-OBJ=.obj
-C_FLAGS=/c /GR- /GX- /W3 /GF
-C_INC=/I
-C_OUT=/Fo
-C_EXEOUT=/Fe
-C_DEF=/D
-C_OPT=/O
-AR=lib /nologo /OUT:
-RANLIB=
-LIB_PREFIX=
-LIB_SUFFIX=.lib
-LINK_OPENGL=Comctl32.lib kernel32.lib user32.lib gdi32.lib OpenGL32.lib Glu32.lib
-LINK_MATH=
-RC_RULE=rc /r /fo$@ $<
-
-ifeq ($(BUILD),release)
-OPT=2
-C_FLAGS+=/Oy
-endif
-
-ifeq ($(BUILD),debug)
-OPT=d
-endif
diff --git a/extern/ode/dist/config/makefile.msvc-dll b/extern/ode/dist/config/makefile.msvc-dll
deleted file mode 100644
index fe495893616..00000000000
--- a/extern/ode/dist/config/makefile.msvc-dll
+++ /dev/null
@@ -1,29 +0,0 @@
-WINDOWS=1
-THIS_DIR=
-DEL_CMD=tools\rm
-CC=cl /nologo /DWIN32 /DMSVC /DSHAREDLIBIMPORT=__declspec(dllimport) /DSHAREDLIBEXPORT=__declspec(dllexport)
-OBJ=.obj
-C_FLAGS=/c /GR- /GX- /W3 /GF
-C_INC=/I
-C_OUT=/Fo
-C_EXEOUT=/Fe
-C_DEF=/D
-C_OPT=/O
-AR=lib /nologo /OUT:
-RANLIB=
-LIB_PREFIX=
-LIB_SUFFIX=.lib
-LINK_OPENGL=Comctl32.lib kernel32.lib user32.lib gdi32.lib OpenGL32.lib Glu32.lib
-LINK_MATH=
-RC_RULE=rc /r /fo$@ $<
-
-ifeq ($(BUILD),release)
-OPT=2
-C_FLAGS+=/Oy
-endif
-
-ifeq ($(BUILD),debug)
-OPT=d
-endif
-
-ODE_LIB_AR_RULE=link /dll /nologo /SUBSYSTEM:WINDOWS /LIBPATH:"C:\Programme\Micros~2\VC98\Lib" /def:config/msvcdefs.def $(LINK_OPENGL) /OUT:$(patsubst %.lib,%.dll,$@)
diff --git a/extern/ode/dist/config/makefile.osx b/extern/ode/dist/config/makefile.osx
deleted file mode 100644
index 1d5e0f42252..00000000000
--- a/extern/ode/dist/config/makefile.osx
+++ /dev/null
@@ -1,26 +0,0 @@
-THIS_DIR=./
-DEL_CMD=rm -f
-CC=cc
-OBJ=.o
-C_FLAGS=-c -Wall -fno-rtti -fno-exceptions -Wall -I/usr/X11R6/include
-C_INC=-I
-C_OUT=-o
-C_EXEOUT=-o
-C_DEF=-D
-C_OPT=-O
-AR=ar rc
-RANLIB=ranlib
-LIB_PREFIX=lib
-LIB_SUFFIX=.a
-LINK_OPENGL=-L/usr/X11R6/lib -L/usr/X11/lib -L/usr/lib/X11R6 -L/usr/lib/X11 -lX11 -lGL -lGLU -lstdc++
-LINK_MATH=-lm
-
-ifeq ($(BUILD),release)
-OPT=2
-C_FLAGS+=-fomit-frame-pointer -ffast-math
-endif
-
-ifeq ($(BUILD),debug)
-OPT=0
-C_FLAGS+=-g
-endif
diff --git a/extern/ode/dist/config/makefile.unix-gcc b/extern/ode/dist/config/makefile.unix-gcc
deleted file mode 100644
index b9d07632353..00000000000
--- a/extern/ode/dist/config/makefile.unix-gcc
+++ /dev/null
@@ -1,29 +0,0 @@
-THIS_DIR=./
-DEL_CMD=rm -f
-CC=gcc
-OBJ=.o
-C_FLAGS=-c -Wall -fno-rtti -fno-exceptions -Wall
-C_INC=-I
-C_OUT=-o
-C_EXEOUT=-o
-C_DEF=-D
-C_OPT=-O
-AR=ar rc
-RANLIB=
-LIB_PREFIX=lib
-LIB_SUFFIX=.a
-LINK_OPENGL=-L/usr/X11R6/lib -L/usr/X11/lib -L/usr/lib/X11R6 -L/usr/lib/X11 -lX11 -lGL -lGLU
-LINK_MATH=-lm
-
-ifeq ($(BUILD),release)
-OPT=2
-C_FLAGS+=-fomit-frame-pointer -ffast-math
-endif
-
-ifeq ($(BUILD),debug)
-OPT=0
-C_FLAGS+=-g
-endif
-
-# some other possible flags:
-# -malign-double -mpentiumpro -march=pentiumpro
diff --git a/extern/ode/dist/config/makefile.unix-generic b/extern/ode/dist/config/makefile.unix-generic
deleted file mode 100644
index f435e1a0db8..00000000000
--- a/extern/ode/dist/config/makefile.unix-generic
+++ /dev/null
@@ -1,24 +0,0 @@
-THIS_DIR=./
-DEL_CMD=rm -f
-CC=CC
-OBJ=.o
-C_FLAGS=-c
-C_INC=-I
-C_OUT=-o
-C_EXEOUT=-o
-C_DEF=-D
-C_OPT=-O
-AR=ar rc
-RANLIB=
-LIB_PREFIX=lib
-LIB_SUFFIX=.a
-LINK_OPENGL=-L/usr/X11R6/lib -L/usr/X11/lib -L/usr/lib/X11R6 -L/usr/lib/X11 -lX11 -lGL -lGLU
-LINK_MATH=-lm
-
-ifeq ($(BUILD),release)
-OPT=2
-endif
-
-ifeq ($(BUILD),debug)
-OPT=0
-endif
diff --git a/extern/ode/dist/config/msvcdefs.def b/extern/ode/dist/config/msvcdefs.def
deleted file mode 100644
index 11258ab9aa8..00000000000
--- a/extern/ode/dist/config/msvcdefs.def
+++ /dev/null
@@ -1,228 +0,0 @@
-LIBRARY ODE
-EXPORTS
-dAreConnected
-dBodyAddForce
-dBodyAddForceAtPos
-dBodyAddForceAtRelPos
-dBodyAddRelForce
-dBodyAddRelForceAtPos
-dBodyAddRelForceAtRelPos
-dBodyAddRelTorque
-dBodyAddTorque
-dBodyCreate
-dBodyDestroy
-dBodyDisable
-dBodyEnable
-dBodyGetAngularVel
-dBodyGetData
-dBodyGetFiniteRotationAxis
-dBodyGetFiniteRotationMode
-dBodyGetForce
-dBodyGetGravityMode
-dBodyGetJoint
-dBodyGetLinearVel
-dBodyGetMass
-dBodyGetNumJoints
-dBodyGetPointVel
-dBodyGetPosRelPoint
-dBodyGetPosition
-dBodyGetQuaternion
-dBodyGetRelPointPos
-dBodyGetRelPointVel
-dBodyGetRotation
-dBodyGetTorque
-dBodyIsEnabled
-dBodySetAngularVel
-dBodySetData
-dBodySetFiniteRotationAxis
-dBodySetFiniteRotationMode
-dBodySetForce
-dBodySetGravityMode
-dBodySetLinearVel
-dBodySetMass
-dBodySetPosition
-dBodySetQuaternion
-dBodySetRotation
-dBodySetTorque
-dBodyVectorFromWorld
-dBodyVectorToWorld
-dBoxBox
-dBoxClass
-dBoxTouchesBox
-dCCylinderClass
-dClearUpperTriangle
-dCloseODE
-dClosestLineSegmentPoints
-dCollide
-dCreateBox
-dCreateCCylinder
-dCreateGeom
-dCreateGeomClass
-dCreateGeomGroup
-dCreateGeomTransform
-dCreatePlane
-dCreateSphere
-dError
-dFactorCholesky
-dFactorLDLT
-dGeomBoxGetLengths
-dGeomBoxSetLengths
-dGeomCCylinderGetParams
-dGeomCCylinderSetParams
-dGeomDestroy
-dGeomGetAABB
-dGeomGetBody
-dGeomGetClass
-dGeomGetClassData
-dGeomGetData
-dGeomGetPosition
-dGeomGetRotation
-dGeomGetSpaceAABB
-dGeomGroupAdd
-dGeomGroupGetGeom
-dGeomGroupGetNumGeoms
-dGeomGroupRemove
-dGeomPlaneGetParams
-dGeomPlaneSetParams
-dGeomSetBody
-dGeomSetData
-dGeomSetPosition
-dGeomSetRotation
-dGeomSphereGetRadius
-dGeomSphereSetRadius
-dGeomTransformClass
-dGeomTransformGetCleanup
-dGeomTransformGetGeom
-dGeomTransformSetCleanup
-dGeomTransformSetGeom
-dHashSpaceCreate
-dHashSpaceSetLevels
-dInfiniteAABB
-dInfinityValue
-dInvertPDMatrix
-dIsPositiveDefinite
-dJointAttach
-dJointCreateAMotor
-dJointCreateBall
-dJointCreateContact
-dJointCreateFixed
-dJointCreateHinge
-dJointCreateHinge2
-dJointCreateSlider
-dJointCreateUniversal
-dJointDestroy
-dJointGetAMotorAngle
-dJointGetAMotorAngleRate
-dJointGetAMotorAxis
-dJointGetAMotorAxisRel
-dJointGetAMotorMode
-dJointGetAMotorNumAxes
-dJointGetAMotorParam
-dJointGetBallAnchor
-dJointGetBody
-dJointGetData
-dJointGetHinge2Anchor
-dJointGetHinge2Angle1
-dJointGetHinge2Angle1Rate
-dJointGetHinge2Angle2Rate
-dJointGetHinge2Axis1
-dJointGetHinge2Axis2
-dJointGetHinge2Param
-dJointGetHingeAnchor
-dJointGetHingeAngle
-dJointGetHingeAngleRate
-dJointGetHingeAxis
-dJointGetHingeParam
-dJointGetSliderAxis
-dJointGetSliderParam
-dJointGetSliderPosition
-dJointGetSliderPositionRate
-dJointGetType
-dJointGetUniversalAnchor
-dJointGetUniversalAxis1
-dJointGetUniversalAxis2
-dJointGroupCreate
-dJointGroupDestroy
-dJointGroupEmpty
-dJointSetAMotorAngle
-dJointSetAMotorAxis
-dJointSetAMotorMode
-dJointSetAMotorNumAxes
-dJointSetAMotorParam
-dJointSetBallAnchor
-dJointSetData
-dJointSetFixed
-dJointSetHinge2Anchor
-dJointSetHinge2Axis1
-dJointSetHinge2Axis2
-dJointSetHinge2Param
-dJointSetHingeAnchor
-dJointSetHingeAxis
-dJointSetHingeParam
-dJointSetSliderAxis
-dJointSetSliderParam
-dJointSetUniversalAnchor
-dJointSetUniversalAxis1
-dJointSetUniversalAxis2
-dLDLTAddTL
-dLDLTRemove
-dMakeRandomMatrix
-dMakeRandomVector
-dMassAdd
-dMassAdjust
-dMassRotate
-dMassSetBox
-dMassSetCappedCylinder
-dMassSetParameters
-dMassSetSphere
-dMassSetZero
-dMassTranslate
-dMaxDifference
-dMultiply0
-dMultiply1
-dMultiply2
-dNormalize3
-dNormalize4
-dPlaneSpace
-dQFromAxisAndAngle
-dQMultiply0
-dQMultiply1
-dQMultiply2
-dQMultiply3
-dQSetIdentity
-dQtoR
-dRFrom2Axes
-dRFromAxisAndAngle
-dRFromEulerAngles
-dRSetIdentity
-dRandInt
-dRandReal
-dRandSetSeed
-dRemoveRowCol
-dRtoQ
-dSetMessageHandler
-dSetZero
-dSimpleSpaceCreate
-dSolveCholesky
-dSolveLDLT
-dSpaceAdd
-dSpaceCollide
-dSpaceDestroy
-dSpaceQuery
-dSpaceRemove
-dSphereClass
-dTestMatrixComparison
-dTestRand
-dTestSolveLCP
-dWorldCreate
-dWorldDestroy
-dWorldGetCFM
-dWorldGetERP
-dWorldGetGravity
-dWorldImpulseToForce
-dWorldSetCFM
-dWorldSetERP
-dWorldSetGravity
-dWorldStep
-dWorldStep
-dWtoDQ
diff --git a/extern/ode/dist/config/user-settings b/extern/ode/dist/config/user-settings
deleted file mode 100644
index d632eba9678..00000000000
--- a/extern/ode/dist/config/user-settings
+++ /dev/null
@@ -1,31 +0,0 @@
-# ODE user settings: the following variables must be set by the user
-
-# (1) the platform to use. this name should have a corresponding
-# makefile.PLATFORM file. currently supported platforms are:
-# msvc microsoft visual C/C++
-# msvc-dll microsoft visual C/C++, create a DLL
-# mingw minimalist GNU for windows
-# cygwin cygnus GNU for windows
-# unix-gcc GNU gcc on unix
-# unix-generic generic unix compiler. you may need to edit the CC
-# variable in makefile.unix-generic
-# osx Mac OS-X, with the gnu compiler.
-
-PLATFORM=unix-gcc
-
-# (2) the floating point precision to use (either "SINGLE" or "DOUBLE")
-
-PRECISION=SINGLE
-#PRECISION=DOUBLE
-
-# (3) the library type to build (either "debug" if you are doing development,
-# or "release" for the optimized library)
-
-#BUILD=debug
-BUILD=release
-
-# (4) if you are using an old version of MS-Windows that has command line
-# length limitations then you will need to set this to "1". otherwise,
-# leave it at "0".
-
-WINDOWS16=0
diff --git a/extern/ode/dist/config/user-settings.example b/extern/ode/dist/config/user-settings.example
deleted file mode 100644
index 0b0d480a25a..00000000000
--- a/extern/ode/dist/config/user-settings.example
+++ /dev/null
@@ -1,31 +0,0 @@
-# ODE user settings: the following variables must be set by the user
-
-# (1) the platform to use. this name should have a corresponding
-# makefile.PLATFORM file. currently supported platforms are:
-# msvc microsoft visual C/C++
-# msvc-dll microsoft visual C/C++, create a DLL
-# mingw minimalist GNU for windows
-# cygwin cygnus GNU for windows
-# unix-gcc GNU gcc on unix
-# unix-generic generic unix compiler. you may need to edit the CC
-# variable in makefile.unix-generic
-# osx Mac OS-X, with the gnu compiler.
-
-PLATFORM=unix-gcc
-
-# (2) the floating point precision to use (either "SINGLE" or "DOUBLE")
-
-#PRECISION=SINGLE
-PRECISION=DOUBLE
-
-# (3) the library type to build (either "debug" if you are doing development,
-# or "release" for the optimized library)
-
-#BUILD=debug
-BUILD=release
-
-# (4) if you are using an old version of MS-Windows that has command line
-# length limitations then you will need to set this to "1". otherwise,
-# leave it at "0".
-
-WINDOWS16=0
diff --git a/extern/ode/dist/configurator.c b/extern/ode/dist/configurator.c
deleted file mode 100644
index 8129716881d..00000000000
--- a/extern/ode/dist/configurator.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/*
-
-this program discovers some system configuration stuff, prior to compiling
-ODE. the usage is:
-
- configurator <config.h-file-to-generate> <compiler-command-line>
- <delete-command-line> <THIS_DIR-variable>
-
-this program looks long, but it really has an extremely simple structure and
-should be very easy for anyone to modify. it should be very portable as it
-is written in straight ANSI C and only uses the following library functions:
- * printf
- * fopen (assumes 0 returned on failure)
- * fclose
- * fprintf
- * system
- * exit
-except where stated, we do not assume anything about the return codes from
-these functions.
-
-why didn't i just use GNU autoconf? :
- * autoconf needs a bourne shell and a bunch of other tools that windows
- users may not have.
- * i like reinventing the wheel.
-
-*/
-
-#include <stdio.h>
-
-/****************************************************************************/
-/* project constants */
-
-#define SETUP_SHLIB_DEFS \
- "#ifndef SHAREDLIBIMPORT\n" \
- "#define SHAREDLIBIMPORT\n" \
- "#endif\n" \
- "#ifndef SHAREDLIBEXPORT\n" \
- "#define SHAREDLIBEXPORT\n" \
- "#endif\n"
-
-/* the config.h header */
-char *config_h_part1 =
-"/* per-machine configuration. this file is automatically generated. */\n"
-"\n"
-"#ifndef _ODE_CONFIG_H_\n"
-"#define _ODE_CONFIG_H_\n"
-"\n"
-"/* shared lib definitions */\n"
-SETUP_SHLIB_DEFS
-"\n"
-"/* standard system headers */\n";
-
-
-char *config_h_part2 =
-"\n"
-"#ifdef __cplusplus\n"
-"extern \"C\" {\n"
-"#endif\n"
-"\n";
-
-/* the config.h footer */
-char *config_h_footer =
-"#ifdef __cplusplus\n"
-"}\n"
-"#endif\n"
-"#endif\n";
-
-/****************************************************************************/
-/* implementations of some string functions. these are prefixed with 'x'
- * to prevent any conflicts with built-in functions.
- */
-
-#define strcpy xstrcpy
-void xstrcpy (char *dest, char *src)
-{
- while (*src) *dest++ = *src++;
- *dest = 0;
-}
-
-
-#define strcat xstrcat
-void xstrcat (char *dest, char *src)
-{
- while (*dest) dest++;
- while (*src) *dest++ = *src++;
- *dest = 0;
-}
-
-/****************************************************************************/
-/* utility functions */
-
-/* print an error message and exit */
-
-void fatal_error (char *message)
-{
- printf ("\n*** configurator failed: %s.\n\n"
- "please fix your configuration and try again.\n"
- "if you have to fix the configurator program or the makefiles, "
- "please email\n"
- "your changes to the ODE mailing list (ode@q12.org).\n\n", message);
- exit (0);
-}
-
-
-/* open a file, generate an error if it can't be done */
-
-FILE * xfopen (char *filename, char *mode)
-{
- FILE *f;
- f = fopen (filename,mode);
- if (!f) fatal_error ("can not open a file");
- return f;
-}
-
-
-/* return 1 if the file exists or 0 if not */
-
-int file_exists (char *filename)
-{
- FILE *f;
- f = fopen (filename,"rb");
- if (f) fclose (f);
- return (f != 0);
-}
-
-
-/* write a string to a new file */
-
-void write_to_file (char *filename, char *s)
-{
- FILE *f = xfopen (filename,"wt");
- fprintf (f,"%s",s);
- fclose (f);
-}
-
-
-/* write a comment to a header file */
-
-void write_header_comment (FILE *file, char *description)
-{
- fprintf (file,"/* %s */\n",description);
- printf ("%s ...\n",description);
-}
-
-
-/* delete a file */
-
-char *delete_cmd_line = 0;
-void delete_file (char *filename)
-{
- char cmd[1000];
- strcpy (cmd,delete_cmd_line);
- strcat (cmd," ");
- strcat (cmd,filename);
- printf ("%s\n",cmd);
- system (cmd);
-}
-
-
-/* run a compile command */
-
-char *compile_cmd_line = 0;
-void compile (char *output, char *input)
-{
- char cmd[1000];
- strcpy (cmd,compile_cmd_line);
- strcat (cmd,output);
- strcat (cmd," ");
- strcat (cmd,input);
- printf ("%s\n",cmd);
- system (cmd);
-}
-
-
-/* run a program we've just compiled */
-
-char *run_prefix = "";
-void run (char *filename)
-{
- char cmd[1000];
- strcpy (cmd,run_prefix);
- strcat (cmd,filename);
- printf ("%s\n",cmd);
- system (cmd);
-}
-
-/****************************************************************************/
-/* system tests */
-
-void check_if_this_is_a_pentium (FILE *file)
-{
- write_header_comment (file,"is this a pentium on a gcc-based platform?");
- write_to_file ("ctest.c",
- "int main() {\n"
- " asm (\"mov $0,%%eax\\n cpuid\\n\" : : : \"%eax\");\n"
- " return 0;\n"
- "}\n");
- delete_file ("ctest.exe");
- compile ("ctest.exe","ctest.c");
- if (file_exists ("ctest.exe")) {
- fprintf (file,"#define PENTIUM 1\n\n");
- }
- else {
- fprintf (file,"/* #define PENTIUM 1 -- not a pentium */\n\n");
- }
-
- delete_file ("ctest.c");
- delete_file ("ctest.exe");
-}
-
-/****************************************************************************/
-/* tests: standard headers */
-
-void get_all_standard_headers (FILE *file)
-{
- int i;
- FILE *f;
- char *header[7] = {"stdio.h", "stdlib.h", "math.h", "string.h",
- "stdarg.h", "malloc.h", "alloca.h"};
-
- for (i=0; i < sizeof(header)/sizeof(char*); i++) {
- FILE *f = xfopen ("ctest.c","wt");
- fprintf (f,"#include <%s>\nint main() { return 0; }\n",header[i]);
- fclose (f);
- delete_file ("ctest.exe");
- compile ("ctest.exe","ctest.c");
- if (file_exists ("ctest.exe")) {
- fprintf (file,"#include <%s>\n",header[i]);
- }
- }
-
- delete_file ("ctest.c");
- delete_file ("ctest.exe");
-}
-
-/****************************************************************************/
-/* tests: typedefs and constants for ODE */
-
-void get_ODE_integer_typedefs (FILE *file)
-{
- write_header_comment (file,"integer types (we assume int >= 32 bits)");
- if (sizeof(char) != 1) fatal_error ("expecting sizeof(char) == 1");
- if (sizeof(int) < 4) fatal_error ("expecting sizeof(int) >= 4");
- fprintf (file,"typedef char int8;\ntypedef unsigned char uint8;\n");
- if (sizeof(short) == 4) {
- fprintf (file,"typedef short int32;\ntypedef unsigned short uint32;\n");
- }
- else if (sizeof(int) == 4) {
- fprintf (file,"typedef int int32;\ntypedef unsigned int uint32;\n");
- }
- else {
- fatal_error ("can not find 4 byte integer type");
- }
- fprintf (file,"\n"
- "/* an integer type that we can safely cast a pointer to and\n"
- " * from without loss of bits.\n"
- " */\n");
- if (sizeof(short) == sizeof(void*)) {
- fprintf (file,"typedef unsigned short intP;\n");
- }
- else if (sizeof(int) == sizeof(void*)) {
- fprintf (file,"typedef unsigned int intP;\n");
- }
- else if (sizeof(long int) == sizeof(void*)) {
- fprintf (file,"typedef unsigned long int intP;\n");
- }
- fprintf (file,"\n");
-}
-
-
-void get_ODE_float_stuff (FILE *file)
-{
- char *suffix,*type;
- int i;
- FILE *f;
-
-#define SHARED_LIB_SPEC_DECISION \
- "#if defined SHARED_CONFIG_H_INCLUDED_FROM_DEFINING_FILE\n" \
- " #define GLOBAL_SHAREDLIB_SPEC SHAREDLIBEXPORT\n" \
- "#else \n" \
- " #define GLOBAL_SHAREDLIB_SPEC SHAREDLIBIMPORT\n" \
- "#endif\n"
-
-#define UNDEF_SHAREDLIB_SPEC "\n#undef GLOBAL_SHAREDLIB_SPEC\n"
-
-#ifdef dSINGLE
-
-#define INFBYTES SHARED_LIB_SPEC_DECISION "union dInfBytes { unsigned char c[4]; float f; };\nextern GLOBAL_SHAREDLIB_SPEC union dInfBytes dInfinityValue;\n#define dInfinity (dInfinityValue.f)"
-
- char *inc[6] = {"#include <math.h>",
- "#include <math.h>",
- "",
- "",
- "",
- ""};
- char *decl[6] = {
- "SHAREDLIBEXPORT double dInfinityValue = HUGE_VALF;",
- "SHAREDLIBEXPORT double dInfinityValue = HUGE_VAL;",
- "SHAREDLIBEXPORT union dInfBytes dInfinityValue = {{0x7f,0x80,0,0}};",
- "SHAREDLIBEXPORT union dInfBytes dInfinityValue = {{0,0,0x80,0x7f}};",
- "SHAREDLIBEXPORT double dInfinityValue = 1.0f/0.0f;",
- "SHAREDLIBEXPORT double dInfinityValue = 1e20f;"};
- char *inf[6] = {
- SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC,
- SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC,
- INFBYTES UNDEF_SHAREDLIB_SPEC,
- INFBYTES UNDEF_SHAREDLIB_SPEC,
- SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC,
- SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC};
-
-#else /* not dSINGLE, must be dDOUBLE */
-
-#define INFBYTES SHARED_LIB_SPEC_DECISION "union dInfBytes { unsigned char c[8]; double d; };\nextern GLOBAL_SHAREDLIB_SPEC union dInfBytes dInfinityValue;\n#define dInfinity (dInfinityValue.d)"
-
- char *inc[5] = {
- "#include <math.h>",
- "",
- "",
- "",
- ""};
- char *decl[5] = {
- "SHAREDLIBEXPORT double dInfinityValue = HUGE_VAL;",
- "SHAREDLIBEXPORT union dInfBytes dInfinityValue = {{0x7f,0xf0,0,0,0,0,0,0}};",
- "SHAREDLIBEXPORT union dInfBytes dInfinityValue = {{0,0,0,0,0,0,0xf0,0x7f}};",
- "SHAREDLIBEXPORT double dInfinityValue = 1.0/0.0;",
- "SHAREDLIBEXPORT double dInfinityValue = 1e20;"};
- char *inf[5] = {
- SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC,
- INFBYTES UNDEF_SHAREDLIB_SPEC,
- INFBYTES UNDEF_SHAREDLIB_SPEC,
- SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC,
- SHARED_LIB_SPEC_DECISION "extern GLOBAL_SHAREDLIB_SPEC double dInfinityValue;\n#define dInfinity dInfinityValue" UNDEF_SHAREDLIB_SPEC};
-#endif
-
- write_header_comment (file,"select the base floating point type");
-#ifdef dSINGLE
- fprintf (file,"#define dSINGLE 1\n\n");
- type = "float";
- suffix = "f";
-#else
- fprintf (file,"#define dDOUBLE 1\n\n");
- type = "double";
- suffix = "";
-#endif
-
- /* infinity */
- write_header_comment (file,"the floating point infinity");
-
- /* try the different infinity constants until one works */
- for (i=0; i < sizeof(inf)/sizeof(char*); i++) {
- f = xfopen ("ctest.c","wt");
- fprintf (f,
- "#include <stdio.h>\n"
- "#define SHARED_CONFIG_H_INCLUDED_FROM_DEFINING_FILE 1\n"
- SETUP_SHLIB_DEFS
- "%s\n"
- "%s\n"
- "%s\n"
- "int main() {\n"
- " if (dInfinity > 1e10%s && -dInfinity < -1e10%s &&\n"
- " -dInfinity < dInfinity) {\n"
- " FILE *f = fopen (\"data\",\"wt\");\n"
- " fprintf (f,\"foo\\n\");\n"
- " fclose (f);\n"
- " }\n"
- " return 0;\n"
- "}\n"
- ,inc[i],inf[i],decl[i],suffix,suffix);
- fclose (f);
- delete_file ("data");
- compile ("ctest.exe","ctest.c");
- run ("ctest.exe");
- if (file_exists ("data")) {
- fprintf (file,"#define DINFINITY_DECL %s\n",decl[i]);
- fprintf (file,"%s\n\n",inf[i]);
- delete_file ("ctest.c");
- delete_file ("ctest.exe");
- delete_file ("data");
- return;
- }
- }
-
- fatal_error ("can't determine dInfinity constant");
-}
-
-/****************************************************************************/
-
-int main (int argc, char **argv)
-{
- FILE *file;
-
- if (argc < 4 || argc > 5)
- fatal_error ("configurator expects 3 or 4 arguments");
- compile_cmd_line = argv[2];
- delete_cmd_line = argv[3];
- if (argc >= 5) run_prefix = argv[4];
-
- /* check some defines we should have been compiled with */
-#if !defined(dSINGLE) && !defined(dDOUBLE)
- fatal_error ("you must set PRECISION to either SINGLE or DOUBLE");
-#endif
-
- file = xfopen (argv[1],"wt");
- fprintf (file,config_h_part1);
- get_all_standard_headers (file);
- fprintf (file,config_h_part2);
- check_if_this_is_a_pentium (file);
- get_ODE_integer_typedefs (file);
- get_ODE_float_stuff (file);
- fprintf (file,config_h_footer);
- fclose (file);
-
- printf ("\n*** configurator succeeded ***\n\n");
- return 0;
-}
diff --git a/extern/ode/dist/include/ode/README b/extern/ode/dist/include/ode/README
deleted file mode 100644
index aaedfcc38fe..00000000000
--- a/extern/ode/dist/include/ode/README
+++ /dev/null
@@ -1,18 +0,0 @@
-
-this is the public C interface to the ODE library.
-
-all these files should be includable from C, i.e. they should not use any
-C++ features. everything should be protected with
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- ...
-
- #ifdef __cplusplus
- }
- #endif
-
-the only exception is the odecpp.h file, which defines a C++ wrapper for
-the C interface. remember to keep this in sync!
diff --git a/extern/ode/dist/include/ode/common.h b/extern/ode/dist/include/ode/common.h
deleted file mode 100644
index bd29d904028..00000000000
--- a/extern/ode/dist/include/ode/common.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_COMMON_H_
-#define _ODE_COMMON_H_
-
-#include <ode/config.h>
-#include <ode/error.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* configuration stuff */
-
-/* the efficient alignment. most platforms align data structures to some
- * number of bytes, but this is not always the most efficient alignment.
- * for example, many x86 compilers align to 4 bytes, but on a pentium it
- * is important to align doubles to 8 byte boundaries (for speed), and
- * the 4 floats in a SIMD register to 16 byte boundaries. many other
- * platforms have similar behavior. setting a larger alignment can waste
- * a (very) small amount of memory. NOTE: this number must be a power of
- * two. this is set to 16 by default.
- */
-#define EFFICIENT_ALIGNMENT 16
-
-
-/* constants */
-
-/* pi and 1/sqrt(2) are defined here if necessary because they don't get
- * defined in <math.h> on some platforms (like MS-Windows)
- */
-
-#ifndef M_PI
-#define M_PI REAL(3.1415926535897932384626433832795029)
-#endif
-#ifndef M_SQRT1_2
-#define M_SQRT1_2 REAL(0.7071067811865475244008443621048490)
-#endif
-
-
-/* debugging:
- * IASSERT is an internal assertion, i.e. a consistency check. if it fails
- * we want to know where.
- * UASSERT is a user assertion, i.e. if it fails a nice error message
- * should be printed for the user.
- * AASSERT is an arguments assertion, i.e. if it fails "bad argument(s)"
- * is printed.
- * DEBUGMSG just prints out a message
- */
-
-#ifndef dNODEBUG
-#ifdef __GNUC__
-#define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \
- "assertion \"" #a "\" failed in %s() [%s]",__FUNCTION__,__FILE__);
-#define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \
- msg " in %s()", __FUNCTION__);
-#define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \
- msg " in %s()", __FUNCTION__);
-#else
-#define dIASSERT(a) if (!(a)) dDebug (d_ERR_IASSERT, \
- "assertion \"" #a "\" failed in %s:%d",__FILE__,__LINE__);
-#define dUASSERT(a,msg) if (!(a)) dDebug (d_ERR_UASSERT, \
- msg " (%s:%d)", __FILE__,__LINE__);
-#define dDEBUGMSG(msg) dMessage (d_ERR_UASSERT, \
- msg " (%s:%d)", __FILE__,__LINE__);
-#endif
-#else
-#define dIASSERT(a) ;
-#define dUASSERT(a,msg) ;
-#define dDEBUGMSG(msg) ;
-#endif
-#define dAASSERT(a) dUASSERT(a,"Bad argument(s)")
-
-/* floating point data type, vector, matrix and quaternion types */
-
-#if defined(dSINGLE)
-typedef float dReal;
-#elif defined(dDOUBLE)
-typedef double dReal;
-#else
-#error You must #define dSINGLE or dDOUBLE
-#endif
-
-
-/* round an integer up to a multiple of 4, except that 0 and 1 are unmodified
- * (used to compute matrix leading dimensions)
- */
-#define dPAD(a) (((a) > 1) ? ((((a)-1)|3)+1) : (a))
-
-/* these types are mainly just used in headers */
-typedef dReal dVector3[4];
-typedef dReal dVector4[4];
-typedef dReal dMatrix3[4*3];
-typedef dReal dMatrix4[4*4];
-typedef dReal dMatrix6[8*6];
-typedef dReal dQuaternion[4];
-
-
-/* precision dependent scalar math functions */
-
-#if defined(dSINGLE)
-
-#define REAL(x) (x ## f) /* form a constant */
-#define dRecip(x) ((float)(1.0f/(x))) /* reciprocal */
-#define dSqrt(x) ((float)sqrt(x)) /* square root */
-#define dRecipSqrt(x) ((float)(1.0f/sqrt(x))) /* reciprocal square root */
-#define dSin(x) ((float)sin(x)) /* sine */
-#define dCos(x) ((float)cos(x)) /* cosine */
-#define dFabs(x) ((float)fabs(x)) /* absolute value */
-#define dAtan2(y,x) ((float)atan2((y),(x))) /* arc tangent with 2 args */
-
-#elif defined(dDOUBLE)
-
-#define REAL(x) (x)
-#define dRecip(x) (1.0/(x))
-#define dSqrt(x) sqrt(x)
-#define dRecipSqrt(x) (1.0/sqrt(x))
-#define dSin(x) sin(x)
-#define dCos(x) cos(x)
-#define dFabs(x) fabs(x)
-#define dAtan2(y,x) atan2((y),(x))
-
-#else
-#error You must #define dSINGLE or dDOUBLE
-#endif
-
-
-/* utility */
-
-
-/* round something up to be a multiple of the EFFICIENT_ALIGNMENT */
-
-#define dEFFICIENT_SIZE(x) ((((x)-1)|(EFFICIENT_ALIGNMENT-1))+1)
-
-
-/* alloca aligned to the EFFICIENT_ALIGNMENT. note that this can waste
- * up to 15 bytes per allocation, depending on what alloca() returns.
- */
-
-#define dALLOCA16(n) \
- ((char*)dEFFICIENT_SIZE(((int)(alloca((n)+(EFFICIENT_ALIGNMENT-1))))))
-
-
-/* internal object types (all prefixed with `dx') */
-
-struct dxWorld; /* dynamics world */
-struct dxSpace; /* collision space */
-struct dxBody; /* rigid body (dynamics object) */
-struct dxGeom; /* geometry (collision object) */
-struct dxJoint;
-struct dxJointNode;
-struct dxJointGroup;
-
-typedef struct dxWorld *dWorldID;
-typedef struct dxSpace *dSpaceID;
-typedef struct dxBody *dBodyID;
-typedef struct dxGeom *dGeomID;
-typedef struct dxJoint *dJointID;
-typedef struct dxJointGroup *dJointGroupID;
-
-
-/* error numbers */
-
-enum {
- d_ERR_UNKNOWN = 0, /* unknown error */
- d_ERR_IASSERT, /* internal assertion failed */
- d_ERR_UASSERT, /* user assertion failed */
- d_ERR_LCP /* user assertion failed */
-};
-
-
-/* joint type numbers */
-
-enum {
- dJointTypeNone = 0, /* or "unknown" */
- dJointTypeBall,
- dJointTypeHinge,
- dJointTypeSlider,
- dJointTypeContact,
- dJointTypeUniversal,
- dJointTypeHinge2,
- dJointTypeFixed,
- dJointTypeNull,
- dJointTypeAMotor
-};
-
-
-/* an alternative way of setting joint parameters, using joint parameter
- * structures and member constants. we don't actually do this yet.
- */
-
-/*
-typedef struct dLimot {
- int mode;
- dReal lostop, histop;
- dReal vel, fmax;
- dReal fudge_factor;
- dReal bounce, soft;
- dReal suspension_erp, suspension_cfm;
-} dLimot;
-
-enum {
- dLimotLoStop = 0x0001,
- dLimotHiStop = 0x0002,
- dLimotVel = 0x0004,
- dLimotFMax = 0x0008,
- dLimotFudgeFactor = 0x0010,
- dLimotBounce = 0x0020,
- dLimotSoft = 0x0040
-};
-*/
-
-
-/* standard joint parameter names. why are these here? - because we don't want
- * to include all the joint function definitions in joint.cpp. hmmmm.
- * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument,
- * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and
- * paste between these two.
- */
-
-#define D_ALL_PARAM_NAMES(start) \
- /* parameters for limits and motors */ \
- dParamLoStop = start, \
- dParamHiStop, \
- dParamVel, \
- dParamFMax, \
- dParamFudgeFactor, \
- dParamBounce, \
- dParamCFM, \
- dParamStopERP, \
- dParamStopCFM, \
- /* parameters for suspension */ \
- dParamSuspensionERP, \
- dParamSuspensionCFM,
-
-#define D_ALL_PARAM_NAMES_X(start,x) \
- /* parameters for limits and motors */ \
- dParamLoStop ## x = start, \
- dParamHiStop ## x, \
- dParamVel ## x, \
- dParamFMax ## x, \
- dParamFudgeFactor ## x, \
- dParamBounce ## x, \
- dParamCFM ## x, \
- dParamStopERP ## x, \
- dParamStopCFM ## x, \
- /* parameters for suspension */ \
- dParamSuspensionERP ## x, \
- dParamSuspensionCFM ## x,
-
-enum {
- D_ALL_PARAM_NAMES(0)
- D_ALL_PARAM_NAMES_X(0x100,2)
- D_ALL_PARAM_NAMES_X(0x200,3)
-
- /* add a multiple of this constant to the basic parameter numbers to get
- * the parameters for the second, third etc axes.
- */
- dParamGroup=0x100
-};
-
-
-/* angular motor mode numbers */
-
-enum{
- dAMotorUser = 0,
- dAMotorEuler = 1
-};
-
-
-/* joint force feedback information */
-
-typedef struct dJointFeedback {
- dVector3 f1; // force applied to body 1
- dVector3 t1; // torque applied to body 1
- dVector3 f2; // force applied to body 2
- dVector3 t2; // torque applied to body 2
-} dJointFeedback;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/contact.h b/extern/ode/dist/include/ode/contact.h
deleted file mode 100644
index 6fc66a179c0..00000000000
--- a/extern/ode/dist/include/ode/contact.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_CONTACT_H_
-#define _ODE_CONTACT_H_
-
-#include <ode/common.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-enum {
- dContactMu2 = 0x001,
- dContactFDir1 = 0x002,
- dContactBounce = 0x004,
- dContactSoftERP = 0x008,
- dContactSoftCFM = 0x010,
- dContactMotion1 = 0x020,
- dContactMotion2 = 0x040,
- dContactSlip1 = 0x080,
- dContactSlip2 = 0x100,
-
- dContactApprox0 = 0x0000,
- dContactApprox1_1 = 0x1000,
- dContactApprox1_2 = 0x2000,
- dContactApprox1 = 0x3000
-};
-
-
-typedef struct dSurfaceParameters {
- /* must always be defined */
- int mode;
- dReal mu;
-
- /* only defined if the corresponding flag is set in mode */
- dReal mu2;
- dReal bounce;
- dReal bounce_vel;
- dReal soft_erp;
- dReal soft_cfm;
- dReal motion1,motion2;
- dReal slip1,slip2;
-} dSurfaceParameters;
-
-
-/* contact info set by collision functions */
-
-typedef struct dContactGeom {
- dVector3 pos;
- dVector3 normal;
- dReal depth;
- dGeomID g1,g2;
-} dContactGeom;
-
-
-/* contact info used by contact joint */
-
-typedef struct dContact {
- dSurfaceParameters surface;
- dContactGeom geom;
- dVector3 fdir1;
-} dContact;
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/error.h b/extern/ode/dist/include/ode/error.h
deleted file mode 100644
index 1350bbc8427..00000000000
--- a/extern/ode/dist/include/ode/error.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/* this comes from the `reuse' library. copy any changes back to the source */
-
-#ifndef _ODE_ERROR_H_
-#define _ODE_ERROR_H_
-
-#include <ode/config.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* all user defined error functions have this type. error and debug functions
- * should not return.
- */
-typedef void dMessageFunction (int errnum, const char *msg, va_list ap);
-
-/* set a new error, debug or warning handler. if fn is 0, the default handlers
- * are used.
- */
-void dSetErrorHandler (dMessageFunction *fn);
-void dSetDebugHandler (dMessageFunction *fn);
-void dSetMessageHandler (dMessageFunction *fn);
-
-/* return the current error, debug or warning handler. if the return value is
- * 0, the default handlers are in place.
- */
-dMessageFunction *dGetErrorHandler();
-dMessageFunction *dGetDebugHandler();
-dMessageFunction *dGetMessageHandler();
-
-/* generate a fatal error, debug trap or a message. */
-void dError (int num, const char *msg, ...);
-void dDebug (int num, const char *msg, ...);
-void dMessage (int num, const char *msg, ...);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/geom.h b/extern/ode/dist/include/ode/geom.h
deleted file mode 100644
index 20fc8998ded..00000000000
--- a/extern/ode/dist/include/ode/geom.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_GEOM_H_
-#define _ODE_GEOM_H_
-
-#include <ode/common.h>
-#include <ode/space.h>
-#include <ode/contact.h>
-
-#if defined SHARED_GEOM_H_INCLUDED_FROM_DEFINING_FILE
-#define GLOBAL_SHAREDLIB_SPEC SHAREDLIBEXPORT
-#else
-#define GLOBAL_SHAREDLIB_SPEC SHAREDLIBIMPORT
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* ************************************************************************ */
-/* utility functions */
-
-void dClosestLineSegmentPoints (const dVector3 a1, const dVector3 a2,
- const dVector3 b1, const dVector3 b2,
- dVector3 cp1, dVector3 cp2);
-
-int dBoxTouchesBox (const dVector3 _p1, const dMatrix3 R1,
- const dVector3 side1, const dVector3 _p2,
- const dMatrix3 R2, const dVector3 side2);
-
-void dInfiniteAABB (dGeomID geom, dReal aabb[6]);
-void dCloseODE();
-
-/* ************************************************************************ */
-/* standard classes */
-
-/* class numbers */
-extern GLOBAL_SHAREDLIB_SPEC int dSphereClass;
-extern GLOBAL_SHAREDLIB_SPEC int dBoxClass;
-extern GLOBAL_SHAREDLIB_SPEC int dCCylinderClass;
-extern GLOBAL_SHAREDLIB_SPEC int dPlaneClass;
-extern GLOBAL_SHAREDLIB_SPEC int dGeomGroupClass;
-extern GLOBAL_SHAREDLIB_SPEC int dGeomTransformClass;
-
-/* constructors */
-dGeomID dCreateSphere (dSpaceID space, dReal radius);
-dGeomID dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz);
-dGeomID dCreatePlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d);
-dGeomID dCreateCCylinder (dSpaceID space, dReal radius, dReal length);
-dGeomID dCreateGeomGroup (dSpaceID space);
-
-/* set geometry parameters */
-void dGeomSphereSetRadius (dGeomID sphere, dReal radius);
-void dGeomBoxSetLengths (dGeomID box, dReal lx, dReal ly, dReal lz);
-void dGeomPlaneSetParams (dGeomID plane, dReal a, dReal b, dReal c, dReal d);
-void dGeomCCylinderSetParams (dGeomID ccylinder, dReal radius, dReal length);
-
-/* get geometry parameters */
-int dGeomGetClass (dGeomID);
-dReal dGeomSphereGetRadius (dGeomID sphere);
-void dGeomBoxGetLengths (dGeomID box, dVector3 result);
-void dGeomPlaneGetParams (dGeomID plane, dVector4 result);
-void dGeomCCylinderGetParams (dGeomID ccylinder,
- dReal *radius, dReal *length);
-
-/* general functions */
-void dGeomSetData (dGeomID, void *);
-void *dGeomGetData (dGeomID);
-void dGeomSetBody (dGeomID, dBodyID);
-dBodyID dGeomGetBody (dGeomID);
-void dGeomSetPosition (dGeomID, dReal x, dReal y, dReal z);
-void dGeomSetRotation (dGeomID, const dMatrix3 R);
-const dReal * dGeomGetPosition (dGeomID);
-const dReal * dGeomGetRotation (dGeomID);
-void dGeomDestroy (dGeomID);
-void dGeomGetAABB (dGeomID, dReal aabb[6]);
-dReal *dGeomGetSpaceAABB (dGeomID);
-
-/* ************************************************************************ */
-/* geometry group functions */
-
-void dGeomGroupAdd (dGeomID group, dGeomID x);
-void dGeomGroupRemove (dGeomID group, dGeomID x);
-int dGeomGroupGetNumGeoms (dGeomID group);
-dGeomID dGeomGroupGetGeom (dGeomID group, int i);
-
-/* ************************************************************************ */
-/* transformed geometry functions */
-
-dGeomID dCreateGeomTransform (dSpaceID space);
-void dGeomTransformSetGeom (dGeomID g, dGeomID obj);
-dGeomID dGeomTransformGetGeom (dGeomID g);
-void dGeomTransformSetCleanup (dGeomID g, int mode);
-int dGeomTransformGetCleanup (dGeomID g);
-void dGeomTransformSetInfo (dGeomID g, int mode);
-int dGeomTransformGetInfo (dGeomID g);
-
-/* ************************************************************************ */
-/* general collision */
-
-int dCollide (dGeomID o1, dGeomID o2, int flags, dContactGeom *contact,
- int skip);
-
-/* ************************************************************************ */
-/* custom classes */
-
-typedef void dGetAABBFn (dGeomID, dReal aabb[6]);
-typedef int dColliderFn (dGeomID o1, dGeomID o2,
- int flags, dContactGeom *contact, int skip);
-typedef dColliderFn * dGetColliderFnFn (int num);
-typedef void dGeomDtorFn (dGeomID o);
-typedef int dAABBTestFn (dGeomID o1, dGeomID o2, dReal aabb[6]);
-
-typedef struct dGeomClass {
- int bytes;
- dGetColliderFnFn *collider;
- dGetAABBFn *aabb;
- dAABBTestFn *aabb_test;
- dGeomDtorFn *dtor;
-} dGeomClass;
-
-int dCreateGeomClass (const dGeomClass *classptr);
-void * dGeomGetClassData (dGeomID);
-dGeomID dCreateGeom (int classnum);
-
-/* ************************************************************************ */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/mass.h b/extern/ode/dist/include/ode/mass.h
deleted file mode 100644
index 8e75da0c1eb..00000000000
--- a/extern/ode/dist/include/ode/mass.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_MASS_H_
-#define _ODE_MASS_H_
-
-#include <ode/common.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct dMass;
-typedef struct dMass dMass;
-
-
-void dMassSetZero (dMass *);
-
-void dMassSetParameters (dMass *, dReal themass,
- dReal cgx, dReal cgy, dReal cgz,
- dReal I11, dReal I22, dReal I33,
- dReal I12, dReal I13, dReal I23);
-
-void dMassSetSphere (dMass *, dReal density, dReal radius);
-
-void dMassSetCappedCylinder (dMass *, dReal density, int direction,
- dReal a, dReal b);
-
-void dMassSetBox (dMass *, dReal density,
- dReal lx, dReal ly, dReal lz);
-
-void dMassAdjust (dMass *, dReal newmass);
-
-void dMassTranslate (dMass *, dReal x, dReal y, dReal z);
-
-void dMassRotate (dMass *, const dMatrix3 R);
-
-void dMassAdd (dMass *a, const dMass *b);
-
-
-
-struct dMass {
- dReal mass;
- dVector4 c;
- dMatrix3 I;
-
-#ifdef __cplusplus
- dMass()
- { dMassSetZero (this); }
- void setZero()
- { dMassSetZero (this); }
- void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz,
- dReal I11, dReal I22, dReal I33,
- dReal I12, dReal I13, dReal I23)
- { dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); }
- void setSphere (dReal density, dReal radius)
- { dMassSetSphere (this,density,radius); }
- void setCappedCylinder (dReal density, int direction, dReal a, dReal b)
- { dMassSetCappedCylinder (this,density,direction,a,b); }
- void setBox (dReal density, dReal lx, dReal ly, dReal lz)
- { dMassSetBox (this,density,lx,ly,lz); }
- void adjust (dReal newmass)
- { dMassAdjust (this,newmass); }
- void translate (dReal x, dReal y, dReal z)
- { dMassTranslate (this,x,y,z); }
- void rotate (const dMatrix3 R)
- { dMassRotate (this,R); }
- void add (const dMass *b)
- { dMassAdd (this,b); }
-#endif
-};
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/matrix.h b/extern/ode/dist/include/ode/matrix.h
deleted file mode 100644
index 94d830095cd..00000000000
--- a/extern/ode/dist/include/ode/matrix.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/* optimized and unoptimized vector and matrix functions */
-
-#ifndef _ODE_MATRIX_H_
-#define _ODE_MATRIX_H_
-
-#include <ode/common.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* set a vector/matrix of size n to all zeros, or to a specific value. */
-
-void dSetZero (dReal *a, int n);
-void dSetValue (dReal *a, int n, dReal value);
-
-
-/* get the dot product of two n*1 vectors. if n <= 0 then
- * zero will be returned (in which case a and b need not be valid).
- */
-
-dReal dDot (const dReal *a, const dReal *b, int n);
-
-
-/* get the dot products of (a0,b), (a1,b), etc and return them in outsum.
- * all vectors are n*1. if n <= 0 then zeroes will be returned (in which case
- * the input vectors need not be valid). this function is somewhat faster
- * than calling dDot() for all of the combinations separately.
- */
-
-/* NOT INCLUDED in the library for now.
-void dMultidot2 (const dReal *a0, const dReal *a1,
- const dReal *b, dReal *outsum, int n);
-*/
-
-
-/* matrix multiplication. all matrices are stored in standard row format.
- * the digit refers to the argument that is transposed:
- * 0: A = B * C (sizes: A:p*r B:p*q C:q*r)
- * 1: A = B' * C (sizes: A:p*r B:q*p C:q*r)
- * 2: A = B * C' (sizes: A:p*r B:p*q C:r*q)
- * case 1,2 are equivalent to saying that the operation is A=B*C but
- * B or C are stored in standard column format.
- */
-
-void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
-void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
-void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r);
-
-
-/* do an in-place cholesky decomposition on the lower triangle of the n*n
- * symmetric matrix A (which is stored by rows). the resulting lower triangle
- * will be such that L*L'=A. return 1 on success and 0 on failure (on failure
- * the matrix is not positive definite).
- */
-
-int dFactorCholesky (dReal *A, int n);
-
-
-/* solve for x: L*L'*x = b, and put the result back into x.
- * L is size n*n, b is size n*1. only the lower triangle of L is considered.
- */
-
-void dSolveCholesky (const dReal *L, dReal *b, int n);
-
-
-/* compute the inverse of the n*n positive definite matrix A and put it in
- * Ainv. this is not especially fast. this returns 1 on success (A was
- * positive definite) or 0 on failure (not PD).
- */
-
-int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n);
-
-
-/* check whether an n*n matrix A is positive definite, return 1/0 (yes/no).
- * positive definite means that x'*A*x > 0 for any x. this performs a
- * cholesky decomposition of A. if the decomposition fails then the matrix
- * is not positive definite. A is stored by rows. A is not altered.
- */
-
-int dIsPositiveDefinite (const dReal *A, int n);
-
-
-/* factorize a matrix A into L*D*L', where L is lower triangular with ones on
- * the diagonal, and D is diagonal.
- * A is an n*n matrix stored by rows, with a leading dimension of n rounded
- * up to 4. L is written into the strict lower triangle of A (the ones are not
- * written) and the reciprocal of the diagonal elements of D are written into
- * d.
- */
-void dFactorLDLT (dReal *A, dReal *d, int n, int nskip);
-
-
-/* solve L*x=b, where L is n*n lower triangular with ones on the diagonal,
- * and x,b are n*1. b is overwritten with x.
- * the leading dimension of L is `nskip'.
- */
-void dSolveL1 (const dReal *L, dReal *b, int n, int nskip);
-
-
-/* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal,
- * and x,b are n*1. b is overwritten with x.
- * the leading dimension of L is `nskip'.
- */
-void dSolveL1T (const dReal *L, dReal *b, int n, int nskip);
-
-
-/* in matlab syntax: a(1:n) = a(1:n) .* d(1:n) */
-
-void dVectorScale (dReal *a, const dReal *d, int n);
-
-
-/* given `L', a n*n lower triangular matrix with ones on the diagonal,
- * and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matrix
- * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b.
- * the leading dimension of L is `nskip'.
- */
-
-void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip);
-
-
-/* given an L*D*L' factorization of an n*n matrix A, return the updated
- * factorization L2*D2*L2' of A plus the following "top left" matrix:
- *
- * [ b a' ] <-- b is a[0]
- * [ a 0 ] <-- a is a[1..n-1]
- *
- * - L has size n*n, its leading dimension is nskip. L is lower triangular
- * with ones on the diagonal. only the lower triangle of L is referenced.
- * - d has size n. d contains the reciprocal diagonal elements of D.
- * - a has size n.
- * the result is written into L, except that the left column of L and d[0]
- * are not actually modified. see ldltaddTL.m for further comments.
- */
-void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip);
-
-
-/* given an L*D*L' factorization of a permuted matrix A, produce a new
- * factorization for row and column `r' removed.
- * - A has size n1*n1, its leading dimension in nskip. A is symmetric and
- * positive definite. only the lower triangle of A is referenced.
- * A itself may actually be an array of row pointers.
- * - L has size n2*n2, its leading dimension in nskip. L is lower triangular
- * with ones on the diagonal. only the lower triangle of L is referenced.
- * - d has size n2. d contains the reciprocal diagonal elements of D.
- * - p is a permutation vector. it contains n2 indexes into A. each index
- * must be in the range 0..n1-1.
- * - r is the row/column of L to remove.
- * the new L will be written within the old L, i.e. will have the same leading
- * dimension. the last row and column of L, and the last element of d, are
- * undefined on exit.
- *
- * a fast O(n^2) algorithm is used. see ldltremove.m for further comments.
- */
-void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d,
- int n1, int n2, int r, int nskip);
-
-
-/* given an n*n matrix A (with leading dimension nskip), remove the r'th row
- * and column by moving elements. the new matrix will have the same leading
- * dimension. the last row and column of A are untouched on exit.
- */
-void dRemoveRowCol (dReal *A, int n, int nskip, int r);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/memory.h b/extern/ode/dist/include/ode/memory.h
deleted file mode 100644
index 7ea668e4d39..00000000000
--- a/extern/ode/dist/include/ode/memory.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/* this comes from the `reuse' library. copy any changes back to the source */
-
-#ifndef _ODE_MEMORY_H_
-#define _ODE_MEMORY_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* function types to allocate and free memory */
-typedef void * dAllocFunction (int size);
-typedef void * dReallocFunction (void *ptr, int oldsize, int newsize);
-typedef void dFreeFunction (void *ptr, int size);
-
-/* set new memory management functions. if fn is 0, the default handlers are
- * used. */
-void dSetAllocHandler (dAllocFunction *fn);
-void dSetReallocHandler (dReallocFunction *fn);
-void dSetFreeHandler (dFreeFunction *fn);
-
-/* get current memory management functions */
-dAllocFunction *dGetAllocHandler ();
-dReallocFunction *dGetReallocHandler ();
-dFreeFunction *dGetFreeHandler ();
-
-/* allocate and free memory. */
-void * dAlloc (int size);
-void * dRealloc (void *ptr, int oldsize, int newsize);
-void dFree (void *ptr, int size);
-
-/* when alloc debugging is turned on, this indicates that the given block of
- * alloc()ed memory should not be reported as "still in use" when the program
- * exits.
- */
-void dAllocDontReport (void *ptr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/misc.h b/extern/ode/dist/include/ode/misc.h
deleted file mode 100644
index 241ad71ed9e..00000000000
--- a/extern/ode/dist/include/ode/misc.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/* miscellaneous math functions. these are mostly useful for testing */
-
-#ifndef _ODE_MISC_H_
-#define _ODE_MISC_H_
-
-#include <ode/common.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* return 1 if the random number generator is working. */
-int dTestRand();
-
-/* return next 32 bit random number. this uses a not-very-random linear
- * congruential method.
- */
-unsigned long dRand();
-
-/* get and set the current random number seed. */
-unsigned long dRandGetSeed();
-void dRandSetSeed (unsigned long s);
-
-/* return a random integer between 0..n-1. the distribution will get worse
- * as n approaches 2^32.
- */
-int dRandInt (int n);
-
-/* return a random real number between 0..1 */
-dReal dRandReal();
-
-/* print out a matrix */
-#ifdef __cplusplus
-void dPrintMatrix (dReal *A, int n, int m, char *fmt = "%10.4f ",
- FILE *f=stdout);
-#else
-void dPrintMatrix (dReal *A, int n, int m, char *fmt, FILE *f);
-#endif
-
-/* make a random vector with entries between +/- range. A has n elements. */
-void dMakeRandomVector (dReal *A, int n, dReal range);
-
-/* make a random matrix with entries between +/- range. A has size n*m. */
-void dMakeRandomMatrix (dReal *A, int n, int m, dReal range);
-
-/* clear the upper triangle of a square matrix */
-void dClearUpperTriangle (dReal *A, int n);
-
-/* return the maximum element difference between the two n*m matrices */
-dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m);
-
-/* return the maximum element difference between the lower triangle of two
- * n*n matrices */
-dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/objects.h b/extern/ode/dist/include/ode/objects.h
deleted file mode 100644
index 606051ead34..00000000000
--- a/extern/ode/dist/include/ode/objects.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_OBJECTS_H_
-#define _ODE_OBJECTS_H_
-
-#include <ode/common.h>
-#include <ode/mass.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* world */
-
-dWorldID dWorldCreate();
-void dWorldDestroy (dWorldID);
-
-void dWorldSetGravity (dWorldID, dReal x, dReal y, dReal z);
-void dWorldGetGravity (dWorldID, dVector3 gravity);
-void dWorldSetERP (dWorldID, dReal erp);
-dReal dWorldGetERP (dWorldID);
-void dWorldSetCFM (dWorldID, dReal cfm);
-dReal dWorldGetCFM (dWorldID);
-void dWorldStep (dWorldID, dReal stepsize);
-void dWorldImpulseToForce (dWorldID, dReal stepsize,
- dReal ix, dReal iy, dReal iz, dVector3 force);
-
-/* bodies */
-
-dBodyID dBodyCreate (dWorldID);
-void dBodyDestroy (dBodyID);
-
-void dBodySetData (dBodyID, void *data);
-void *dBodyGetData (dBodyID);
-
-void dBodySetPosition (dBodyID, dReal x, dReal y, dReal z);
-void dBodySetRotation (dBodyID, const dMatrix3 R);
-void dBodySetQuaternion (dBodyID, const dQuaternion q);
-void dBodySetLinearVel (dBodyID, dReal x, dReal y, dReal z);
-void dBodySetAngularVel (dBodyID, dReal x, dReal y, dReal z);
-const dReal * dBodyGetPosition (dBodyID);
-const dReal * dBodyGetRotation (dBodyID); /* ptr to 4x3 rot matrix */
-const dReal * dBodyGetQuaternion (dBodyID);
-const dReal * dBodyGetLinearVel (dBodyID);
-const dReal * dBodyGetAngularVel (dBodyID);
-
-void dBodySetMass (dBodyID, const dMass *mass);
-void dBodyGetMass (dBodyID, dMass *mass);
-
-void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz);
-void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz);
-void dBodyAddRelForce (dBodyID, dReal fx, dReal fy, dReal fz);
-void dBodyAddRelTorque (dBodyID, dReal fx, dReal fy, dReal fz);
-void dBodyAddForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz);
-void dBodyAddForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz);
-void dBodyAddRelForceAtPos (dBodyID, dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz);
-void dBodyAddRelForceAtRelPos (dBodyID, dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz);
-
-const dReal * dBodyGetForce (dBodyID);
-const dReal * dBodyGetTorque (dBodyID);
-void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z);
-void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z);
-
-void dBodyGetRelPointPos (dBodyID, dReal px, dReal py, dReal pz,
- dVector3 result);
-void dBodyGetRelPointVel (dBodyID, dReal px, dReal py, dReal pz,
- dVector3 result);
-void dBodyGetPointVel (dBodyID, dReal px, dReal py, dReal pz,
- dVector3 result);
-void dBodyGetPosRelPoint (dBodyID, dReal px, dReal py, dReal pz,
- dVector3 result);
-void dBodyVectorToWorld (dBodyID, dReal px, dReal py, dReal pz,
- dVector3 result);
-void dBodyVectorFromWorld (dBodyID, dReal px, dReal py, dReal pz,
- dVector3 result);
-
-void dBodySetFiniteRotationMode (dBodyID, int mode);
-void dBodySetFiniteRotationAxis (dBodyID, dReal x, dReal y, dReal z);
-
-int dBodyGetFiniteRotationMode (dBodyID);
-void dBodyGetFiniteRotationAxis (dBodyID, dVector3 result);
-
-int dBodyGetNumJoints (dBodyID b);
-dJointID dBodyGetJoint (dBodyID, int index);
-
-void dBodyEnable (dBodyID);
-void dBodyDisable (dBodyID);
-int dBodyIsEnabled (dBodyID);
-
-void dBodySetGravityMode (dBodyID b, int mode);
-int dBodyGetGravityMode (dBodyID b);
-
-
-/* joints */
-
-dJointID dJointCreateBall (dWorldID, dJointGroupID);
-dJointID dJointCreateHinge (dWorldID, dJointGroupID);
-dJointID dJointCreateSlider (dWorldID, dJointGroupID);
-dJointID dJointCreateContact (dWorldID, dJointGroupID, const dContact *);
-dJointID dJointCreateHinge2 (dWorldID, dJointGroupID);
-dJointID dJointCreateUniversal (dWorldID, dJointGroupID);
-dJointID dJointCreateFixed (dWorldID, dJointGroupID);
-dJointID dJointCreateNull (dWorldID, dJointGroupID);
-dJointID dJointCreateAMotor (dWorldID, dJointGroupID);
-
-void dJointDestroy (dJointID);
-
-dJointGroupID dJointGroupCreate (int max_size);
-void dJointGroupDestroy (dJointGroupID);
-void dJointGroupEmpty (dJointGroupID);
-
-void dJointAttach (dJointID, dBodyID body1, dBodyID body2);
-void dJointSetData (dJointID, void *data);
-void *dJointGetData (dJointID);
-int dJointGetType (dJointID);
-dBodyID dJointGetBody (dJointID, int index);
-
-void dJointSetFeedback (dJointID, dJointFeedback *);
-dJointFeedback *dJointGetFeedback (dJointID);
-
-void dJointSetBallAnchor (dJointID, dReal x, dReal y, dReal z);
-void dJointSetHingeAnchor (dJointID, dReal x, dReal y, dReal z);
-void dJointSetHingeAxis (dJointID, dReal x, dReal y, dReal z);
-void dJointSetHingeParam (dJointID, int parameter, dReal value);
-void dJointSetSliderAxis (dJointID, dReal x, dReal y, dReal z);
-void dJointSetSliderParam (dJointID, int parameter, dReal value);
-void dJointSetHinge2Anchor (dJointID, dReal x, dReal y, dReal z);
-void dJointSetHinge2Axis1 (dJointID, dReal x, dReal y, dReal z);
-void dJointSetHinge2Axis2 (dJointID, dReal x, dReal y, dReal z);
-void dJointSetHinge2Param (dJointID, int parameter, dReal value);
-void dJointSetUniversalAnchor (dJointID, dReal x, dReal y, dReal z);
-void dJointSetUniversalAxis1 (dJointID, dReal x, dReal y, dReal z);
-void dJointSetUniversalAxis2 (dJointID, dReal x, dReal y, dReal z);
-void dJointSetFixed (dJointID);
-void dJointSetAMotorNumAxes (dJointID, int num);
-void dJointSetAMotorAxis (dJointID, int anum, int rel,
- dReal x, dReal y, dReal z);
-void dJointSetAMotorAngle (dJointID, int anum, dReal angle);
-void dJointSetAMotorParam (dJointID, int parameter, dReal value);
-void dJointSetAMotorMode (dJointID, int mode);
-
-void dJointGetBallAnchor (dJointID, dVector3 result);
-void dJointGetHingeAnchor (dJointID, dVector3 result);
-void dJointGetHingeAxis (dJointID, dVector3 result);
-dReal dJointGetHingeParam (dJointID, int parameter);
-dReal dJointGetHingeAngle (dJointID);
-dReal dJointGetHingeAngleRate (dJointID);
-dReal dJointGetSliderPosition (dJointID);
-dReal dJointGetSliderPositionRate (dJointID);
-void dJointGetSliderAxis (dJointID, dVector3 result);
-dReal dJointGetSliderParam (dJointID, int parameter);
-void dJointGetHinge2Anchor (dJointID, dVector3 result);
-void dJointGetHinge2Axis1 (dJointID, dVector3 result);
-void dJointGetHinge2Axis2 (dJointID, dVector3 result);
-dReal dJointGetHinge2Param (dJointID, int parameter);
-dReal dJointGetHinge2Angle1 (dJointID);
-dReal dJointGetHinge2Angle1Rate (dJointID);
-dReal dJointGetHinge2Angle2Rate (dJointID);
-void dJointGetUniversalAnchor (dJointID, dVector3 result);
-void dJointGetUniversalAxis1 (dJointID, dVector3 result);
-void dJointGetUniversalAxis2 (dJointID, dVector3 result);
-int dJointGetAMotorNumAxes (dJointID);
-void dJointGetAMotorAxis (dJointID, int anum, dVector3 result);
-int dJointGetAMotorAxisRel (dJointID, int anum);
-dReal dJointGetAMotorAngle (dJointID, int anum);
-dReal dJointGetAMotorAngleRate (dJointID, int anum);
-dReal dJointGetAMotorParam (dJointID, int parameter);
-int dJointGetAMotorMode (dJointID);
-
-int dAreConnected (dBodyID, dBodyID);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/ode.h b/extern/ode/dist/include/ode/ode.h
deleted file mode 100644
index da7f2e1a0e7..00000000000
--- a/extern/ode/dist/include/ode/ode.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_ODE_H_
-#define _ODE_ODE_H_
-
-/* include *everything* here */
-
-#include <ode/config.h>
-#include <ode/common.h>
-#include <ode/contact.h>
-#include <ode/error.h>
-#include <ode/memory.h>
-#include <ode/odemath.h>
-#include <ode/matrix.h>
-#include <ode/timer.h>
-#include <ode/rotation.h>
-#include <ode/mass.h>
-#include <ode/space.h>
-#include <ode/geom.h>
-#include <ode/misc.h>
-#include <ode/objects.h>
-#include <ode/odecpp.h>
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/odecpp.h b/extern/ode/dist/include/ode/odecpp.h
deleted file mode 100644
index 35712236d1d..00000000000
--- a/extern/ode/dist/include/ode/odecpp.h
+++ /dev/null
@@ -1,797 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-// C++ interface for everything
-
-
-#ifndef _ODE_ODECPP_H_
-#define _ODE_ODECPP_H_
-#ifdef __cplusplus
-
-#include <ode/error.h>
-
-
-class dWorld {
- dWorldID _id;
-
- // intentionally undefined, don't use these
- dWorld (const dWorld &);
- void operator= (const dWorld &);
-
-public:
- dWorld()
- { _id = dWorldCreate(); }
- ~dWorld()
- { dWorldDestroy (_id); }
-
- dWorldID id() const
- { return _id; }
- operator dWorldID() const
- { return _id; }
-
- void setGravity (dReal x, dReal y, dReal z)
- { dWorldSetGravity (_id,x,y,z); }
- void getGravity (dVector3 g) const
- { dWorldGetGravity (_id,g); }
-
- void setERP (dReal erp)
- { dWorldSetERP(_id, erp); }
- dReal getERP() const
- { return dWorldGetERP(_id); }
-
- void setCFM (dReal cfm)
- { dWorldSetCFM(_id, cfm); }
- dReal getCFM() const
- { return dWorldGetCFM(_id); }
-
- void step (dReal stepsize)
- { dWorldStep (_id,stepsize); }
-
- void impulseToForce (dReal stepsize, dReal ix, dReal iy, dReal iz,
- dVector3 force)
- { dWorldImpulseToForce (_id,stepsize,ix,iy,iz,force); }
-};
-
-
-class dBody {
- dBodyID _id;
-
- // intentionally undefined, don't use these
- dBody (const dBody &);
- void operator= (const dBody &);
-
-public:
- dBody()
- { _id = 0; }
- dBody (dWorldID world)
- { _id = dBodyCreate (world); }
- ~dBody()
- { if (_id) dBodyDestroy (_id); }
-
- void create (dWorldID world) {
- if (_id) dBodyDestroy (_id);
- _id = dBodyCreate (world);
- }
-
- dBodyID id() const
- { return _id; }
- operator dBodyID() const
- { return _id; }
-
- void setData (void *data)
- { dBodySetData (_id,data); }
- void *getData() const
- { return dBodyGetData (_id); }
-
- void setPosition (dReal x, dReal y, dReal z)
- { dBodySetPosition (_id,x,y,z); }
- void setRotation (const dMatrix3 R)
- { dBodySetRotation (_id,R); }
- void setQuaternion (const dQuaternion q)
- { dBodySetQuaternion (_id,q); }
- void setLinearVel (dReal x, dReal y, dReal z)
- { dBodySetLinearVel (_id,x,y,z); }
- void setAngularVel (dReal x, dReal y, dReal z)
- { dBodySetAngularVel (_id,x,y,z); }
-
- const dReal * getPosition() const
- { return dBodyGetPosition (_id); }
- const dReal * getRotation() const
- { return dBodyGetRotation (_id); }
- const dReal * getQuaternion() const
- { return dBodyGetQuaternion (_id); }
- const dReal * getLinearVel() const
- { return dBodyGetLinearVel (_id); }
- const dReal * getAngularVel() const
- { return dBodyGetAngularVel (_id); }
-
- void setMass (const dMass *mass)
- { dBodySetMass (_id,mass); }
- void getMass (dMass *mass) const
- { dBodyGetMass (_id,mass); }
-
- void addForce (dReal fx, dReal fy, dReal fz)
- { dBodyAddForce (_id, fx, fy, fz); }
- void addTorque (dReal fx, dReal fy, dReal fz)
- { dBodyAddTorque (_id, fx, fy, fz); }
- void addRelForce (dReal fx, dReal fy, dReal fz)
- { dBodyAddRelForce (_id, fx, fy, fz); }
- void addRelTorque (dReal fx, dReal fy, dReal fz)
- { dBodyAddRelTorque (_id, fx, fy, fz); }
- void addForceAtPos (dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
- { dBodyAddForceAtPos (_id, fx, fy, fz, px, py, pz); }
- void addForceAtRelPos (dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
- { dBodyAddForceAtRelPos (_id, fx, fy, fz, px, py, pz); }
- void addRelForceAtPos (dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
- { dBodyAddRelForceAtPos (_id, fx, fy, fz, px, py, pz); }
- void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
- { dBodyAddRelForceAtRelPos (_id, fx, fy, fz, px, py, pz); }
-
- const dReal * getForce() const
- { return dBodyGetForce(_id); }
- const dReal * getTorque() const
- { return dBodyGetTorque(_id); }
- void setForce (dReal x, dReal y, dReal z)
- { dBodySetForce (_id,x,y,z); }
- void setTorque (dReal x, dReal y, dReal z)
- { dBodySetTorque (_id,x,y,z); }
-
- void enable()
- { dBodyEnable (_id); }
- void disable()
- { dBodyDisable (_id); }
- int isEnabled() const
- { return dBodyIsEnabled (_id); }
-
- void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const
- { dBodyGetRelPointPos (_id, px, py, pz, result); }
- void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result) const
- { dBodyGetRelPointVel (_id, px, py, pz, result); }
- void getPointVel (dReal px, dReal py, dReal pz, dVector3 result) const
- { dBodyGetPointVel (_id,px,py,pz,result); }
- void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const
- { dBodyGetPosRelPoint (_id,px,py,pz,result); }
- void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const
- { dBodyVectorToWorld (_id,px,py,pz,result); }
- void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const
- { dBodyVectorFromWorld (_id,px,py,pz,result); }
-
- void setFiniteRotationMode (int mode)
- { dBodySetFiniteRotationMode (_id, mode); }
- void setFiniteRotationAxis (dReal x, dReal y, dReal z)
- { dBodySetFiniteRotationAxis (_id, x, y, z); }
-
- int getFiniteRotationMode() const
- { return dBodyGetFiniteRotationMode (_id); }
- void getFiniteRotationAxis (dVector3 result) const
- { dBodyGetFiniteRotationAxis (_id, result); }
-
- int getNumJoints() const
- { return dBodyGetNumJoints (_id); }
- dJointID getJoint (int index) const
- { return dBodyGetJoint (_id, index); }
-
- void setGravityMode (int mode)
- { dBodySetGravityMode (_id,mode); }
- int getGravityMode() const
- { return dBodyGetGravityMode (_id); }
-
- int isConnectedTo (dBodyID body) const
- { return dAreConnected (_id, body); }
-};
-
-
-class dJointGroup {
- dJointGroupID _id;
-
- // intentionally undefined, don't use these
- dJointGroup (const dJointGroup &);
- void operator= (const dJointGroup &);
-
-public:
- dJointGroup (int dummy_arg=0)
- { _id = dJointGroupCreate (0); }
- ~dJointGroup()
- { dJointGroupDestroy (_id); }
- void create (int dummy_arg=0) {
- if (_id) dJointGroupDestroy (_id);
- _id = dJointGroupCreate (0);
- }
-
- dJointGroupID id() const
- { return _id; }
- operator dJointGroupID() const
- { return _id; }
-
- void empty()
- { dJointGroupEmpty (_id); }
-};
-
-
-class dJoint {
-private:
- // intentionally undefined, don't use these
- dJoint (const dJoint &) ;
- void operator= (const dJoint &);
-
-protected:
- dJointID _id;
-
-public:
- dJoint()
- { _id = 0; }
- ~dJoint()
- { if (_id) dJointDestroy (_id); }
-
- dJointID id() const
- { return _id; }
- operator dJointID() const
- { return _id; }
-
- void attach (dBodyID body1, dBodyID body2)
- { dJointAttach (_id, body1, body2); }
-
- void setData (void *data)
- { dJointSetData (_id, data); }
- void *getData (void *data) const
- { return dJointGetData (_id); }
-
- int getType() const
- { return dJointGetType (_id); }
-
- dBodyID getBody (int index) const
- { return dJointGetBody (_id, index); }
-};
-
-
-class dBallJoint : public dJoint {
-private:
- // intentionally undefined, don't use these
- dBallJoint (const dBallJoint &);
- void operator= (const dBallJoint &);
-
-public:
- dBallJoint() { }
- dBallJoint (dWorldID world, dJointGroupID group=0)
- { _id = dJointCreateBall (world, group); }
-
- void create (dWorldID world, dJointGroupID group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateBall (world, group);
- }
-
- void setAnchor (dReal x, dReal y, dReal z)
- { dJointSetBallAnchor (_id, x, y, z); }
- void getAnchor (dVector3 result) const
- { dJointGetBallAnchor (_id, result); }
-} ;
-
-
-class dHingeJoint : public dJoint {
- // intentionally undefined, don't use these
- dHingeJoint (const dHingeJoint &);
- void operator = (const dHingeJoint &);
-
-public:
- dHingeJoint() { }
- dHingeJoint (dWorldID world, dJointGroupID group=0)
- { _id = dJointCreateHinge (world, group); }
-
- void create (dWorldID world, dJointGroupID group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateHinge (world, group);
- }
-
- void setAnchor (dReal x, dReal y, dReal z)
- { dJointSetHingeAnchor (_id, x, y, z); }
- void getAnchor (dVector3 result) const
- { dJointGetHingeAnchor (_id, result); }
-
- void setAxis (dReal x, dReal y, dReal z)
- { dJointSetHingeAxis (_id, x, y, z); }
- void getAxis (dVector3 result) const
- { dJointGetHingeAxis (_id, result); }
-
- dReal getAngle() const
- { return dJointGetHingeAngle (_id); }
- dReal getAngleRate() const
- { return dJointGetHingeAngleRate (_id); }
-
- void setParam (int parameter, dReal value)
- { dJointSetHingeParam (_id, parameter, value); }
- dReal getParam (int parameter) const
- { return dJointGetHingeParam (_id, parameter); }
-};
-
-
-class dSliderJoint : public dJoint {
- // intentionally undefined, don't use these
- dSliderJoint (const dSliderJoint &);
- void operator = (const dSliderJoint &);
-
-public:
- dSliderJoint() { }
- dSliderJoint (dWorldID world, dJointGroupID group=0)
- { _id = dJointCreateSlider (world, group); }
-
- void create (dWorldID world, dJointGroupID group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateSlider (world, group);
- }
-
- void setAxis (dReal x, dReal y, dReal z)
- { dJointSetSliderAxis (_id, x, y, z); }
- void getAxis (dVector3 result) const
- { dJointGetSliderAxis (_id, result); }
-
- dReal getPosition() const
- { return dJointGetSliderPosition (_id); }
- dReal getPositionRate() const
- { return dJointGetSliderPositionRate (_id); }
-
- void setParam (int parameter, dReal value)
- { dJointSetSliderParam (_id, parameter, value); }
- dReal getParam (int parameter) const
- { return dJointGetSliderParam (_id, parameter); }
-};
-
-
-class dUniversalJoint : public dJoint {
- // intentionally undefined, don't use these
- dUniversalJoint (const dUniversalJoint &);
- void operator = (const dUniversalJoint &);
-
-public:
- dUniversalJoint() { }
- dUniversalJoint (dWorldID world, dJointGroupID group=0)
- { _id = dJointCreateUniversal (world, group); }
-
- void create (dWorldID world, dJointGroupID group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateUniversal (world, group);
- }
-
- void setAnchor (dReal x, dReal y, dReal z)
- { dJointSetUniversalAnchor (_id, x, y, z); }
- void setAxis1 (dReal x, dReal y, dReal z)
- { dJointSetUniversalAxis1 (_id, x, y, z); }
- void setAxis2 (dReal x, dReal y, dReal z)
- { dJointSetUniversalAxis2 (_id, x, y, z); }
-
- void getAnchor (dVector3 result) const
- { dJointGetUniversalAnchor (_id, result); }
- void getAxis1 (dVector3 result) const
- { dJointGetUniversalAxis1 (_id, result); }
- void getAxis2 (dVector3 result) const
- { dJointGetUniversalAxis2 (_id, result); }
-};
-
-
-class dHinge2Joint : public dJoint {
- // intentionally undefined, don't use these
- dHinge2Joint (const dHinge2Joint &);
- void operator = (const dHinge2Joint &);
-
-public:
- dHinge2Joint() { }
- dHinge2Joint (dWorldID world, dJointGroupID group=0)
- { _id = dJointCreateHinge2 (world, group); }
-
- void create (dWorldID world, dJointGroupID group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateHinge2 (world, group);
- }
-
- void setAnchor (dReal x, dReal y, dReal z)
- { dJointSetHinge2Anchor (_id, x, y, z); }
- void setAxis1 (dReal x, dReal y, dReal z)
- { dJointSetHinge2Axis1 (_id, x, y, z); }
- void setAxis2 (dReal x, dReal y, dReal z)
- { dJointSetHinge2Axis2 (_id, x, y, z); }
-
- void getAnchor (dVector3 result) const
- { dJointGetHinge2Anchor (_id, result); }
- void getAxis1 (dVector3 result) const
- { dJointGetHinge2Axis1 (_id, result); }
- void getAxis2 (dVector3 result) const
- { dJointGetHinge2Axis2 (_id, result); }
-
- dReal getAngle1() const
- { return dJointGetHinge2Angle1 (_id); }
- dReal getAngle1Rate() const
- { return dJointGetHinge2Angle1Rate (_id); }
- dReal getAngle2Rate() const
- { return dJointGetHinge2Angle2Rate (_id); }
-
- void setParam (int parameter, dReal value)
- { dJointSetHinge2Param (_id, parameter, value); }
- dReal getParam (int parameter) const
- { return dJointGetHinge2Param (_id, parameter); }
-};
-
-
-class dFixedJoint : public dJoint {
- // intentionally undefined, don't use these
- dFixedJoint (const dFixedJoint &);
- void operator = (const dFixedJoint &);
-
-public:
- dFixedJoint() { }
- dFixedJoint (dWorldID world, dJointGroupID group=0)
- { _id = dJointCreateFixed (world, group); }
-
- void create (dWorldID world, dJointGroupID group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateFixed (world, group);
- }
-
- void set()
- { dJointSetFixed (_id); }
-};
-
-
-class dContactJoint : public dJoint {
- // intentionally undefined, don't use these
- dContactJoint (const dContactJoint &);
- void operator = (const dContactJoint &);
-
-public:
- dContactJoint() { }
- dContactJoint (dWorldID world, dJointGroupID group, dContact *contact)
- { _id = dJointCreateContact (world, group, contact); }
-
- void create (dWorldID world, dJointGroupID group, dContact *contact) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateContact (world, group, contact);
- }
-};
-
-
-class dNullJoint : public dJoint {
- // intentionally undefined, don't use these
- dNullJoint (const dNullJoint &);
- void operator = (const dNullJoint &);
-
-public:
- dNullJoint() { }
- dNullJoint (dWorldID world, dJointGroupID group=0)
- { _id = dJointCreateNull (world, group); }
-
- void create (dWorldID world, dJointGroupID group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateNull (world, group);
- }
-};
-
-
-class dAMotorJoint : public dJoint {
- // intentionally undefined, don't use these
- dAMotorJoint (const dAMotorJoint &);
- void operator = (const dAMotorJoint &);
-
-public:
- dAMotorJoint() { }
- dAMotorJoint (dWorldID world, dJointGroupID group=0)
- { _id = dJointCreateAMotor (world, group); }
-
- void create (dWorldID world, dJointGroupID group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateAMotor (world, group);
- }
-
- void setMode (int mode)
- { dJointSetAMotorMode (_id, mode); }
- int getMode() const
- { return dJointGetAMotorMode (_id); }
-
- void setNumAxes (int num)
- { dJointSetAMotorNumAxes (_id, num); }
- int getNumAxes() const
- { return dJointGetAMotorNumAxes (_id); }
-
- void setAxis (int anum, int rel, dReal x, dReal y, dReal z)
- { dJointSetAMotorAxis (_id, anum, rel, x, y, z); }
- void getAxis (int anum, dVector3 result) const
- { dJointGetAMotorAxis (_id, anum, result); }
- int getAxisRel (int anum) const
- { return dJointGetAMotorAxisRel (_id, anum); }
-
- void setAngle (int anum, dReal angle)
- { dJointSetAMotorAngle (_id, anum, angle); }
- dReal getAngle (int anum) const
- { return dJointGetAMotorAngle (_id, anum); }
- dReal getAngleRate (int anum)
- { return dJointGetAMotorAngleRate (_id,anum); }
-
- void setParam (int parameter, dReal value)
- { dJointSetAMotorParam (_id, parameter, value); }
- dReal getParam (int parameter) const
- { return dJointGetAMotorParam (_id, parameter); }
-};
-
-
-class dGeom {
- // intentionally undefined, don't use these
- dGeom (dGeom &);
- void operator= (dGeom &);
-
-protected:
- dGeomID _id;
-
-public:
- dGeom()
- { _id = 0; }
- ~dGeom()
- { if (_id) dGeomDestroy (_id); }
-
- dGeomID id() const
- { return _id; }
- operator dGeomID() const
- { return _id; }
-
- void destroy() {
- if (_id) dGeomDestroy (_id);
- _id = 0;
- }
-
- int getClass() const
- { return dGeomGetClass (_id); }
-
- void setData (void *data)
- { dGeomSetData (_id,data); }
- void *getData() const
- { return dGeomGetData (_id); }
-
- void setBody (dBodyID b)
- { dGeomSetBody (_id,b); }
- dBodyID getBody() const
- { return dGeomGetBody (_id); }
-
- void setPosition (dReal x, dReal y, dReal z)
- { dGeomSetPosition (_id,x,y,z); }
- const dReal * getPosition() const
- { return dGeomGetPosition (_id); }
-
- void setRotation (const dMatrix3 R)
- { dGeomSetRotation (_id,R); }
- const dReal * getRotation() const
- { return dGeomGetRotation (_id); }
-
- void getAABB (dReal aabb[6]) const
- { dGeomGetAABB (_id, aabb); }
- const dReal *getSpaceAABB() const
- { return dGeomGetSpaceAABB (_id); }
-};
-
-
-class dSpace {
- // intentionally undefined, don't use these
- dSpace (dSpace &);
- void operator= (dSpace &);
-
-protected:
- dSpaceID _id;
-
- // the default constructor is protected so that you
- // can't instance this class. you must instance one
- // of its subclasses instead.
- dSpace () { _id = 0; }
-
-public:
- ~dSpace()
- { dSpaceDestroy (_id); }
-
- dSpaceID id() const
- { return _id; }
- operator dSpaceID() const
- { return _id; }
-
- void add (dGeomID x)
- { dSpaceAdd (_id, x); }
- void remove (dGeomID x)
- { dSpaceRemove (_id, x); }
- int query (dGeomID x)
- { return dSpaceQuery (_id,x); }
-
- void collide (void *data, dNearCallback *callback)
- { dSpaceCollide (_id,data,callback); }
-};
-
-
-class dSimpleSpace : public dSpace {
- // intentionally undefined, don't use these
- dSimpleSpace (dSimpleSpace &);
- void operator= (dSimpleSpace &);
-
-public:
- dSimpleSpace ()
- { _id = dSimpleSpaceCreate(); }
-};
-
-
-class dHashSpace : public dSpace {
- // intentionally undefined, don't use these
- dHashSpace (dHashSpace &);
- void operator= (dHashSpace &);
-
-public:
- dHashSpace ()
- { _id = dHashSpaceCreate(); }
- void setLevels (int minlevel, int maxlevel)
- { dHashSpaceSetLevels (_id,minlevel,maxlevel); }
-};
-
-
-class dSphere : public dGeom {
- // intentionally undefined, don't use these
- dSphere (dSphere &);
- void operator= (dSphere &);
-
-public:
- dSphere () { }
- dSphere (dSpaceID space, dReal radius)
- { _id = dCreateSphere (space, radius); }
-
- void create (dSpaceID space, dReal radius) {
- if (_id) dGeomDestroy (_id);
- _id = dCreateSphere (space, radius);
- }
-
- void setRadius (dReal radius)
- { dGeomSphereSetRadius (_id, radius); }
- dReal getRadius() const
- { return dGeomSphereGetRadius (_id); }
-};
-
-
-class dBox : public dGeom {
- // intentionally undefined, don't use these
- dBox (dBox &);
- void operator= (dBox &);
-
-public:
- dBox () { }
- dBox (dSpaceID space, dReal lx, dReal ly, dReal lz)
- { _id = dCreateBox (space,lx,ly,lz); }
-
- void create (dSpaceID space, dReal lx, dReal ly, dReal lz) {
- if (_id) dGeomDestroy (_id);
- _id = dCreateBox (space,lx,ly,lz);
- }
-
- void setLengths (dReal lx, dReal ly, dReal lz)
- { dGeomBoxSetLengths (_id, lx, ly, lz); }
- void getLengths (dVector3 result) const
- { dGeomBoxGetLengths (_id,result); }
-};
-
-
-class dPlane : public dGeom {
- // intentionally undefined, don't use these
- dPlane (dPlane &);
- void operator= (dPlane &);
-
-public:
- dPlane() { }
- dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d)
- { _id = dCreatePlane (space,a,b,c,d); }
-
- void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) {
- if (_id) dGeomDestroy (_id);
- _id = dCreatePlane (space,a,b,c,d);
- }
-
- void setParams (dReal a, dReal b, dReal c, dReal d)
- { dGeomPlaneSetParams (_id, a, b, c, d); }
- void getParams (dVector4 result) const
- { dGeomPlaneGetParams (_id,result); }
-};
-
-
-class dCCylinder : public dGeom {
- // intentionally undefined, don't use these
- dCCylinder (dCCylinder &);
- void operator= (dCCylinder &);
-
-public:
- dCCylinder() { }
- dCCylinder (dSpaceID space, dReal radius, dReal length)
- { _id = dCreateCCylinder (space,radius,length); }
-
- void create (dSpaceID space, dReal radius, dReal length) {
- if (_id) dGeomDestroy (_id);
- _id = dCreateCCylinder (space,radius,length);
- }
-
- void setParams (dReal radius, dReal length)
- { dGeomCCylinderSetParams (_id, radius, length); }
- void getParams (dReal *radius, dReal *length) const
- { dGeomCCylinderGetParams (_id,radius,length); }
-};
-
-
-class dGeomGroup : public dGeom {
- // intentionally undefined, don't use these
- dGeomGroup (dGeomGroup &);
- void operator= (dGeomGroup &);
-
-public:
- dGeomGroup() { }
- dGeomGroup (dSpaceID space)
- { _id = dCreateGeomGroup (space); }
-
- void create (dSpaceID space=0) {
- if (_id) dGeomDestroy (_id);
- _id = dCreateGeomGroup (space);
- }
-
- void add (dGeomID x)
- { dGeomGroupAdd (_id, x); }
- void remove (dGeomID x)
- { dGeomGroupRemove (_id, x); }
-
- int getNumGeoms() const
- { return dGeomGroupGetNumGeoms (_id); }
- dGeomID getGeom (int i) const
- { return dGeomGroupGetGeom (_id, i); }
-};
-
-
-class dGeomTransform : public dGeom {
- // intentionally undefined, don't use these
- dGeomTransform (dGeomTransform &);
- void operator= (dGeomTransform &);
-
-public:
- dGeomTransform() { }
- dGeomTransform (dSpaceID space)
- { _id = dCreateGeomTransform (space); }
-
- void create (dSpaceID space=0) {
- if (_id) dGeomDestroy (_id);
- _id = dCreateGeomTransform (space);
- }
-
- void setGeom (dGeomID geom)
- { dGeomTransformSetGeom (_id, geom); }
- dGeomID getGeom() const
- { return dGeomTransformGetGeom (_id); }
-
- void setCleanup (int mode)
- { dGeomTransformSetCleanup (_id,mode); }
- int getCleanup (dGeomID g)
- { return dGeomTransformGetCleanup (_id); }
-
- void setInfo (int mode)
- { dGeomTransformSetInfo (_id,mode); }
- int getInfo()
- { return dGeomTransformGetInfo (_id); }
-};
-
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/odecpp_old.h b/extern/ode/dist/include/ode/odecpp_old.h
deleted file mode 100644
index b7b55232f89..00000000000
--- a/extern/ode/dist/include/ode/odecpp_old.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/* this is the old C++ interface, the new C++ interface is not quite
- * compatible with this. but this file is kept around in case you were
- * using the old interface.
- */
-
-#ifndef _ODE_ODECPP_H_
-#define _ODE_ODECPP_H_
-#ifdef __cplusplus
-
-#include <ode/error.h>
-
-
-class dWorld {
- dWorldID _id;
-
- dWorld (dWorld &) { dDebug (0,"bad"); }
- void operator= (dWorld &) { dDebug (0,"bad"); }
-
-public:
- dWorld()
- { _id = dWorldCreate(); }
- ~dWorld()
- { dWorldDestroy (_id); }
- dWorldID id()
- { return _id; }
-
- void setGravity (dReal x, dReal y, dReal z)
- { dWorldSetGravity (_id,x,y,z); }
- void getGravity (dVector3 g)
- { dWorldGetGravity (_id,g); }
- void step (dReal stepsize)
- { dWorldStep (_id,stepsize); }
-};
-
-
-class dBody {
- dBodyID _id;
-
- dBody (dBody &) { dDebug (0,"bad"); }
- void operator= (dBody &) { dDebug (0,"bad"); }
-
-public:
- dBody()
- { _id = 0; }
- dBody (dWorld &world)
- { _id = dBodyCreate (world.id()); }
- ~dBody()
- { dBodyDestroy (_id); }
- void create (dWorld &world)
- { if (_id) dBodyDestroy (_id); _id = dBodyCreate (world.id()); }
- dBodyID id()
- { return _id; }
-
- void setData (void *data)
- { dBodySetData (_id,data); }
- void *getData()
- { return dBodyGetData (_id); }
-
- void setPosition (dReal x, dReal y, dReal z)
- { dBodySetPosition (_id,x,y,z); }
- void setRotation (const dMatrix3 R)
- { dBodySetRotation (_id,R); }
- void setQuaternion (const dQuaternion q)
- { dBodySetQuaternion (_id,q); }
- void setLinearVel (dReal x, dReal y, dReal z)
- { dBodySetLinearVel (_id,x,y,z); }
- void setAngularVel (dReal x, dReal y, dReal z)
- { dBodySetAngularVel (_id,x,y,z); }
-
- const dReal * getPosition()
- { return dBodyGetPosition (_id); }
- const dReal * getRotation()
- { return dBodyGetRotation (_id); }
- const dReal * getQuaternion()
- { return dBodyGetQuaternion (_id); }
- const dReal * getLinearVel()
- { return dBodyGetLinearVel (_id); }
- const dReal * getAngularVel()
- { return dBodyGetAngularVel (_id); }
-
- void setMass (const dMass *mass)
- { dBodySetMass (_id,mass); }
- void getMass (dMass *mass)
- { dBodyGetMass (_id,mass); }
-
- void addForce (dReal fx, dReal fy, dReal fz)
- { dBodyAddForce (_id, fx, fy, fz); }
- void addTorque (dReal fx, dReal fy, dReal fz)
- { dBodyAddTorque (_id, fx, fy, fz); }
- void addRelForce (dReal fx, dReal fy, dReal fz)
- { dBodyAddRelForce (_id, fx, fy, fz); }
- void addRelTorque (dReal fx, dReal fy, dReal fz)
- { dBodyAddRelTorque (_id, fx, fy, fz); }
- void addForceAtPos (dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
- { dBodyAddForceAtPos (_id, fx, fy, fz, px, py, pz); }
- void addRelForceAtPos (dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
- { dBodyAddRelForceAtPos (_id, fx, fy, fz, px, py, pz); }
- void addRelForceAtRelPos (dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
- { dBodyAddRelForceAtRelPos (_id, fx, fy, fz, px, py, pz); }
-
- void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result)
- { dBodyGetRelPointPos (_id, px, py, pz, result); }
- void getRelPointVel (dReal px, dReal py, dReal pz, dVector3 result)
- { dBodyGetRelPointVel (_id, px, py, pz, result); }
-
- int isConnectedTo (const dBody &b)
- { return dAreConnected (_id,b._id); }
-};
-
-
-class dJointGroup {
- dJointGroupID _id;
-
- dJointGroup (dJointGroup &) { dDebug (0,"bad"); }
- void operator= (dJointGroup &) { dDebug (0,"bad"); }
-
-public:
- dJointGroup()
- { _id = 0; }
- dJointGroup (int max_size)
- { _id = dJointGroupCreate (max_size); }
- ~dJointGroup()
- { dJointGroupDestroy (_id); }
- void create (int max_size)
- { if (_id) dJointGroupDestroy (_id); _id = dJointGroupCreate (max_size); }
- dJointGroupID id()
- { return _id; }
-
- void empty()
- { dJointGroupEmpty (_id); }
-};
-
-
-class dJoint {
- dJointID _id;
-
- dJoint (dJoint &) { dDebug (0,"bad"); }
- void operator= (dJoint &) { dDebug (0,"bad"); }
-
-public:
- dJoint()
- { _id = 0; }
- ~dJoint()
- { dJointDestroy (_id); }
- dJointID id()
- { return _id; }
-
- void createBall (dWorld &world, dJointGroup *group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateBall (world.id(), group ? group->id() : 0);
- }
- void createHinge (dWorld &world, dJointGroup *group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateHinge (world.id(), group ? group->id() : 0);
- }
- void createSlider (dWorld &world, dJointGroup *group=0) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateSlider (world.id(), group ? group->id() : 0);
- }
- void createContact (dWorld &world, dJointGroup *group, dContact *contact) {
- if (_id) dJointDestroy (_id);
- _id = dJointCreateContact (world.id(), group ? group->id() : 0, contact);
- }
-
- void attach (dBody &body1, dBody &body2)
- { dJointAttach (_id, body1.id(), body2.id()); }
-
- void setBallAnchor (dReal x, dReal y, dReal z)
- { dJointSetBallAnchor (_id, x, y, z); }
- void setHingeAnchor (dReal x, dReal y, dReal z)
- { dJointSetHingeAnchor (_id, x, y, z); }
-
- void setHingeAxis (dReal x, dReal y, dReal z)
- { dJointSetHingeAxis (_id, x, y, z); }
- void setSliderAxis (dReal x, dReal y, dReal z)
- { dJointSetSliderAxis (_id, x, y, z); }
-
- void getBallAnchor (dVector3 result)
- { dJointGetBallAnchor (_id, result); }
- void getHingeAnchor (dVector3 result)
- { dJointGetHingeAnchor (_id, result); }
-
- void getHingeAxis (dVector3 result)
- { dJointGetHingeAxis (_id, result); }
- void getSliderAxis (dVector3 result)
- { dJointGetSliderAxis (_id, result); }
-};
-
-
-class dSpace {
- dSpaceID _id;
-
- dSpace (dSpace &) { dDebug (0,"bad"); }
- void operator= (dSpace &) { dDebug (0,"bad"); }
-
-public:
- dSpace ()
- { _id = dHashSpaceCreate(); }
- ~dSpace()
- { dSpaceDestroy (_id); }
- dSpaceID id()
- { return _id; }
- void collide (void *data, dNearCallback *callback)
- { dSpaceCollide (_id,data,callback); }
-};
-
-
-class dGeom {
- dGeomID _id;
-
- dGeom (dGeom &) { dDebug (0,"bad"); }
- void operator= (dGeom &) { dDebug (0,"bad"); }
-
-public:
- dGeom()
- { _id = 0; }
- ~dGeom()
- { dGeomDestroy (_id); }
- dGeomID id()
- { return _id; }
-
- void createSphere (dSpace &space, dReal radius) {
- if (_id) dGeomDestroy (_id);
- _id = dCreateSphere (space.id(),radius);
- }
-
- void createBox (dSpace &space, dReal lx, dReal ly, dReal lz) {
- if (_id) dGeomDestroy (_id);
- _id = dCreateBox (space.id(),lx,ly,lz);
- }
-
- void createPlane (dSpace &space, dReal a, dReal b, dReal c, dReal d) {
- if (_id) dGeomDestroy (_id);
- _id = dCreatePlane (space.id(),a,b,c,d);
- }
-
- void createCCylinder (dSpace &space, dReal radius, dReal length) {
- if (_id) dGeomDestroy (_id);
- _id = dCreateCCylinder (space.id(),radius,length);
- }
-
- void destroy() {
- if (_id) dGeomDestroy (_id);
- _id = 0;
- }
-
- int getClass()
- { return dGeomGetClass (_id); }
-
- dReal sphereGetRadius()
- { return dGeomSphereGetRadius (_id); }
-
- void boxGetLengths (dVector3 result)
- { dGeomBoxGetLengths (_id,result); }
-
- void planeGetParams (dVector4 result)
- { dGeomPlaneGetParams (_id,result); }
-
- void CCylinderGetParams (dReal *radius, dReal *length)
- { dGeomCCylinderGetParams (_id,radius,length); }
-
- void setData (void *data)
- { dGeomSetData (_id,data); }
-
- void *getData()
- { return dGeomGetData (_id); }
-
- void setBody (dBody &b)
- { dGeomSetBody (_id,b.id()); }
- void setBody (dBodyID b)
- { dGeomSetBody (_id,b); }
-
- dBodyID getBody()
- { return dGeomGetBody (_id); }
-
- void setPosition (dReal x, dReal y, dReal z)
- { dGeomSetPosition (_id,x,y,z); }
-
- void setRotation (const dMatrix3 R)
- { dGeomSetRotation (_id,R); }
-
- const dReal * getPosition()
- { return dGeomGetPosition (_id); }
-
- const dReal * getRotation()
- { return dGeomGetRotation (_id); }
-};
-
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/odemath.h b/extern/ode/dist/include/ode/odemath.h
deleted file mode 100644
index 5f41a27b5a1..00000000000
--- a/extern/ode/dist/include/ode/odemath.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_ODEMATH_H_
-#define _ODE_ODEMATH_H_
-
-#include <ode/common.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* 3-way dot product. dDOTpq means that elements of `a' and `b' are spaced
- * p and q indexes apart respectively. dDOT() means dDOT11.
- */
-
-#ifdef __cplusplus
-inline dReal dDOT (const dReal *a, const dReal *b)
- { return ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]); }
-inline dReal dDOT14(const dReal *a, const dReal *b)
- { return ((a)[0]*(b)[0] + (a)[1]*(b)[4] + (a)[2]*(b)[8]); }
-inline dReal dDOT41(const dReal *a, const dReal *b)
- { return ((a)[0]*(b)[0] + (a)[4]*(b)[1] + (a)[8]*(b)[2]); }
-inline dReal dDOT44(const dReal *a, const dReal *b)
- { return ((a)[0]*(b)[0] + (a)[4]*(b)[4] + (a)[8]*(b)[8]); }
-#else
-#define dDOT(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2])
-#define dDOT14(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[4] + (a)[2]*(b)[8])
-#define dDOT41(a,b) ((a)[0]*(b)[0] + (a)[4]*(b)[1] + (a)[8]*(b)[2])
-#define dDOT44(a,b) ((a)[0]*(b)[0] + (a)[4]*(b)[4] + (a)[8]*(b)[8])
-#endif
-
-
-/* cross product, set a = b x c. dCROSSpqr means that elements of `a', `b'
- * and `c' are spaced p, q and r indexes apart respectively.
- * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to
- * +=, -= etc to get other effects.
- */
-
-#define dCROSS(a,op,b,c) \
- (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \
- (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \
- (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]);
-#define dCROSSpqr(a,op,b,c,p,q,r) \
- (a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \
- (a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \
- (a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]);
-#define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4)
-#define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1)
-#define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4)
-#define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1)
-#define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4)
-#define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1)
-#define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4)
-
-
-/* set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b.
- * A is stored by rows, and has `skip' elements per row. the matrix is
- * assumed to be already zero, so this does not write zero elements!
- * if (plus,minus) is (+,-) then a positive version will be written.
- * if (plus,minus) is (-,+) then a negative version will be written.
- */
-
-#define dCROSSMAT(A,a,skip,plus,minus) \
- (A)[1] = minus (a)[2]; \
- (A)[2] = plus (a)[1]; \
- (A)[(skip)+0] = plus (a)[2]; \
- (A)[(skip)+2] = minus (a)[0]; \
- (A)[2*(skip)+0] = minus (a)[1]; \
- (A)[2*(skip)+1] = plus (a)[0];
-
-
-/* compute the distance between two 3-vectors (oops, C++!) */
-#ifdef __cplusplus
-inline dReal dDISTANCE (const dVector3 a, const dVector3 b)
- { return dSqrt( (a[0]-b[0])*(a[0]-b[0]) + (a[1]-b[1])*(a[1]-b[1]) +
- (a[2]-b[2])*(a[2]-b[2]) ); }
-#else
-#define dDISTANCE(a,b) \
- (dSqrt( ((a)[0]-(b)[0])*((a)[0]-(b)[0]) + ((a)[1]-(b)[1])*((a)[1]-(b)[1]) + \
- ((a)[2]-(b)[2])*((a)[2]-(b)[2]) ))
-#endif
-
-
-/* normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) */
-void dNormalize3 (dVector3 a);
-void dNormalize4 (dVector4 a);
-
-
-/* given a unit length "normal" vector n, generate vectors p and q vectors
- * that are an orthonormal basis for the plane space perpendicular to n.
- * i.e. this makes p,q such that n,p,q are all perpendicular to each other.
- * q will equal n x p. if n is not unit length then p will be unit length but
- * q wont be.
- */
-
-void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q);
-
-
-/* special case matrix multipication, with operator selection */
-
-#define dMULTIPLYOP0_331(A,op,B,C) \
- (A)[0] op dDOT((B),(C)); \
- (A)[1] op dDOT((B+4),(C)); \
- (A)[2] op dDOT((B+8),(C));
-#define dMULTIPLYOP1_331(A,op,B,C) \
- (A)[0] op dDOT41((B),(C)); \
- (A)[1] op dDOT41((B+1),(C)); \
- (A)[2] op dDOT41((B+2),(C));
-#define dMULTIPLYOP0_133(A,op,B,C) \
- (A)[0] op dDOT14((B),(C)); \
- (A)[1] op dDOT14((B),(C+1)); \
- (A)[2] op dDOT14((B),(C+2));
-#define dMULTIPLYOP0_333(A,op,B,C) \
- (A)[0] op dDOT14((B),(C)); \
- (A)[1] op dDOT14((B),(C+1)); \
- (A)[2] op dDOT14((B),(C+2)); \
- (A)[4] op dDOT14((B+4),(C)); \
- (A)[5] op dDOT14((B+4),(C+1)); \
- (A)[6] op dDOT14((B+4),(C+2)); \
- (A)[8] op dDOT14((B+8),(C)); \
- (A)[9] op dDOT14((B+8),(C+1)); \
- (A)[10] op dDOT14((B+8),(C+2));
-#define dMULTIPLYOP1_333(A,op,B,C) \
- (A)[0] op dDOT44((B),(C)); \
- (A)[1] op dDOT44((B),(C+1)); \
- (A)[2] op dDOT44((B),(C+2)); \
- (A)[4] op dDOT44((B+1),(C)); \
- (A)[5] op dDOT44((B+1),(C+1)); \
- (A)[6] op dDOT44((B+1),(C+2)); \
- (A)[8] op dDOT44((B+2),(C)); \
- (A)[9] op dDOT44((B+2),(C+1)); \
- (A)[10] op dDOT44((B+2),(C+2));
-#define dMULTIPLYOP2_333(A,op,B,C) \
- (A)[0] op dDOT((B),(C)); \
- (A)[1] op dDOT((B),(C+4)); \
- (A)[2] op dDOT((B),(C+8)); \
- (A)[4] op dDOT((B+4),(C)); \
- (A)[5] op dDOT((B+4),(C+4)); \
- (A)[6] op dDOT((B+4),(C+8)); \
- (A)[8] op dDOT((B+8),(C)); \
- (A)[9] op dDOT((B+8),(C+4)); \
- (A)[10] op dDOT((B+8),(C+8));
-
-#ifdef __cplusplus
-
-inline void dMULTIPLY0_331(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP0_331(A,=,B,C) }
-inline void dMULTIPLY1_331(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP1_331(A,=,B,C) }
-inline void dMULTIPLY0_133(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP0_133(A,=,B,C) }
-inline void dMULTIPLY0_333(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP0_333(A,=,B,C) }
-inline void dMULTIPLY1_333(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP1_333(A,=,B,C) }
-inline void dMULTIPLY2_333(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP2_333(A,=,B,C) }
-
-inline void dMULTIPLYADD0_331(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP0_331(A,+=,B,C) }
-inline void dMULTIPLYADD1_331(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP1_331(A,+=,B,C) }
-inline void dMULTIPLYADD0_133(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP0_133(A,+=,B,C) }
-inline void dMULTIPLYADD0_333(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP0_333(A,+=,B,C) }
-inline void dMULTIPLYADD1_333(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP1_333(A,+=,B,C) }
-inline void dMULTIPLYADD2_333(dReal *A, const dReal *B, const dReal *C)
- { dMULTIPLYOP2_333(A,+=,B,C) }
-
-#else
-
-#define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C)
-#define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C)
-#define dMULTIPLY0_133(A,B,C) dMULTIPLYOP0_133(A,=,B,C)
-#define dMULTIPLY0_333(A,B,C) dMULTIPLYOP0_333(A,=,B,C)
-#define dMULTIPLY1_333(A,B,C) dMULTIPLYOP1_333(A,=,B,C)
-#define dMULTIPLY2_333(A,B,C) dMULTIPLYOP2_333(A,=,B,C)
-
-#define dMULTIPLYADD0_331(A,B,C) dMULTIPLYOP0_331(A,+=,B,C)
-#define dMULTIPLYADD1_331(A,B,C) dMULTIPLYOP1_331(A,+=,B,C)
-#define dMULTIPLYADD0_133(A,B,C) dMULTIPLYOP0_133(A,+=,B,C)
-#define dMULTIPLYADD0_333(A,B,C) dMULTIPLYOP0_333(A,+=,B,C)
-#define dMULTIPLYADD1_333(A,B,C) dMULTIPLYOP1_333(A,+=,B,C)
-#define dMULTIPLYADD2_333(A,B,C) dMULTIPLYOP2_333(A,+=,B,C)
-
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/rotation.h b/extern/ode/dist/include/ode/rotation.h
deleted file mode 100644
index 19204c651f3..00000000000
--- a/extern/ode/dist/include/ode/rotation.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_ROTATION_H_
-#define _ODE_ROTATION_H_
-
-#include <ode/common.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-void dRSetIdentity (dMatrix3 R);
-
-void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,
- dReal angle);
-
-void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi);
-
-void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az,
- dReal bx, dReal by, dReal bz);
-
-void dQSetIdentity (dQuaternion q);
-
-void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az,
- dReal angle);
-
-void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
-void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
-void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
-void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc);
-
-void dQtoR (const dQuaternion q, dMatrix3 R);
-
-void dRtoQ (const dMatrix3 R, dQuaternion q);
-
-void dWtoDQ (const dVector3 w, const dQuaternion q, dVector4 dq);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/space.h b/extern/ode/dist/include/ode/space.h
deleted file mode 100644
index c540cd69d6e..00000000000
--- a/extern/ode/dist/include/ode/space.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_SPACE_H_
-#define _ODE_SPACE_H_
-
-#include <ode/common.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct dContactGeom;
-
-typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2);
-
-
-/* extra information the space needs in every geometry object */
-
-typedef struct dGeomSpaceData {
- dGeomID next;
-} dGeomSpaceData;
-
-
-dSpaceID dSimpleSpaceCreate();
-dSpaceID dHashSpaceCreate();
-
-void dSpaceDestroy (dSpaceID);
-void dSpaceAdd (dSpaceID, dGeomID);
-void dSpaceRemove (dSpaceID, dGeomID);
-void dSpaceCollide (dSpaceID space, void *data, dNearCallback *callback);
-int dSpaceQuery (dSpaceID, dGeomID);
-
-void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel);
-
-
-/* @@@ NOT FLEXIBLE ENOUGH
- *
- * generate contacts for those objects in the space that touch each other.
- * an array of contacts is created on the alternative stack using
- * StackAlloc(), and a pointer to the array is returned. the size of the
- * array is returned by the function.
- */
-/* int dSpaceCollide (dSpaceID space, dContactGeom **contact_array); */
-
-
-/* HMMMMM... i dont think so.
- * tell the space that an object has moved, so its representation in the
- * space should be changed.
- */
-/* void dSpaceObjectMoved (dSpaceID, dGeomID); */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/include/ode/timer.h b/extern/ode/dist/include/ode/timer.h
deleted file mode 100644
index fe2574feb3c..00000000000
--- a/extern/ode/dist/include/ode/timer.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_TIMER_H_
-#define _ODE_TIMER_H_
-
-#include <ode/config.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* stop watch objects */
-
-typedef struct dStopwatch {
- double time; /* total clock count */
- unsigned long cc[2]; /* clock count since last `start' */
-} dStopwatch;
-
-void dStopwatchReset (dStopwatch *);
-void dStopwatchStart (dStopwatch *);
-void dStopwatchStop (dStopwatch *);
-double dStopwatchTime (dStopwatch *); /* returns total time in secs */
-
-
-/* code timers */
-
-void dTimerStart (const char *description); /* pass a static string here */
-void dTimerNow (const char *description); /* pass a static string here */
-void dTimerEnd();
-
-/* print out a timer report. if `average' is nonzero, print out the average
- * time for each slot (this is only meaningful if the same start-now-end
- * calls are being made repeatedly.
- */
-void dTimerReport (FILE *fout, int average);
-
-
-/* resolution */
-
-/* returns the timer ticks per second implied by the timing hardware or API.
- * the actual timer resolution may not be this great.
- */
-double dTimerTicksPerSecond();
-
-/* returns an estimate of the actual timer resolution, in seconds. this may
- * be greater than 1/ticks_per_second.
- */
-double dTimerResolution();
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/extern/ode/dist/ode/README b/extern/ode/dist/ode/README
deleted file mode 100644
index dd4596f9935..00000000000
--- a/extern/ode/dist/ode/README
+++ /dev/null
@@ -1,158 +0,0 @@
-Dynamics Library.
-=================
-
-CONVENTIONS
------------
-
-matrix storage
---------------
-
-matrix operations like factorization are expensive, so we must store the data
-in a way that is most useful to the matrix code. we want the ability to update
-the dynamics library without recompiling applications, e.g. so users can take
-advantage of new floating point hardware. so we must settle on a single
-format. because of the prevalence of 4-way SIMD, the format is this: store
-the matrix by rows or columns, and each column is rounded up to a multiple of
-4 elements. the extra "padding" elements at the end of each row/column are set
-to 0. this is called the "standard format". to indicate if the data is stored
-by rows or columns, we will say "standard row format" or "standard column
-format". hopefully this decision will remain good in the future, as more and
-more processors have 4-way SIMD, and 3D graphics always needs fast 4x4
-matrices.
-
-exception: matrices that have only one column or row (vectors), are always
-stored as consecutive elements in standard row format, i.e. there is no
-interior padding, only padding at the end.
-
-thus: all 3x1 floating point vectors are stored as 4x1 vectors: (x,x,x,0).
-also: all 6x1 spatial velocities and accelerations are split into 3x1 position
- and angular components, which are stored as contiguous 4x1 vectors.
-
-ALL matrices are stored by in standard row format.
-
-
-arguments
----------
-
-3x1 vector arguments to set() functions are supplied as x,y,z.
-3x1 vector result arguments to get() function are pointers to arrays.
-larger vectors are always supplied and returned as pointers.
-all coordinates are in the global frame except where otherwise specified.
-output-only arguments are usually supplied at the end.
-
-
-memory allocation
------------------
-
-with many C/C++ libraries memory allocation is a difficult problem to solve.
-who allocates the memory? who frees it? must objects go on the heap or can
-they go on the stack or in static storage? to provide the maximum flexibility,
-the dynamics and collision libraries do not do their own memory allocation.
-you must pass in pointers to externally allocated chunks of the right sizes.
-the body, joint and colllision object structures are all exported, so you
-can make instances of those structure and pass pointers to them.
-
-there are helper functions which allocate objects out of areans, in case you
-need loots of dynamic creation and deletion.
-
-BUT!!! this ties us down to the body/joint/collision representation.
-
-a better approach is to supply custom memory allocation functions
-(e.g. dlAlloc() etc).
-
-
-C versus C++ ... ?
-------------------
-
-everything should be C linkable, and there should be C header files for
-everything. but we want to develop in C++. so do this:
- * all comments are "//". automatically convert to /**/ for distribution.
- * structures derived from other structures --> automatically convert?
-
-
-WORLDS
-------
-
-might want better terminology here.
-
-the dynamics world (DWorld) is a list of systems. each system corresponds to
-one or more bodies, or perhaps some other kinds of physical object.
-each system corresponds to one or more objects in the collision world
-(there does not have to be a one-to-one correspondence between bodies and
-collision objects).
-
-systems are simulated separately, perhaps using completely different
-techniques. we must do something special when systems collide.
-systems collide when collision objects belonging to system A touch
-collision objects belonging to system B.
-
-for each collision point, the system must provide matrix equation data
-that is used to compute collision forces. once those forces are computed,
-the system must incorporate the forces into its timestep.
-PROBLEM: what if we intertwine the LCP problems of the two systems - then
-this simple approach wont work.
-
-the dynamics world contains two kinds of objects: bodies and joints.
-joints connect two bodies together.
-
-the world contains one of more partitions. each partition is a collection of
-bodies and joints such that each body is attached (through one or more joints)
-to every other body.
-
-Joints
-------
-
-a joint can be connected to one or two bodies.
-if the joint is only connected to one body, joint.node[1].body == 0.
-joint.node[0].body is always valid.
-
-
-Linkage
--------
-
-this library will always be statically linked with the app, for these reasons:
- * collision space is selected at compile time, it adds data to the geom
- objects.
-
-
-Optimization
-------------
-
-doubles must be aligned on 8 byte boundaries!
-
-
-MinGW on Windows issues
------------------------
-
-* the .rc file for drawstuff needs a different include, try winresrc.h.
-
-* it seems we can't have both main() and WinMain() without the entry point
- defaulting to main() and having resource loading problems. this screws up
- what i was trying to do in the drawstuff library. perhaps main2() ?
-
-* remember to compile resources to COFF format RES files.
-
-
-
-Collision
----------
-
-to plug in your own collision handling, replace (some of?) these functions
-with your own. collision should be a separate library that you can link in
-or not. your own library can call components in this collision library, e.g.
-if you want polymorphic spaces instead of a single statically called space.
-
-creating an object will automatically register the appropriate
-class (if necessary). how can we ensure that the minimum amount of code is
-linked in? e.g. only one space handler, and sphere-sphere and sphere-box and
-box-box collision code (if spheres and boxes instanced).
-
-the user creates a collision space, and for each dynamics object that is
-created a collision object is inserted into the space. the collision
-object's pos and R pointers are set to the corresponding dynamics
-variables.
-
-there should be utility functions which create the dynamics and collision
-objects at the same time, e.g. dMakeSphere().
-
-collision objects and dynamics objects keep pointers to each other.
diff --git a/extern/ode/dist/ode/fbuild/BuildDot b/extern/ode/dist/ode/fbuild/BuildDot
deleted file mode 100644
index 09b49274da8..00000000000
--- a/extern/ode/dist/ode/fbuild/BuildDot
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/perl
-#
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# dot product code generator.
-#
-# code generation parameters, set in a parameters file:
-# FNAME : name of source file to generate - a .c file will be made
-# UNROLL1 : inner loop unrolling factor (1..)
-# FETCH : max num of a[i]'s and b[i]'s to load ahead of muls
-# LAT1 : load -> mul latency (>=1)
-# LAT2 : mul -> add latency (>=1). if this is 1, use fused mul-add
-#
-#############################################################################
-
-require ("BuildUtil");
-
-# get and check code generation parameters
-error ("Usage: BuildDot <parameters-file>") if $#ARGV != 0;
-do $ARGV[0];
-
-if (!defined($FNAME) || !defined($UNROLL1) || !defined($FETCH) ||
- !defined($LAT1) || !defined($LAT2)) {
- error ("code generation parameters not defined");
-}
-
-# check parameters
-error ("bad UNROLL1") if $UNROLL1 < 1;
-error ("bad FETCH") if $FETCH < 1;
-error ("bad LAT1") if $LAT1 < 1;
-error ("bad LAT2") if $LAT2 < 1;
-
-#############################################################################
-
-open (FOUT,">$FNAME.c") or die "can't open $FNAME.c for writing";
-
-# file and function header
-output (<<END);
-/* generated code, do not edit. */
-
-#include "ode/matrix.h"
-
-
-dReal dDot (const dReal *a, const dReal *b, int n)
-{
-END
-
-output ("dReal ");
-for ($i=0; $i<$UNROLL1; $i++) {
- output ("p$i,q$i,m$i,");
-}
-output ("sum;\n");
-
-output (<<END);
-sum = 0;
-n -= $UNROLL1;
-while (n >= 0) {
-END
-
-@load = (); # slot where a[i]'s and b[i]'s loaded
-@mul = (); # slot where multiply i happened
-@add = (); # slow where add i happened
-
-# in the future we may want to reduce the number of variables declared,
-# so these arrays will be useful.
-@pqused = (); # 1 if p/q[i] loaded with data, 0 once that data's used
-@mused = (); # 1 if m[i] loaded with data, 0 once that data's used
-@pqmap = (); # map virtual p/q variables to actual p/q variables
-@mmap = (); # map virtual m variables to actual m variables
-
-output ("p0 = a[0]; q0 = b[0];\n");
-push (@load,0);
-
-$slot=0; # one slot for every load/mul/add/nop issued
-for (;;) {
- $startslot = $slot;
-
- # do next load
- if (($#load - $#mul) < $FETCH && ($#load+1) < $UNROLL1) {
- push (@load,$slot);
- output ("p$#load = a[$#load]; q$#load = b[$#load];\n");
- $slot++;
- }
- # do next multiply
- if ($#load > $#mul && $slot >= ($load[$#mul+1] + $LAT1) &&
- ($#mul+1) < $UNROLL1) {
- push (@mul,$slot);
- if ($LAT2 > 1) {
- output ("m$#mul = p$#mul * q$#mul;\n");
- }
- else {
- output ("sum += p$#mul * q$#mul;\n");
- last if ($#mul+1) >= $UNROLL1;
- }
- $slot++;
- }
- # do next add
- if ($LAT2 > 1) {
- if ($#mul > $#add && $slot >= ($mul[$#add+1] + $LAT2)) {
- push (@add,$slot);
- output ("sum += m$#add;\n");
- $slot++;
- last if ($#add+1) >= $UNROLL1;
- }
- }
-
- if ($slot == $startslot) {
- # comment ("nop");
- $slot++;
- }
-}
-
-output ("a += $UNROLL1;\n");
-output ("b += $UNROLL1;\n");
-output ("n -= $UNROLL1;\n");
-output ("}\n");
-
-output (<<END);
-n += $UNROLL1;
-while (n > 0) {
-sum += (*a) * (*b);
-a++;
-b++;
-n--;
-}
-return sum;
-}
-END
diff --git a/extern/ode/dist/ode/fbuild/BuildLDLT b/extern/ode/dist/ode/fbuild/BuildLDLT
deleted file mode 100644
index fd74faf18df..00000000000
--- a/extern/ode/dist/ode/fbuild/BuildLDLT
+++ /dev/null
@@ -1,654 +0,0 @@
-#!/usr/bin/perl
-#
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-#
-# triangular matrix solver and factorizer code generator.
-#
-# SOLVER
-# ------
-#
-# if L is an n x n lower triangular matrix (with ones on the diagonal), the
-# solver solves L*X=B where X and B are n x m matrices. this is the core
-# step in L*D*L' factorization. the algorithm is (in matlab):
-#
-# for i=1:n
-# for j=1:m
-# X(i,j) = B(i,j) - L(i,1:i-1)*X(1:i-1,j);
-# end
-# end
-#
-# note that the ordering of the (i,j) loop is somewhat arbitrary. the only
-# prerequisite to calculating element (i,j) of X is that all X(1:i-1,j) have
-# have already been calcuated. this gives us some flexibility.
-#
-# the code generated below calculates X in N1 x N1 blocks. to speed up the
-# innermost dot product loop, the outer product trick is used. for instance,
-# to calculate the value of the 2x2 matrix ABCD below we first iterate over
-# the vectors (a,b,c,d) and (e,f,g,h), computing ABCD = a*e+b*f+c*g+d*h.
-# then A and B contain the dot product values needed in the algorithm, and
-# C and D have almost all of it. the outer product trick reduces the number
-# of memory loads required. in this example 16 loads are required, but if
-# the simple dot product in the above algorithm is used then 32 loads are
-# required. increasing N1 decreases the total number of loads, but only as long
-# as we have enough temporary registers to keep the matrix blocks and vectors.
-#
-# L * X = B
-#
-# [ . ] [ e e ] [ . . ]
-# [ . . ] [ f f ] [ . . ]
-# [ . . . ] [ g g ] [ . . ]
-# [ . . . . ] [ h h ] [ . . ]
-# [ a b c d . ] [ A B ] = [ . . ]
-# [ a b c d . . ] [ C D ] [ . . ]
-# [ . . . . . . . ] [ . . ] [ . . ]
-# [ . . . . . . . . ] [ . . ] [ . . ]
-# [ . . . . . . . . . ] [ . . ] [ . . ]
-#
-# note that L is stored by rows but X and B are stored by columns.
-# the outer product loops are unrolled for extra speed.
-#
-# LDLT FACTORIZATION
-# ------------------
-#
-# the factorization algorithm builds L incrementally by repeatedly solving
-# the following equation:
-#
-# [ L 0 ] [ D 0 ] [ L' l ] = [ A a ] <-- n rows
-# [ l' e ] [ 0 d ] [ 0 e' ] [ a' b ] <-- m rows
-#
-# [ L*D*L' L*D*l ] = [ A a ]
-# [ l'*D*L' l'*D*l+e*d*e' ] [ a' b ]
-#
-# L*D*L'=A is an existing solution, and a,b are new rows/columns to add to A.
-# we compute:
-#
-# L * (Dl) = a
-# l = inv(D) * Dl
-# e*d*e' = b - l'*Dl (m*m LDLT factorization)
-#
-#
-# L-transpose solver
-# ------------------
-#
-# the LT (L-transpose) solver uses the same logic as the standard L-solver,
-# with a few tricks to make it work. to solve L^T*X=B we first remap:
-# L to Lhat : Lhat(i,j) = L(n-j,n-i)
-# X to Xhat : Xhat(i) = X(n-i)
-# B to Bhat : Bhat(i) = B(n-i)
-# and then solve Lhat*Xhat = Bhat. the current LT solver only supports one
-# right hand side, but that's okay as it is not used in the factorizer.
-#
-#############################################################################
-#
-# code generation parameters, set in a parameters file:
-# FNAME : name of source file to generate - a .c file will be made
-# TYPE : 'f' to build factorizer, 's' to build solver, 't' to build the
-# transpose solver.
-# N1 : block size (size of outer product matrix) (1..9)
-# UNROLL1 : solver inner loop unrolling factor (1..)
-# UNROLL2 : factorizer inner loop unrolling factor (1..)
-# MADD : if nonzero, generate code for fused multiply-add (0,1)
-# FETCH : how to fetch data in the inner loop:
-# 0 - load in a batch (the `normal way')
-# 1 - delay inner loop loads until just before they're needed
-#
-#############################################################################
-#
-# TODO
-# ----
-#
-# * dFactorLDLT() is not so efficient for matrix sizes < block size, e.g.
-# redundant calls, zero loads, adds etc
-#
-#############################################################################
-#
-# NOTES:
-#
-# * on the pentium we can prefetch like this:
-# asm ("prefetcht0 %0" : : "m" (*Ai) );
-# but it doesn't seem to help much
-
-require ("BuildUtil");
-
-# get and check code generation parameters
-error ("Usage: BuildLDLT <parameters-file>") if $#ARGV != 0;
-do $ARGV[0];
-
-if (!defined($FNAME) || !defined($TYPE) || !defined($N1) ||
- !defined($UNROLL1) || !defined($UNROLL2) || !defined($MADD) ||
- !defined($FETCH)) {
- error ("code generation parameters not defined");
-}
-
-# check parameters
-error ("bad TYPE") if $TYPE ne 'f' && $TYPE ne 's' && $TYPE ne 't';
-error ("bad N1") if $N1 < 1 || $N1 > 9;
-error ("bad UNROLL1") if $UNROLL1 < 1;
-error ("bad UNROLL2") if $UNROLL2 < 1;
-error ("bad MADD") if $MADD != 0 && $MADD != 1;
-error ("bad FETCH") if $FETCH < 0 && $FETCH > 1;
-
-#############################################################################
-# utility
-
-# functions to handle delayed loading of p and q values.
-# bit in the the `ploaded' and `qloaded' numbers record what has been loaded,
-# so we dont load it again.
-
-sub newLoads
-{
- # bits in these numbers say what registers p and q have been loaded so far
- $ploaded = 0;
- $qloaded = 0;
-}
-
-sub loadedEverything
-{
- $ploaded = 0xffffffff;
- $qloaded = 0xffffffff;
-}
-
-sub loadP # (i,loadcmd)
-{
- my $i = $_[0];
- my $loadcmd = $_[1];
- return if ($ploaded & (1 << $i));
- output ($loadcmd);
- $ploaded |= (1 << $i);
-}
-
-sub loadQ # (i,loadcmd)
-{
- my $i = $_[0];
- my $loadcmd = $_[1];
- return if ($qloaded & (1 << $i));
- output ($loadcmd);
- $qloaded |= (1 << $i);
-}
-
-#############################################################################
-# make a fast L solve function.
-# this function has a restriction that the leading dimension of X and B must
-# be a multiple of the block size.
-
-sub innerOuterProductLoop # (M,k,nrhs,increment)
-{
- my $M=$_[0];
- my $k=$_[1];
- my $nrhs=$_[2];
- my $increment=$_[3];
- my ($i,$j);
- newLoads;
- if ($FETCH==0) {
- comment ("load p and q values");
- for ($i=1; $i<=$M; $i++) {
- if ($TYPE eq 't') {
- output ("p$i=ell[".ofs2(-($i-1),0,'lskip')."];\n");
- output ("q$i=ex[".ofs2(-($k),$i-1,'lskip')."];\n") if $i <= $nrhs;
- }
- else {
- output ("p$i=ell[".ofs2($k,$i-1,'lskip')."];\n");
- output ("q$i=ex[".ofs2($k,$i-1,'lskip')."];\n") if $i <= $nrhs;
- }
- }
- loadedEverything;
- }
-
- comment ("compute outer product and add it to the Z matrix");
- for ($i=1; $i<=$M; $i++) {
- for ($j=1; $j<=$nrhs; $j++) {
- if ($TYPE eq 't') {
- loadP ($i,"p$i=ell[".ofs2(-($i-1),0,'lskip')."];\n");
- loadQ ($j,"q$j=ex[".ofs2(-($k),$j-1,'lskip')."];\n");
- }
- else {
- loadP ($i,"p$i=ell[".ofs2($k,$i-1,'lskip')."];\n");
- loadQ ($j,"q$j=ex[".ofs2($k,$j-1,'lskip')."];\n");
- }
- my $var = $MADD ? "Z$i$j +=" : "m$i$j =";
- output ("$var p$i * q$j;\n");
- }
- }
-
- if ($TYPE eq 't') {
- if ($increment > 0) {
- output ("ell += lskip1;\n");
- output ("ex -= $increment;\n");
- }
- else {
- output ("ell += lskip1;\n");
- }
- }
- else {
- if ($increment > 0) {
- comment ("advance pointers");
- output ("ell += $increment;\n");
- output ("ex += $increment;\n");
- }
- }
-
- if ($MADD==0) {
- for ($i=1; $i<=$M; $i++) {
- for ($j=1; $j<=$nrhs; $j++) {
- output ("Z$i$j += m$i$j;\n");
- }
- }
- }
-}
-
-
-sub computeRows # (nrhs,rows)
-{
- my $nrhs = $_[0];
- my $rows = $_[1];
- my ($i,$j,$k);
-
- comment ("compute all $rows x $nrhs block of X, from rows i..i+$rows-1");
-
- comment ("set the Z matrix to 0");
- for ($i=1; $i<=$rows; $i++) {
- for ($j=1; $j<=$nrhs; $j++) {
- output ("Z$i$j=0;\n");
- }
- }
- if ($TYPE eq 't') {
- output ("ell = L - i;\n");
- }
- else {
- output ("ell = L + i*lskip1;\n");
- }
- output ("ex = B;\n");
-
- comment ("the inner loop that computes outer products and adds them to Z");
- output ("for (j=i-$UNROLL1; j >= 0; j -= $UNROLL1) {\n");
- for ($k=0; $k < $UNROLL1; $k++) {
- innerOuterProductLoop ($rows,$k,$nrhs,($k==$UNROLL1-1) ? $UNROLL1 : 0);
- }
-
- comment ("end of inner loop");
- output ("}\n");
-
- if ($UNROLL1 > 1) {
- comment ("compute left-over iterations");
- output ("j += $UNROLL1;\n");
- output ("for (; j > 0; j--) {\n");
- innerOuterProductLoop ($rows,'0',$nrhs,1);
- output ("}\n");
- }
-
- comment ("finish computing the X(i) block");
-
- for ($j=1; $j<=$nrhs; $j++) {
- if ($TYPE eq 't') {
- output ("Z1$j = ex[".ofs1(-($j-1),'lskip')."] - Z1$j;\n");
- output ("ex[".ofs1(-($j-1),'lskip')."] = Z1$j;\n");
- }
- else {
- output ("Z1$j = ex[".ofs1($j-1,'lskip')."] - Z1$j;\n");
- output ("ex[".ofs1($j-1,'lskip')."] = Z1$j;\n");
- }
- }
-
- for ($i=2; $i<=$rows; $i++) {
- for ($j=1; $j<$i; $j++) {
- if ($TYPE eq 't') {
- output ("p$j = ell[".ofs2(-($i-1),$j-1,'lskip')."];\n");
- }
- else {
- output ("p$j = ell[".ofs2($j-1,$i-1,'lskip')."];\n");
- }
- }
- for ($j=1; $j<=$nrhs; $j++) {
- if ($TYPE eq 't') {
- output ("Z$i$j = ex[".ofs2(-($i-1),$j-1,'lskip')."] - Z$i$j");
- }
- else {
- output ("Z$i$j = ex[".ofs2($i-1,$j-1,'lskip')."] - Z$i$j");
- }
- for ($k=1; $k < $i; $k++) {
- output (" - p$k*Z$k$j");
- }
- output (";\n");
- if ($TYPE eq 't') {
- output ("ex[".ofs2(-($i-1),$j-1,'lskip')."] = Z$i$j;\n");
- }
- else {
- output ("ex[".ofs2($i-1,$j-1,'lskip')."] = Z$i$j;\n");
- }
- }
- }
-}
-
-
-sub makeFastL1Solve # ( number-of-right-hand-sides )
-{
- my $nrhs = $_[0];
- my ($i,$j,$k);
- my $funcsuffix = ($TYPE eq 'f') ? "_$nrhs" : '';
- my $staticvoid = ($TYPE eq 'f') ? 'static void' : 'void';
-
- # function header
- if ($TYPE eq 't') {
- output (<<END);
-
-/* solve L^T * x=b, with b containing 1 right hand side.
- * L is an n*n lower triangular matrix with ones on the diagonal.
- * L is stored by rows and its leading dimension is lskip.
- * b is an n*1 matrix that contains the right hand side.
- * b is overwritten with x.
- * this processes blocks of $N1.
- */
-
-void dSolveL1T (const dReal *L, dReal *B, int n, int lskip1)
-{
-END
- }
- else {
- output (<<END);
-
-/* solve L*X=B, with B containing $nrhs right hand sides.
- * L is an n*n lower triangular matrix with ones on the diagonal.
- * L is stored by rows and its leading dimension is lskip.
- * B is an n*$nrhs matrix that contains the right hand sides.
- * B is stored by columns and its leading dimension is also lskip.
- * B is overwritten with X.
- * this processes blocks of $N1*$N1.
- * if this is in the factorizer source file, n must be a multiple of $N1.
- */
-
-$staticvoid dSolveL1$funcsuffix (const dReal *L, dReal *B, int n, int lskip1)
-{
-END
- }
-
- comment ("declare variables - Z matrix, p and q vectors, etc");
- output ("dReal ");
- for ($i=1; $i<=$N1; $i++) {
- for ($j=1; $j<=$nrhs; $j++) {
- output ("Z$i$j,"); # Z matrix
- output ("m$i$j,") if ! $MADD; # temporary vars where multiplies put
- }
- }
- for ($i=1; $i<=$N1; $i++) {
- output ("p$i,");
- output ("q$i,") if $i <= $nrhs;
- }
- output ("*ex;\nconst dReal *ell;\n");
- output ("int ");
- for ($i=2; $i<$N1; $i++) {
- output ("lskip$i,");
- }
- output ("i,j;\n");
-
- if ($TYPE eq 't') {
- comment ("special handling for L and B because we're solving L1 *transpose*");
- output ("L = L + (n-1)*(lskip1+1);\n");
- output ("B = B + n-1;\n");
- output ("lskip1 = -lskip1;\n");
- }
-
- if ($N1 > 2) {
- comment ("compute lskip values");
- for ($i=2; $i<$N1; $i++) {
- output ("lskip$i = $i*lskip1;\n");
- }
- }
-
- comment ("compute all $N1 x $nrhs blocks of X");
- if ($TYPE eq 's' or $TYPE eq 't') {
- output ("for (i=0; i <= n-$N1; i+=$N1) {\n");
- }
- else {
- output ("for (i=0; i < n; i+=$N1) {\n");
- }
- computeRows ($nrhs,$N1);
- comment ("end of outer loop");
- output ("}\n");
-
- if ($TYPE eq 's' or $TYPE eq 't') {
- comment ("compute rows at end that are not a multiple of block size");
- output ("for (; i < n; i++) {\n");
- computeRows ($nrhs,1);
- output ("}\n");
- }
-
- output ("}\n");
-}
-
-#############################################################################
-# make a fast L*D*L' factorizer
-
-# code fragment: this factors an M x M block. if A_or_Z is 0 then it works
-# on the $A matrix otherwise it works on the Z matrix. in either case it
-# writes the diagonal entries into the `dee' vector.
-# it is a simple implementation of the LDLT algorithm, with no tricks.
-
-sub getA # (i,j,A,A_or_Z)
-{
- my $i = $_[0];
- my $j = $_[1];
- my $A = $_[2];
- return $_[3] ? ('Z'.($i+1).($j+1)) : ($A.'['.ofs2($j,$i,'nskip').']');
-}
-
-sub miniLDLT # (A,A_or_Z,M)
-{
- my ($i,$j,$k);
- my $A = $_[0];
- my $AZ = $_[1];
- my $M = $_[2];
- comment ("factorize $M x $M block " . ($AZ ? "Z,dee" : "$A,dee"));
- comment ("factorize row 1");
- output ("dee[0] = dRecip(".getA(0,0,$A,$AZ).");\n");
- for ($i=1; $i<$M; $i++) {
- comment ("factorize row ".($i+1));
- for ($j=1; $j<$i; $j++) {
- output (getA($i,$j,$A,$AZ)." -= ");
- for ($k=0; $k<$j; $k++) {
- output (" + ") if $k > 0;
- output (getA($i,$k,$A,$AZ)."*".getA($j,$k,$A,$AZ));
- }
- output (";\n");
- }
- output ("sum = 0;\n");
- for ($j=0; $j<$i; $j++) {
- output ("q1 = ".getA($i,$j,$A,$AZ).";\n");
- output ("q2 = q1 * dee[$j];\n");
- output (getA($i,$j,$A,$AZ)." = q2;\n");
- output ("sum += q1*q2;\n");
- }
- output ("dee[$i] = dRecip(".getA($i,$i,$A,$AZ)." - sum);\n");
- }
- comment ("done factorizing $M x $M block");
-}
-
-
-sub innerScaleAndOuterProductLoop # (M,k)
-{
- my $M = $_[0];
- my $k = $_[1];
- my ($i,$j);
- for ($i=1; $i<=$M; $i++) {
- output ("p$i = ell[".ofs2($k,$i-1,'nskip')."];\n");
- }
- output ("dd = dee[$k];\n");
- for ($i=1; $i<=$M; $i++) {
- output ("q$i = p$i*dd;\n");
- }
- for ($i=1; $i<=$M; $i++) {
- output ("ell[".ofs2($k,$i-1,'nskip')."] = q$i;\n");
- }
- for ($i=1; $i<=$M; $i++) {
- for ($j=1; $j<=$i; $j++) {
- my $var = $MADD ? "Z$i$j +=" : "m$i$j =";
- output ("$var p$i*q$j;\n");
- }
- }
- if ($MADD==0) {
- for ($i=1; $i<=$M; $i++) {
- for ($j=1; $j<=$i; $j++) {
- output ("Z$i$j += m$i$j;\n");
- }
- }
- }
-}
-
-
-sub diagRows # (M)
-{
- my $M=$_[0];
- comment ("scale the elements in a $M x i block at A(i,0), and also");
- comment ("compute Z = the outer product matrix that we'll need.");
- for ($i=1; $i<=$M; $i++) {
- for ($j=1; $j<=$i; $j++) {
- output ("Z$i$j = 0;\n");
- }
- }
- output ("ell = A+i*nskip1;\n");
- output ("dee = d;\n");
- output ("for (j=i-$UNROLL2; j >= 0; j -= $UNROLL2) {\n");
- for ($i=0; $i < $UNROLL2; $i++) {
- innerScaleAndOuterProductLoop ($M,$i);
- }
- output ("ell += $UNROLL2;\n");
- output ("dee += $UNROLL2;\n");
- output ("}\n");
-
- if ($UNROLL2 > 1) {
- comment ("compute left-over iterations");
- output ("j += $UNROLL2;\n");
- output ("for (; j > 0; j--) {\n");
- innerScaleAndOuterProductLoop ($M,0);
- output ("ell++;\n");
- output ("dee++;\n");
- output ("}\n");
- }
-}
-
-
-sub diagBlock # (M)
-{
- my $M = $_[0];
- comment ("solve for diagonal $M x $M block at A(i,i)");
- for ($i=1; $i<=$M; $i++) {
- for ($j=1; $j<=$i; $j++) {
- output ("Z$i$j = ell[".ofs2($j-1,$i-1,'nskip')."] - Z$i$j;\n");
- }
- }
- output ("dee = d + i;\n");
- miniLDLT ('',1,$M);
- for ($i=2; $i<=$M; $i++) {
- for ($j=1; $j<$i; $j++) {
- output ("ell[".ofs2($j-1,$i-1,'nskip')."] = Z$i$j;\n");
- }
- }
-}
-
-
-sub makeFastLDLT
-{
- my ($i,$j,$k);
-
- # function header
- output (<<END);
-
-
-void dFactorLDLT (dReal *A, dReal *d, int n, int nskip1)
-{
-END
- output ("int i,j");
- for ($i=2; $i<$N1; $i++) {
- output (",nskip$i");
- }
- output (";\n");
- output ("dReal sum,*ell,*dee,dd,p1,p2");
- for ($i=3; $i<=$N1; $i++) {
- output (",p$i");
- }
- for ($i=1; $i<=$N1; $i++) {
- output (",q$i");
- }
- for ($i=1; $i<=$N1; $i++) {
- for ($j=1; $j<=$i; $j++) {
- output (",Z$i$j");
- output (",m$i$j") if ! $MADD; # temporary vars where multiplies put
- }
- }
- output (";\n");
- output ("if (n < 1) return;\n");
- # output ("nskip1 = dPAD(n);\n"); ... not any more
- for ($i=2; $i<$N1; $i++) {
- output ("nskip$i = $i*nskip1;\n");
- }
-
- output ("\nfor (i=0; i<=n-$N1; i += $N1) {\n");
- comment ("solve L*(D*l)=a, l is scaled elements in $N1 x i block at A(i,0)");
- output ("dSolveL1_$N1 (A,A+i*nskip1,i,nskip1);\n");
-
- diagRows ($N1);
- diagBlock ($N1);
- output ("}\n");
-
- comment ("compute the (less than $N1) rows at the bottom");
- output ("switch (n-i) {\n");
- output ("case 0:\n");
- output ("break;\n\n");
-
- for ($i=1; $i<$N1; $i++) {
- output ("case $i:\n");
- output ("dSolveL1_$i (A,A+i*nskip1,i,nskip1);\n");
- diagRows ($i);
- diagBlock ($i);
- output ("break;\n\n");
- }
-
- output ("default: *((char*)0)=0; /* this should never happen! */\n");
- output ("}\n");
-
- output ("}\n");
-}
-
-#############################################################################
-# write source code
-
-open (FOUT,">$FNAME.c") or die "can't open $FNAME.c for writing";
-
-# file and function header
-output (<<END);
-/* generated code, do not edit. */
-
-#include "ode/matrix.h"
-END
-
-if ($TYPE eq 'f') {
- for ($i=1; $i <= $N1; $i++) {
- makeFastL1Solve ($i);
- }
- makeFastLDLT;
-}
-else {
- makeFastL1Solve (1);
- makeRealFastL1Solve;
-}
-close FOUT;
diff --git a/extern/ode/dist/ode/fbuild/BuildMultidot b/extern/ode/dist/ode/fbuild/BuildMultidot
deleted file mode 100644
index f6b117708c5..00000000000
--- a/extern/ode/dist/ode/fbuild/BuildMultidot
+++ /dev/null
@@ -1,174 +0,0 @@
-#!/usr/bin/perl
-#
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# multi-dot-product code generator. this code generator is based on the
-# dot-product code generator.
-#
-# code generation parameters, set in a parameters file:
-# FNAME : name of source file to generate - a .c file will be made
-# N1 : block size (number of `a' vectors to dot)
-# UNROLL1 : inner loop unrolling factor (1..)
-# FETCH : max num of a[i]'s and b[i]'s to load ahead of muls
-# LAT1 : load -> mul latency (>=1)
-# LAT2 : mul -> add latency (>=1). if this is 1, use fused mul-add
-#
-#############################################################################
-
-require ("BuildUtil");
-
-# get and check code generation parameters
-error ("Usage: BuildMultidot <parameters-file>") if $#ARGV != 0;
-do $ARGV[0];
-
-if (!defined($FNAME) || !defined($N1) || !defined($UNROLL1) ||
- !defined($FETCH) || !defined($LAT1) || !defined($LAT2)) {
- error ("code generation parameters not defined");
-}
-
-# check parameters
-error ("bad N1") if $N1 < 2;
-error ("bad UNROLL1") if $UNROLL1 < 1;
-error ("bad FETCH") if $FETCH < 1;
-error ("bad LAT1") if $LAT1 < 1;
-error ("bad LAT2") if $LAT2 < 1;
-
-#############################################################################
-
-open (FOUT,">$FNAME.c") or die "can't open $FNAME.c for writing";
-
-# file and function header
-output (<<END);
-/* generated code, do not edit. */
-
-#include "ode/matrix.h"
-
-
-END
-output ("void dMultidot$N1 (");
-for ($i=0; $i<$N1; $i++) {
- output ("const dReal *a$i, ");
-}
-output ("const dReal *b, dReal *outsum, int n)\n{\n");
-
-output ("dReal ");
-for ($i=0; $i<$UNROLL1; $i++) {
- for ($j=0; $j<$N1; $j++) {
- output ("p$i$j,");
- output ("m$i$j,") if $LAT2 > 1;
- }
- output ("q$i,");
-}
-for ($i=0; $i<$N1; $i++) {
- output ("sum$i");
- output (",") if $i < ($N1-1);
-}
-output (";\n");
-for ($i=0; $i<$N1; $i++) {
- output ("sum$i = 0;\n");
-}
-output (<<END);
-n -= $UNROLL1;
-while (n >= 0) {
-END
-
-@load = (); # slot where a[i]'s and b[i]'s loaded
-@mul = (); # slot where multiply i happened
-@add = (); # slow where add i happened
-
-for ($i=0; $i<$N1; $i++) {
- output ("p0$i = a$i [0];\n");
-}
-output ("q0 = b[0];\n");
-push (@load,0);
-
-$slot=0; # one slot for every load/mul/add/nop issued
-for (;;) {
- $startslot = $slot;
-
- # do next load
- if (($#load - $#mul) < $FETCH && ($#load+1) < $UNROLL1) {
- push (@load,$slot);
- for ($j=0; $j<$N1; $j++) {
- output ("p$#load$j = a$j [$#load];\n");
- }
- output ("q$#load = b[$#load];\n");
- $slot++;
- }
-
- # do next multiply
- if ($#load > $#mul && $slot >= ($load[$#mul+1] + $LAT1) &&
- ($#mul+1) < $UNROLL1) {
- push (@mul,$slot);
- if ($LAT2 > 1) {
- for ($j=0; $j<$N1; $j++) {
- output ("m$#mul$j = p$#mul$j * q$#mul;\n");
- }
- }
- else {
- for ($j=0; $j<$N1; $j++) {
- output ("sum$j += p$#mul$j * q$#mul;\n");
- }
- last if ($#mul+1) >= $UNROLL1;
- }
- $slot++;
- }
- # do next add
- if ($LAT2 > 1) {
- if ($#mul > $#add && $slot >= ($mul[$#add+1] + $LAT2)) {
- push (@add,$slot);
- for ($j=0; $j<$N1; $j++) {
- output ("sum$j += m$#add$j;\n");
- }
- $slot++;
- last if ($#add+1) >= $UNROLL1;
- }
- }
-
- if ($slot == $startslot) {
- # comment ("nop");
- $slot++;
- }
-}
-
-for ($j=0; $j<$N1; $j++) {
- output ("a$j += $UNROLL1;\n");
-}
-output ("b += $UNROLL1;\n");
-output ("n -= $UNROLL1;\n");
-output ("}\n");
-
-output ("n += $UNROLL1;\n");
-output ("while (n > 0) {\n");
-output ("q0 = *b;\n");
-for ($j=0; $j<$N1; $j++) {
- output ("sum$j += (*a$j) * q0;\n");
- output ("a$j++;\n");
-}
-output ("b++;\n");
-output ("n--;\n");
-output ("}\n");
-for ($j=0; $j<$N1; $j++) {
- output ("outsum[$j] = sum$j;\n");
-}
-output ("}\n");
diff --git a/extern/ode/dist/ode/fbuild/BuildUtil b/extern/ode/dist/ode/fbuild/BuildUtil
deleted file mode 100644
index b0828ff5ec1..00000000000
--- a/extern/ode/dist/ode/fbuild/BuildUtil
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/perl -w
-#
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-package BuildUtil;
-
-
-# print out code. after newlines, indent according to the number of curly
-# brackets we've seen
-
-my $indent = 0;
-my $startofline = 1;
-
-
-sub main::output
-{
- my $line = $_[0];
- my ($i,$j,$c);
- for ($i=0; $i < length ($line); $i++) {
- $c = substr ($line,$i,1);
- print main::FOUT $c if $c eq '{';
- $indent++ if $c eq '{';
- $indent-- if $c eq '}';
- if ($startofline) {
- for ($j=0; $j < $indent; $j++) {
- print main::FOUT " ";
- }
- $startofline = 0;
- }
- print main::FOUT $c if $c ne '{';
- $startofline = 1 if $c eq "\n";
- }
-}
-
-
-# write a C comment with the correct indenting
-
-sub main::comment
-{
- main::output ("/* $_[0] */\n");
-}
-
-
-# return an offset: N*skip = skipN where N=0,1,2,...
-
-sub main::ofs1 # (N,skip)
-{
- my $N = $_[0];
- my $skip = $_[1];
- return '0' if $N==0;
- return $skip . $N;
-}
-
-
-# return an offset: M+N*skip = M+skipN where N=0,1,2,...
-
-sub main::ofs2 # (M,N,skip)
-{
- my $M = $_[0];
- my $N = $_[1];
- my $skip = $_[2];
- $M = '0' if $M eq '-0';
- my $a = $M;
- $a .= '+' . $skip . $N if ($N > 0);
- substr ($a,0,2)='' if substr ($a,0,2) eq '0+';
- return $a;
-}
-
-
-# print an error message and exit
-
-sub main::error
-{
- print "ERROR: $_[0]\n";
- exit 1;
-}
-
-
-1;
diff --git a/extern/ode/dist/ode/fbuild/Dependencies b/extern/ode/dist/ode/fbuild/Dependencies
deleted file mode 100644
index 86f5cd4417b..00000000000
--- a/extern/ode/dist/ode/fbuild/Dependencies
+++ /dev/null
@@ -1,16 +0,0 @@
-test_dot.o: test_dot.cpp ../../include/ode/ode.h \
- ../../include/ode/config.h ../../include/ode/contact.h \
- ../../include/ode/common.h ../../include/ode/error.h \
- ../../include/ode/memory.h ../../include/ode/odemath.h \
- ../../include/ode/matrix.h ../../include/ode/timer.h \
- ../../include/ode/rotation.h ../../include/ode/mass.h \
- ../../include/ode/space.h ../../include/ode/geom.h \
- ../../include/ode/misc.h
-test_ldlt.o: test_ldlt.cpp ../../include/ode/ode.h \
- ../../include/ode/config.h ../../include/ode/contact.h \
- ../../include/ode/common.h ../../include/ode/error.h \
- ../../include/ode/memory.h ../../include/ode/odemath.h \
- ../../include/ode/matrix.h ../../include/ode/timer.h \
- ../../include/ode/rotation.h ../../include/ode/mass.h \
- ../../include/ode/space.h ../../include/ode/geom.h \
- ../../include/ode/misc.h
diff --git a/extern/ode/dist/ode/fbuild/Makefile b/extern/ode/dist/ode/fbuild/Makefile
deleted file mode 100644
index f988c3739af..00000000000
--- a/extern/ode/dist/ode/fbuild/Makefile
+++ /dev/null
@@ -1,77 +0,0 @@
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# currently this only works under linux, and it's a bit of a mess!
-
-MAKEFILE_INC=../../build/Makefile.inc
-include $(MAKEFILE_INC)
-
-INCLUDE_PATHS=../../include
-LIB_PATHS = ../../lib
-DEFINES=dDOUBLE
-
-SOURCES_CPP=test_ldlt.cpp
-SOURCES_C=fastldlt.c fastlsolve.c fastltsolve.c
-APPS=$(call fEXENAME,test_ldlt) $(call fEXENAME,test_dot) $(call fEXENAME,test_multidot)
-EXTRA_CLEAN=test_ldlt test_dot test_multidot fastldlt.c fastlsolve.c fastltsolve.c fastdot.c fastmultidot.c
-
-
-all: $(APPS)
-
-$(call fEXENAME,test_ldlt): $(call fTARGETS,$(SOURCES_CPP) $(SOURCES_C))
- gcc -o $@ $^ -L $(LIB_PATHS) $(call fLIB,ode) -lm
-
-$(call fEXENAME,test_dot): test_dot.o fastdot.o
- gcc -o $@ test_dot.o fastdot.o -L $(LIB_PATHS) $(call fLIB,ode) -lm
-
-$(call fEXENAME,test_multidot): test_multidot.o fastmultidot.o
- gcc -o $@ test_multidot.o fastmultidot.o -L $(LIB_PATHS) $(call fLIB,ode) -lm
-
-fastldlt.o: fastldlt.c
- gcc -O1 -I$(INCLUDE_PATHS) -ffast-math -fomit-frame-pointer -c -D$(DEFINES) $<
-
-fastlsolve.o: fastlsolve.c
- gcc -O1 -I$(INCLUDE_PATHS) -ffast-math -fomit-frame-pointer -c -D$(DEFINES) $<
-
-fastltsolve.o: fastltsolve.c
- gcc -O1 -I$(INCLUDE_PATHS) -ffast-math -fomit-frame-pointer -c -D$(DEFINES) $<
-
-fastdot.o: fastdot.c
- gcc -O1 -I$(INCLUDE_PATHS) -ffast-math -fomit-frame-pointer -c -D$(DEFINES) $<
-
-fastmultidot.o: fastmultidot.c
- gcc -O1 -I$(INCLUDE_PATHS) -ffast-math -fomit-frame-pointer -c -D$(DEFINES) $<
-
-fastldlt.c: BuildLDLT BuildUtil ParametersF
- ./BuildLDLT ParametersF
-
-fastlsolve.c: BuildLDLT BuildUtil ParametersS
- ./BuildLDLT ParametersS
-
-fastltsolve.c: BuildLDLT BuildUtil ParametersT
- ./BuildLDLT ParametersT
-
-fastdot.c: BuildDot BuildUtil ParametersD
- ./BuildDot ParametersD
-
-fastmultidot.c: BuildMultidot BuildUtil ParametersM
- ./BuildMultidot ParametersM
diff --git a/extern/ode/dist/ode/fbuild/OptimizeDot b/extern/ode/dist/ode/fbuild/OptimizeDot
deleted file mode 100644
index 1dc178262aa..00000000000
--- a/extern/ode/dist/ode/fbuild/OptimizeDot
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/perl
-#
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# optimize the dot product built by BuildDot
-
-##############################################################################
-
-require ("OptimizeUtil");
-
-# unused standard parameters
-$TYPE='unused';
-$N1=0; # unused
-$UNROLL2=0; # unused
-$MADD=0; # unused
-
-##############################################################################
-
-sub testDot # (filename)
-{
- my $filename = $_[0];
- createParametersFile ('ParametersD');
- $params = "$N1 $UNROLL1 $UNROLL2 $MADD $FETCH $LAT1 $LAT2";
- print "***** TESTING $params\n";
- doit ("rm -f fastdot.c fastdot.o test_dot");
- doit ("make test_dot");
- doit ("./test_dot >> $filename");
- open (FILE,">>$filename");
- print FILE " $params\n";
- close FILE;
-}
-
-# find optimal parameters. write results to data4.txt
-
-open (FILE,">data4.txt");
-print FILE "# dot product data from OptimizeDot\n";
-close FILE;
-$FNAME='fastdot';
-
-for ($UNROLL1=1; $UNROLL1 <= 10; $UNROLL1++) {
- for ($LAT1=1; $LAT1 <= 5; $LAT1++) {
- for ($LAT2=1; $LAT2 <= 5; $LAT2++) {
- for ($FETCH=1; $FETCH<=5; $FETCH++) {
- testDot ('data4.txt');
- }
- }
- }
-}
-
-readBackDataFile ('data4.txt');
-createParametersFile ('ParametersD');
diff --git a/extern/ode/dist/ode/fbuild/OptimizeLDLT b/extern/ode/dist/ode/fbuild/OptimizeLDLT
deleted file mode 100644
index 612633e00c2..00000000000
--- a/extern/ode/dist/ode/fbuild/OptimizeLDLT
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/perl
-#
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# optimize the factorizer built by BuildLDLT
-#
-# FNAME : name of source file to generate - .h and .c files will be made
-# N1 : block size (size of outer product matrix) (1..9)
-# UNROLL1 : solver inner loop unrolling factor (1..)
-# UNROLL2 : factorizer inner loop unrolling factor (1..)
-# MADD : if nonzero, generate code for fused multiply-add (0,1)
-# FETCH : how to fetch data in the inner loop:
-# 0 - load in a batch (the `normal way')
-# 1 - delay inner loop loads until just before they're needed
-
-##############################################################################
-
-require ("OptimizeUtil");
-
-##############################################################################
-# optimize factorizer
-
-sub testFactorizer # (filename)
-{
- my $filename = $_[0];
- createParametersFile ('ParametersF');
- $params = "$N1 $UNROLL1 $UNROLL2 $MADD $FETCH";
- print "***** TESTING $params\n";
- doit ("rm -f fastldlt.c fastldlt.o test_ldlt");
- doit ("make test_ldlt");
- doit ("./test_ldlt f >> $filename");
- open (FILE,">>$filename");
- print FILE " $params\n";
- close FILE;
-}
-
-
-# first find optimal parameters ignoring UNROLL1 and UNROLL2, write results
-# to data1.txt
-
-open (FILE,">data1.txt");
-print FILE "# factorizer data from OptimizeLDLT\n";
-close FILE;
-$FNAME='fastldlt';
-$TYPE='f';
-$UNROLL1=4;
-$UNROLL2=4;
-for ($N1=1; $N1 <= 4; $N1++) {
- for ($MADD=0; $MADD<=1; $MADD++) {
- for ($FETCH=0; $FETCH<=1; $FETCH++) {
- testFactorizer ('data1.txt');
- }
- }
-}
-
-readBackDataFile ('data1.txt');
-createParametersFile ('ParametersF');
-
-# now find optimal UNROLL1 and UNROLL2 values, write results to data2.txt
-
-open (FILE,">data2.txt");
-print FILE "# factorizer data from OptimizeLDLT\n";
-close FILE;
-for ($UNROLL1=1; $UNROLL1 <= 10; $UNROLL1++) {
- for ($UNROLL2=1; $UNROLL2 <= 10; $UNROLL2++) {
- testFactorizer ('data2.txt');
- }
-}
-
-readBackDataFile ('data2.txt');
-createParametersFile ('ParametersF');
diff --git a/extern/ode/dist/ode/fbuild/OptimizeLSolve b/extern/ode/dist/ode/fbuild/OptimizeLSolve
deleted file mode 100644
index bba6b495f2c..00000000000
--- a/extern/ode/dist/ode/fbuild/OptimizeLSolve
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/perl
-#
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# optimize the solver built by BuildLDLT
-#
-# FNAME : name of source file to generate - .h and .c files will be made
-# N1 : block size (size of outer product matrix) (1..9)
-# UNROLL1 : solver inner loop unrolling factor (1..)
-# UNROLL2 : factorizer inner loop unrolling factor (1..)
-# MADD : if nonzero, generate code for fused multiply-add (0,1)
-# FETCH : how to fetch data in the inner loop:
-# 0 - load in a batch (the `normal way')
-# 1 - delay inner loop loads until just before they're needed
-
-##############################################################################
-
-require ("OptimizeUtil");
-
-##############################################################################
-# optimize solver
-
-sub testSolver # (filename)
-{
- my $filename = $_[0];
- createParametersFile ('ParametersS');
- $params = "$N1 $UNROLL1 $UNROLL2 $MADD $FETCH";
- print "***** TESTING $params\n";
- doit ("rm -f fastlsolve.c fastlsolve.o test_ldlt");
- doit ("make test_ldlt");
- doit ("./test_ldlt s >> $filename");
- open (FILE,">>$filename");
- print FILE " $params\n";
- close FILE;
-}
-
-# find optimal parameters. UNROLL2 has no effect. write results to data3.txt
-
-open (FILE,">data3.txt");
-print FILE "# solver data from OptimizeLDLT\n";
-close FILE;
-$FNAME='fastlsolve';
-$TYPE='s';
-$UNROLL2=1;
-for ($N1=1; $N1 <= 5; $N1++) {
- for ($UNROLL1=1; $UNROLL1 <= 15; $UNROLL1++) {
- for ($MADD=0; $MADD<=1; $MADD++) {
- for ($FETCH=0; $FETCH<=1; $FETCH++) {
- testSolver ('data3.txt');
- }
- }
- }
-}
-
-readBackDataFile ('data3.txt');
-createParametersFile ('ParametersS');
diff --git a/extern/ode/dist/ode/fbuild/OptimizeLTSolve b/extern/ode/dist/ode/fbuild/OptimizeLTSolve
deleted file mode 100644
index a10109e2d2c..00000000000
--- a/extern/ode/dist/ode/fbuild/OptimizeLTSolve
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/perl
-#
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# optimize the transpose solver built by BuildLDLT
-#
-# FNAME : name of source file to generate - .h and .c files will be made
-# N1 : block size (size of outer product matrix) (1..9)
-# UNROLL1 : solver inner loop unrolling factor (1..)
-# UNROLL2 : factorizer inner loop unrolling factor (1..)
-# MADD : if nonzero, generate code for fused multiply-add (0,1)
-# FETCH : how to fetch data in the inner loop:
-# 0 - load in a batch (the `normal way')
-# 1 - delay inner loop loads until just before they're needed
-
-##############################################################################
-
-require ("OptimizeUtil");
-
-##############################################################################
-# optimize solver
-
-sub testSolver # (filename)
-{
- my $filename = $_[0];
- createParametersFile ('ParametersT');
- $params = "$N1 $UNROLL1 $UNROLL2 $MADD $FETCH";
- print "***** TESTING $params\n";
- doit ("rm -f fastltsolve.c fastltsolve.o test_ldlt");
- doit ("make test_ldlt");
- doit ("./test_ldlt t >> $filename");
- open (FILE,">>$filename");
- print FILE " $params\n";
- close FILE;
-}
-
-# find optimal parameters. UNROLL2 has no effect. write results to data5.txt
-
-open (FILE,">data5.txt");
-print FILE "# solver data from OptimizeLDLT\n";
-close FILE;
-$FNAME='fastltsolve';
-$TYPE='t';
-$UNROLL2=1;
-for ($N1=1; $N1 <= 5; $N1++) {
- for ($UNROLL1=1; $UNROLL1 <= 15; $UNROLL1++) {
- for ($MADD=0; $MADD<=1; $MADD++) {
- for ($FETCH=0; $FETCH<=1; $FETCH++) {
- testSolver ('data5.txt');
- }
- }
- }
-}
-
-readBackDataFile ('data5.txt');
-createParametersFile ('ParametersT');
diff --git a/extern/ode/dist/ode/fbuild/OptimizeMultidot b/extern/ode/dist/ode/fbuild/OptimizeMultidot
deleted file mode 100644
index f2b54383312..00000000000
--- a/extern/ode/dist/ode/fbuild/OptimizeMultidot
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/perl
-#
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# optimize the dot product built by BuildMultidot
-
-##############################################################################
-
-require ("OptimizeUtil");
-
-# multiple
-$N1=2;
-
-# unused standard parameters
-$TYPE='unused';
-$UNROLL2=0; # unused
-$MADD=0; # unused
-
-##############################################################################
-
-sub testMultidot # (filename)
-{
- my $filename = $_[0];
- createParametersFile ('ParametersM');
- $params = "$N1 $UNROLL1 $UNROLL2 $MADD $FETCH $LAT1 $LAT2";
- print "***** TESTING $params\n";
- doit ("rm -f fastmultidot.c fastmultidot.o test_multidot");
- doit ("make test_multidot");
- doit ("./test_multidot >> $filename");
- open (FILE,">>$filename");
- print FILE " $params\n";
- close FILE;
-}
-
-# find optimal parameters. write results to data6.txt
-
-open (FILE,">data6.txt");
-print FILE "# multi-dot product data from OptimizeMultidot\n";
-close FILE;
-$FNAME='fastmultidot';
-
-for ($UNROLL1=1; $UNROLL1 <= 10; $UNROLL1++) {
- for ($LAT1=1; $LAT1 <= 5; $LAT1++) {
- for ($LAT2=1; $LAT2 <= 5; $LAT2++) {
- for ($FETCH=1; $FETCH<=5; $FETCH++) {
- testMultidot ('data6.txt');
- }
- }
- }
-}
-
-readBackDataFile ('data6.txt');
-createParametersFile ('ParametersM');
diff --git a/extern/ode/dist/ode/fbuild/OptimizeUtil b/extern/ode/dist/ode/fbuild/OptimizeUtil
deleted file mode 100644
index 2b882fcba65..00000000000
--- a/extern/ode/dist/ode/fbuild/OptimizeUtil
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/perl -w
-#
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-package BuildUtil;
-
-
-sub main::doit
-{
- my $cmd = $_[0];
- print "$cmd\n";
- system ($cmd)==0 or die "FAILED";
-}
-
-
-sub main::createParametersFile # (filename)
-{
- open (PARAM,">$_[0]");
- print PARAM "# perl script to set parameters required by the code generator\n";
- print PARAM "\$FNAME=\"$main::FNAME\";\n" if defined($main::FNAME);
- print PARAM "\$TYPE=\"$main::TYPE\";\n" if defined($main::TYPE);
- print PARAM "\$N1=$main::N1;\n" if defined($main::N1);
- print PARAM "\$UNROLL1=$main::UNROLL1;\n" if defined($main::UNROLL1);
- print PARAM "\$UNROLL2=$main::UNROLL2;\n" if defined($main::UNROLL2);
- print PARAM "\$MADD=$main::MADD;\n" if defined($main::MADD);
- print PARAM "\$FETCH=$main::FETCH;\n" if defined($main::FETCH);
- print PARAM "\$LAT1=$main::LAT1;\n" if defined($main::LAT1);
- print PARAM "\$LAT2=$main::LAT2;\n" if defined($main::LAT2);
- close PARAM;
-}
-
-
-# read back a data file and find best parameters
-
-sub main::readBackDataFile # (filename)
-{
- my $filename = $_[0];
- my $maxtime = 1e10;
- open (FILE,$filename);
- while (<FILE>) {
- next if /^\#/;
- my $line = lc $_;
- if ($line =~ /error/) {
- print "ERRORS FOUND IN $filename\n";
- exit 1;
- }
- $line =~ s/^\s*//;
- $line =~ s/\s*$//;
- my @nums = split (/\s+/,$line);
- $time = $nums[0];
- if ($time < $maxtime) {
- $main::N1 = $nums[1];
- $main::UNROLL1 = $nums[2];
- $main::UNROLL2 = $nums[3];
- $main::MADD = $nums[4];
- $main::FETCH = $nums[5];
- $main::LAT1 = $nums[6];
- $main::LAT2 = $nums[7];
- $maxtime = $time;
- }
- }
- close FILE;
-}
-
-
-1;
diff --git a/extern/ode/dist/ode/fbuild/ParametersD.example b/extern/ode/dist/ode/fbuild/ParametersD.example
deleted file mode 100644
index e58f279f7d7..00000000000
--- a/extern/ode/dist/ode/fbuild/ParametersD.example
+++ /dev/null
@@ -1,32 +0,0 @@
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# perl script to set parameters required by the code generator
-$FNAME="fastdot";
-$TYPE="unused";
-$N1=0;
-$UNROLL1=2;
-$UNROLL2=0;
-$MADD=0;
-$FETCH=1;
-$LAT1=1;
-$LAT2=2;
diff --git a/extern/ode/dist/ode/fbuild/ParametersF.example b/extern/ode/dist/ode/fbuild/ParametersF.example
deleted file mode 100644
index 9881b09ad81..00000000000
--- a/extern/ode/dist/ode/fbuild/ParametersF.example
+++ /dev/null
@@ -1,30 +0,0 @@
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# perl script to set parameters required by the code generator
-$FNAME="fastldlt";
-$TYPE="f";
-$N1=2;
-$UNROLL1=2;
-$UNROLL2=6;
-$MADD=0;
-$FETCH=1;
diff --git a/extern/ode/dist/ode/fbuild/ParametersM.example b/extern/ode/dist/ode/fbuild/ParametersM.example
deleted file mode 100644
index bb81d6b83f1..00000000000
--- a/extern/ode/dist/ode/fbuild/ParametersM.example
+++ /dev/null
@@ -1,32 +0,0 @@
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# perl script to set parameters required by the code generator
-$FNAME="fastmultidot";
-$TYPE="unused";
-$N1=2;
-$UNROLL1=1;
-$UNROLL2=0;
-$MADD=0;
-$FETCH=5;
-$LAT1=1;
-$LAT2=1;
diff --git a/extern/ode/dist/ode/fbuild/ParametersS.example b/extern/ode/dist/ode/fbuild/ParametersS.example
deleted file mode 100644
index 29c9a91fc16..00000000000
--- a/extern/ode/dist/ode/fbuild/ParametersS.example
+++ /dev/null
@@ -1,30 +0,0 @@
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# perl script to set parameters required by the code generator
-$FNAME="fastlsolve";
-$TYPE="s";
-$N1=4;
-$UNROLL1=12;
-$UNROLL2=1;
-$MADD=1;
-$FETCH=0;
diff --git a/extern/ode/dist/ode/fbuild/ParametersT.example b/extern/ode/dist/ode/fbuild/ParametersT.example
deleted file mode 100644
index 3aa92a31dd2..00000000000
--- a/extern/ode/dist/ode/fbuild/ParametersT.example
+++ /dev/null
@@ -1,30 +0,0 @@
-#########################################################################
-# #
-# Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. #
-# All rights reserved. Email: russ@q12.org Web: www.q12.org #
-# #
-# This library is free software; you can redistribute it and/or #
-# modify it under the terms of EITHER: #
-# (1) The GNU Lesser General Public License as published by the Free #
-# Software Foundation; either version 2.1 of the License, or (at #
-# your option) any later version. The text of the GNU Lesser #
-# General Public License is included with this library in the #
-# file LICENSE.TXT. #
-# (2) The BSD-style license that is included with this library in #
-# the file LICENSE-BSD.TXT. #
-# #
-# This library 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 files #
-# LICENSE.TXT and LICENSE-BSD.TXT for more details. #
-# #
-#########################################################################
-
-# perl script to set parameters required by the code generator
-$FNAME="fastltsolve";
-$TYPE="t";
-$N1=4;
-$UNROLL1=12;
-$UNROLL2=1;
-$MADD=1;
-$FETCH=0;
diff --git a/extern/ode/dist/ode/fbuild/README b/extern/ode/dist/ode/fbuild/README
deleted file mode 100644
index bcf7f5aa8b5..00000000000
--- a/extern/ode/dist/ode/fbuild/README
+++ /dev/null
@@ -1,41 +0,0 @@
-
-factorizer/solver builder
-
-before running `make', copy the following files:
- ParametersD.example --> ParametersD
- ParametersF.example --> ParametersF
- ParametersS.example --> ParametersS
-
-the files Parameters[D|F|S] don't exist in the CVS archive because
-they are changable.
-
-
-
-STATS - for chol
------
-
-* all with -O1
-
-128x128 matrix
-atlas = 1724779 clocks
-my chol = 1164629 clocks (parameters: 2 2 2 1) with Ai++, Aj++
-my chol = 1140786 clocks (parameters: 2 6 8 0) with Ai++, Aj++
-my chol = 1118968 clocks (parameters: 2 6 8 0) with +ofs
-
-64x64 matrix
-atlas = 374020 clocks
-my chol = 157076 clocks (parameters = 2 2 2 1)
-
-32x32 matrix (12961 flops)
-atlas = 83827 clocks
-my chol = 25945 clocks (parameters: 2 2 2 1)
-
-
-
-
-TODO
-----
-
-* doc!
-
-* iterate blocks by partial rows to try and keep more data in cache
diff --git a/extern/ode/dist/ode/fbuild/ldlt.m b/extern/ode/dist/ode/fbuild/ldlt.m
deleted file mode 100644
index 19ae2d1c94e..00000000000
--- a/extern/ode/dist/ode/fbuild/ldlt.m
+++ /dev/null
@@ -1,26 +0,0 @@
-function [L,d] = ldlt(A)
-
-n=length(A);
-d=zeros(n,1);
-
-d(1) = 1/A(1,1);
-for i=2:n
- for j=2:i-1
- A(i,j) = A(i,j) - A(j,1:j-1) * A(i,1:j-1)';
- end
- sum = 0;
- for j=1:i-1
- q1 = A(i,j);
- q2 = q1 * d(j);
- A(i,j) = q2;
- sum = sum + q1*q2;
- end
- d(i) = 1/(A(i,i) - sum);
-end
-
-L=A;
-for i=1:n
- L(i,i:n)=zeros(1,n+1-i);
- L(i,i)=1;
-end
-d = d .\ 1;
diff --git a/extern/ode/dist/ode/fbuild/test_dot.cpp b/extern/ode/dist/ode/fbuild/test_dot.cpp
deleted file mode 100644
index 62aec32e509..00000000000
--- a/extern/ode/dist/ode/fbuild/test_dot.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <stdio.h>
-#include "ode/ode.h"
-
-#define ALLOCA dALLOCA16
-#define SIZE 1000
-
-
-// correct dot product, for accuracy testing
-
-dReal goodDot (dReal *a, dReal *b, int n)
-{
- dReal sum=0;
- while (n > 0) {
- sum += (*a) * (*b);
- a++;
- b++;
- n--;
- }
- return sum;
-}
-
-
-// test dot product accuracy
-
-void testAccuracy()
-{
- // allocate vectors a and b and fill them with random data
- dReal *a = (dReal*) ALLOCA (SIZE*sizeof(dReal));
- dReal *b = (dReal*) ALLOCA (SIZE*sizeof(dReal));
- dMakeRandomMatrix (a,1,SIZE,1.0);
- dMakeRandomMatrix (b,1,SIZE,1.0);
-
- for (int n=1; n<100; n++) {
- dReal good = goodDot (a,b,n);
- dReal test = dDot (a,b,n);
- dReal diff = fabs(good-test);
- //printf ("diff = %e\n",diff);
- if (diff > 1e-10) printf ("ERROR: accuracy test failed\n");
- }
-}
-
-
-// test dot product factorizer speed.
-
-void testSpeed()
-{
- // allocate vectors a and b and fill them with random data
- dReal *a = (dReal*) ALLOCA (SIZE*sizeof(dReal));
- dReal *b = (dReal*) ALLOCA (SIZE*sizeof(dReal));
- dMakeRandomMatrix (a,1,SIZE,1.0);
- dMakeRandomMatrix (b,1,SIZE,1.0);
-
- // time several dot products, return the minimum timing
- double mintime = 1e100;
- dStopwatch sw;
- for (int i=0; i<1000; i++) {
- dStopwatchReset (&sw);
- dStopwatchStart (&sw);
-
- // try a bunch of prime sizes up to 101
- dDot (a,b,2);
- dDot (a,b,3);
- dDot (a,b,5);
- dDot (a,b,7);
- dDot (a,b,11);
- dDot (a,b,13);
- dDot (a,b,17);
- dDot (a,b,19);
- dDot (a,b,23);
- dDot (a,b,29);
- dDot (a,b,31);
- dDot (a,b,37);
- dDot (a,b,41);
- dDot (a,b,43);
- dDot (a,b,47);
- dDot (a,b,53);
- dDot (a,b,59);
- dDot (a,b,61);
- dDot (a,b,67);
- dDot (a,b,71);
- dDot (a,b,73);
- dDot (a,b,79);
- dDot (a,b,83);
- dDot (a,b,89);
- dDot (a,b,97);
- dDot (a,b,101);
-
- dStopwatchStop (&sw);
- double time = dStopwatchTime (&sw);
- if (time < mintime) mintime = time;
- }
-
- printf ("%.0f",mintime * dTimerTicksPerSecond());
-}
-
-
-int main()
-{
- testAccuracy();
- testSpeed();
- return 0;
-}
diff --git a/extern/ode/dist/ode/fbuild/test_ldlt.cpp b/extern/ode/dist/ode/fbuild/test_ldlt.cpp
deleted file mode 100644
index 3b795b9ee7f..00000000000
--- a/extern/ode/dist/ode/fbuild/test_ldlt.cpp
+++ /dev/null
@@ -1,299 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <stdio.h>
-#include <malloc.h>
-#include "ode/ode.h"
-
-#define ALLOCA dALLOCA16
-
-//****************************************************************************
-// constants
-
-#ifdef dSINGLE
-#define TOL (1e-4)
-#else
-#define TOL (1e-10)
-#endif
-
-//****************************************************************************
-// test L*X=B solver accuracy.
-
-void testSolverAccuracy (int n)
-{
- int i;
- int npad = dPAD(n);
- dReal *L = (dReal*) ALLOCA (n*npad*sizeof(dReal));
- dReal *B = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *B2 = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *X = (dReal*) ALLOCA (n*sizeof(dReal));
-
- // L is a random lower triangular matrix with 1's on the diagonal
- dMakeRandomMatrix (L,n,n,1.0);
- dClearUpperTriangle (L,n);
- for (i=0; i<n; i++) L[i*npad+i] = 1;
-
- // B is the right hand side
- dMakeRandomMatrix (B,n,1,1.0);
- memcpy (X,B,n*sizeof(dReal)); // copy B to X
-
- dSolveL1 (L,X,n,npad);
-
- /*
- dPrintMatrix (L,n,n);
- printf ("\n");
- dPrintMatrix (B,n,1);
- printf ("\n");
- dPrintMatrix (X,n,1);
- printf ("\n");
- */
-
- dSetZero (B2,n);
- dMultiply0 (B2,L,X,n,n,1);
- dReal error = dMaxDifference (B,B2,1,n);
- if (error > TOL) {
- printf ("error = %e, size = %d\n",error,n);
- }
-}
-
-//****************************************************************************
-// test L^T*X=B solver accuracy.
-
-void testTransposeSolverAccuracy (int n)
-{
- int i;
- int npad = dPAD(n);
- dReal *L = (dReal*) ALLOCA (n*npad*sizeof(dReal));
- dReal *B = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *B2 = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *X = (dReal*) ALLOCA (n*sizeof(dReal));
-
- // L is a random lower triangular matrix with 1's on the diagonal
- dMakeRandomMatrix (L,n,n,1.0);
- dClearUpperTriangle (L,n);
- for (i=0; i<n; i++) L[i*npad+i] = 1;
-
- // B is the right hand side
- dMakeRandomMatrix (B,n,1,1.0);
- memcpy (X,B,n*sizeof(dReal)); // copy B to X
-
- dSolveL1T (L,X,n,npad);
-
- dSetZero (B2,n);
- dMultiply1 (B2,L,X,n,n,1);
- dReal error = dMaxDifference (B,B2,1,n);
- if (error > TOL) {
- printf ("error = %e, size = %d\n",error,n);
- }
-}
-
-//****************************************************************************
-// test L*D*L' factorizer accuracy.
-
-void testLDLTAccuracy (int n)
-{
- int i,j;
- int npad = dPAD(n);
- dReal *A = (dReal*) ALLOCA (n*npad*sizeof(dReal));
- dReal *L = (dReal*) ALLOCA (n*npad*sizeof(dReal));
- dReal *d = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *Atest = (dReal*) ALLOCA (n*npad*sizeof(dReal));
- dReal *DL = (dReal*) ALLOCA (n*npad*sizeof(dReal));
-
- dMakeRandomMatrix (A,n,n,1.0);
- dMultiply2 (L,A,A,n,n,n);
- memcpy (A,L,n*npad*sizeof(dReal));
- dSetZero (d,n);
-
- dFactorLDLT (L,d,n,npad);
-
- // make L lower triangular, and convert d into diagonal of D
- dClearUpperTriangle (L,n);
- for (i=0; i<n; i++) L[i*npad+i] = 1;
- for (i=0; i<n; i++) d[i] = 1.0/d[i];
-
- // form Atest = L*D*L'
- dSetZero (Atest,n*npad);
- dSetZero (DL,n*npad);
- for (i=0; i<n; i++) {
- for (j=0; j<n; j++) DL[i*npad+j] = L[i*npad+j] * d[j];
- }
- dMultiply2 (Atest,L,DL,n,n,n);
- dReal error = dMaxDifference (A,Atest,n,n);
- if (error > TOL) {
- printf ("error = %e, size = %d\n",error,n);
- }
-
- /*
- printf ("\n");
- dPrintMatrix (A,n,n);
- printf ("\n");
- dPrintMatrix (L,n,n);
- printf ("\n");
- dPrintMatrix (d,1,n);
- */
-}
-
-//****************************************************************************
-// test L*D*L' factorizer speed.
-
-void testLDLTSpeed (int n)
-{
- int npad = dPAD(n);
-
- // allocate A
- dReal *A = (dReal*) ALLOCA (n*npad*sizeof(dReal));
-
- // make B a symmetric positive definite matrix
- dMakeRandomMatrix (A,n,n,1.0);
- dReal *B = (dReal*) ALLOCA (n*npad*sizeof(dReal));
- dSetZero (B,n*npad);
- dMultiply2 (B,A,A,n,n,n);
-
- // make d
- dReal *d = (dReal*) ALLOCA (n*sizeof(dReal));
- dSetZero (d,n);
-
- // time several factorizations, return the minimum timing
- double mintime = 1e100;
- dStopwatch sw;
- for (int i=0; i<100; i++) {
- memcpy (A,B,n*npad*sizeof(dReal));
- dStopwatchReset (&sw);
- dStopwatchStart (&sw);
-
- dFactorLDLT (A,d,n,npad);
-
- dStopwatchStop (&sw);
- double time = dStopwatchTime (&sw);
- if (time < mintime) mintime = time;
- }
-
- printf ("%.0f",mintime * dTimerTicksPerSecond());
-}
-
-//****************************************************************************
-// test solver speed.
-
-void testSolverSpeed (int n, int transpose)
-{
- int i;
- int npad = dPAD(n);
-
- // allocate L,B,X
- dReal *L = (dReal*) ALLOCA (n*npad*sizeof(dReal));
- dReal *B = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *X = (dReal*) ALLOCA (n*sizeof(dReal));
-
- // L is a random lower triangular matrix with 1's on the diagonal
- dMakeRandomMatrix (L,n,n,1.0);
- dClearUpperTriangle (L,n);
- for (i=0; i<n; i++) L[i*npad+i] = 1;
-
- // B is the right hand side
- dMakeRandomMatrix (B,n,1,1.0);
-
- // time several factorizations, return the minimum timing
- double mintime = 1e100;
- dStopwatch sw;
- for (int i=0; i<100; i++) {
- memcpy (X,B,n*sizeof(dReal)); // copy B to X
-
- if (transpose) {
- dStopwatchReset (&sw);
- dStopwatchStart (&sw);
- dSolveL1T (L,X,n,npad);
- dStopwatchStop (&sw);
- }
- else {
- dStopwatchReset (&sw);
- dStopwatchStart (&sw);
- dSolveL1 (L,X,n,npad);
- dStopwatchStop (&sw);
- }
-
- double time = dStopwatchTime (&sw);
- if (time < mintime) mintime = time;
- }
-
- printf ("%.0f",mintime * dTimerTicksPerSecond());
-}
-
-//****************************************************************************
-// the single command line argument is 'f' to test and time the factorizer,
-// or 's' to test and time the solver.
-
-
-void testAccuracy (int n, char type)
-{
- if (type == 'f') testLDLTAccuracy (n);
- if (type == 's') testSolverAccuracy (n);
- if (type == 't') testTransposeSolverAccuracy (n);
-}
-
-
-void testSpeed (int n, char type)
-{
- if (type == 'f') testLDLTSpeed (n);
- if (type == 's') testSolverSpeed (n,0);
- if (type == 't') testSolverSpeed (n,1);
-}
-
-
-int main (int argc, char **argv)
-{
- if (argc != 2 || argv[1][0] == 0 || argv[1][1] != 0 ||
- (argv[1][0] != 'f' && argv[1][0] != 's' && argv[1][0] != 't')) {
- fprintf (stderr,"Usage: test_ldlt [f|s|t]\n");
- exit (1);
- }
- char type = argv[1][0];
-
- // accuracy test: test all sizes up to 20 then all prime sizes up to 101
- int i;
- for (i=1; i<20; i++) {
- testAccuracy (i,type);
- }
- testAccuracy (23,type);
- testAccuracy (29,type);
- testAccuracy (31,type);
- testAccuracy (37,type);
- testAccuracy (41,type);
- testAccuracy (43,type);
- testAccuracy (47,type);
- testAccuracy (53,type);
- testAccuracy (59,type);
- testAccuracy (61,type);
- testAccuracy (67,type);
- testAccuracy (71,type);
- testAccuracy (73,type);
- testAccuracy (79,type);
- testAccuracy (83,type);
- testAccuracy (89,type);
- testAccuracy (97,type);
- testAccuracy (101,type);
-
- // test speed on a 127x127 matrix
- testSpeed (127,type);
-
- return 0;
-}
diff --git a/extern/ode/dist/ode/fbuild/test_multidot.cpp b/extern/ode/dist/ode/fbuild/test_multidot.cpp
deleted file mode 100644
index 0e961152fed..00000000000
--- a/extern/ode/dist/ode/fbuild/test_multidot.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <stdio.h>
-#include "ode/ode.h"
-
-#define NUM_A 2
-#define ALLOCA dALLOCA16
-#define SIZE 1000
-
-
-extern "C" void dMultidot2 (const dReal *a0, const dReal *a1,
- const dReal *b, dReal *outsum, int n);
-/*
-extern "C" void dMultidot4 (const dReal *a0, const dReal *a1,
- const dReal *a2, const dReal *a3,
- const dReal *b, dReal *outsum, int n);
-*/
-
-
-// correct dot product, for accuracy testing
-
-dReal goodDot (dReal *a, dReal *b, int n)
-{
- dReal sum=0;
- while (n > 0) {
- sum += (*a) * (*b);
- a++;
- b++;
- n--;
- }
- return sum;
-}
-
-
-// test multi-dot product accuracy
-
-void testAccuracy()
-{
- int j;
-
- // allocate vectors a and b and fill them with random data
- dReal *a[NUM_A];
- for (j=0; j<NUM_A; j++) a[j] = (dReal*) ALLOCA (SIZE*sizeof(dReal));
- dReal *b = (dReal*) ALLOCA (SIZE*sizeof(dReal));
- for (j=0; j<NUM_A; j++) dMakeRandomMatrix (a[j],1,SIZE,1.0);
- dMakeRandomMatrix (b,1,SIZE,1.0);
-
- for (int n=1; n<100; n++) {
- dReal good[NUM_A];
- for (j=0; j<NUM_A; j++) good[j] = goodDot (a[j],b,n);
- dReal test[4];
- dMultidot2 (a[0],a[1],b,test,n);
- dReal diff = 0;
- for (j=0; j<NUM_A; j++) diff += fabs(good[j]-test[j]);
- // printf ("diff = %e\n",diff);
- if (diff > 1e-10) printf ("ERROR: accuracy test failed\n");
- }
-}
-
-
-// test multi-dot product factorizer speed.
-
-void testSpeed()
-{
- int j;
- dReal sum[NUM_A];
-
- // allocate vectors a and b and fill them with random data
- dReal *a[NUM_A];
- for (j=0; j<NUM_A; j++) a[j] = (dReal*) ALLOCA (SIZE*sizeof(dReal));
- dReal *b = (dReal*) ALLOCA (SIZE*sizeof(dReal));
- for (j=0; j<NUM_A; j++) dMakeRandomMatrix (a[j],1,SIZE,1.0);
- dMakeRandomMatrix (b,1,SIZE,1.0);
-
- // time several dot products, return the minimum timing
- double mintime = 1e100;
- dStopwatch sw;
- for (int i=0; i<1000; i++) {
- dStopwatchReset (&sw);
- dStopwatchStart (&sw);
-
- // try a bunch of prime sizes up to 101
- dMultidot2 (a[0],a[1],b,sum,2);
- dMultidot2 (a[0],a[1],b,sum,3);
- dMultidot2 (a[0],a[1],b,sum,5);
- dMultidot2 (a[0],a[1],b,sum,7);
- dMultidot2 (a[0],a[1],b,sum,11);
- dMultidot2 (a[0],a[1],b,sum,13);
- dMultidot2 (a[0],a[1],b,sum,17);
- dMultidot2 (a[0],a[1],b,sum,19);
- dMultidot2 (a[0],a[1],b,sum,23);
- dMultidot2 (a[0],a[1],b,sum,29);
- dMultidot2 (a[0],a[1],b,sum,31);
- dMultidot2 (a[0],a[1],b,sum,37);
- dMultidot2 (a[0],a[1],b,sum,41);
- dMultidot2 (a[0],a[1],b,sum,43);
- dMultidot2 (a[0],a[1],b,sum,47);
- dMultidot2 (a[0],a[1],b,sum,53);
- dMultidot2 (a[0],a[1],b,sum,59);
- dMultidot2 (a[0],a[1],b,sum,61);
- dMultidot2 (a[0],a[1],b,sum,67);
- dMultidot2 (a[0],a[1],b,sum,71);
- dMultidot2 (a[0],a[1],b,sum,73);
- dMultidot2 (a[0],a[1],b,sum,79);
- dMultidot2 (a[0],a[1],b,sum,83);
- dMultidot2 (a[0],a[1],b,sum,89);
- dMultidot2 (a[0],a[1],b,sum,97);
- dMultidot2 (a[0],a[1],b,sum,101);
-
- dStopwatchStop (&sw);
- double time = dStopwatchTime (&sw);
- if (time < mintime) mintime = time;
- }
-
- printf ("%.0f",mintime * dTimerTicksPerSecond());
-}
-
-
-int main()
-{
- testAccuracy();
- testSpeed();
- return 0;
-}
diff --git a/extern/ode/dist/ode/src/array.cpp b/extern/ode/dist/ode/src/array.cpp
deleted file mode 100644
index cbb1a6ed557..00000000000
--- a/extern/ode/dist/ode/src/array.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <ode/config.h>
-#include <ode/memory.h>
-#include <ode/error.h>
-#include "array.h"
-
-
-static inline int roundUpToPowerOfTwo (int x)
-{
- int i = 1;
- while (i < x) i <<= 1;
- return i;
-}
-
-
-void dArrayBase::_freeAll (int sizeofT)
-{
- if (_data) {
- if (_data == this+1) return; // if constructLocalArray() was called
- dFree (_data,_anum * sizeofT);
- }
-}
-
-
-void dArrayBase::_setSize (int newsize, int sizeofT)
-{
- if (newsize < 0) return;
- if (newsize > _anum) {
- if (_data == this+1) {
- // this is a no-no, because constructLocalArray() was called
- dDebug (0,"setSize() out of space in LOCAL array");
- }
- int newanum = roundUpToPowerOfTwo (newsize);
- if (_data) _data = dRealloc (_data, _anum*sizeofT, newanum*sizeofT);
- else _data = dAlloc (newanum*sizeofT);
- _anum = newanum;
- }
- _size = newsize;
-}
-
-
-void * dArrayBase::operator new (size_t size)
-{
- return dAlloc (size);
-}
-
-
-void dArrayBase::operator delete (void *ptr, size_t size)
-{
- dFree (ptr,size);
-}
-
-
-void dArrayBase::constructLocalArray (int __anum)
-{
- _size = 0;
- _anum = __anum;
- _data = this+1;
-}
diff --git a/extern/ode/dist/ode/src/array.h b/extern/ode/dist/ode/src/array.h
deleted file mode 100644
index 97c2cebc2f4..00000000000
--- a/extern/ode/dist/ode/src/array.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/* this comes from the `reuse' library. copy any changes back to the source.
- *
- * Variable sized array template. The array is always stored in a contiguous
- * chunk. The array can be resized. A size increase will cause more memory
- * to be allocated, and may result in relocation of the array memory.
- * A size decrease has no effect on the memory allocation.
- *
- * Array elements with constructors or destructors are not supported!
- * But if you must have such elements, here's what to know/do:
- * - Bitwise copy is used when copying whole arrays.
- * - When copying individual items (via push(), insert() etc) the `='
- * (equals) operator is used. Thus you should define this operator to do
- * a bitwise copy. You should probably also define the copy constructor.
- */
-
-
-#ifndef _ODE_ARRAY_H_
-#define _ODE_ARRAY_H_
-
-#include <ode/config.h>
-
-
-// this base class has no constructors or destructor, for your convenience.
-
-class dArrayBase {
-protected:
- int _size; // number of elements in `data'
- int _anum; // allocated number of elements in `data'
- void *_data; // array data
-
- void _freeAll (int sizeofT);
- void _setSize (int newsize, int sizeofT);
- // set the array size to `newsize', allocating more memory if necessary.
- // if newsize>_anum and is a power of two then this is guaranteed to
- // set _size and _anum to newsize.
-
-public:
- // not: dArrayBase () { _size=0; _anum=0; _data=0; }
-
- int size() const { return _size; }
- int allocatedSize() const { return _anum; }
- void * operator new (size_t size);
- void operator delete (void *ptr, size_t size);
-
- void constructor() { _size=0; _anum=0; _data=0; }
- // if this structure is allocated with malloc() instead of new, you can
- // call this to set it up.
-
- void constructLocalArray (int __anum);
- // this helper function allows non-reallocating arrays to be constructed
- // on the stack (or in the heap if necessary). this is something of a
- // kludge and should be used with extreme care. this function acts like
- // a constructor - it is called on uninitialized memory that will hold the
- // Array structure and the data. __anum is the number of elements that
- // are allocated. the memory MUST be allocated with size:
- // sizeof(ArrayBase) + __anum*sizeof(T)
- // arrays allocated this way will never try to reallocate or free the
- // memory - that's your job.
-};
-
-
-template <class T> class dArray : public dArrayBase {
-public:
- void equals (const dArray<T> &x) {
- setSize (x.size());
- memcpy (_data,x._data,x._size * sizeof(T));
- }
-
- dArray () { constructor(); }
- dArray (const dArray<T> &x) { constructor(); equals (x); }
- ~dArray () { _freeAll(sizeof(T)); }
- void setSize (int newsize) { _setSize (newsize,sizeof(T)); }
- T *data() const { return (T*) _data; }
- T & operator[] (int i) const { return ((T*)_data)[i]; }
- void operator = (const dArray<T> &x) { equals (x); }
-
- void push (const T item) {
- if (_size < _anum) _size++; else _setSize (_size+1,sizeof(T));
- ((T*)_data)[_size-1] = item;
- }
-
- void swap (dArray<T> &x) {
- int tmp1;
- void *tmp2;
- tmp1=_size; _size=x._size; x._size=tmp1;
- tmp1=_anum; _anum=x._anum; x._anum=tmp1;
- tmp2=_data; _data=x._data; x._data=tmp2;
- }
-
- // insert the item at the position `i'. if i<0 then add the item to the
- // start, if i >= size then add the item to the end of the array.
- void insert (int i, const T item) {
- if (_size < _anum) _size++; else _setSize (_size+1,sizeof(T));
- if (i >= (_size-1)) i = _size-1; // add to end
- else {
- if (i < 0) i=0; // add to start
- int n = _size-1-i;
- if (n>0) memmove (((T*)_data) + i+1, ((T*)_data) + i, n*sizeof(T));
- }
- ((T*)_data)[i] = item;
- }
-
- void remove (int i) {
- if (i >= 0 && i < _size) { // passing this test guarantees size>0
- int n = _size-1-i;
- if (n>0) memmove (((T*)_data) + i, ((T*)_data) + i+1, n*sizeof(T));
- _size--;
- }
- }
-};
-
-#endif
-
diff --git a/extern/ode/dist/ode/src/error.cpp b/extern/ode/dist/ode/src/error.cpp
deleted file mode 100644
index 9b33db55f0c..00000000000
--- a/extern/ode/dist/ode/src/error.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <ode/config.h>
-#include <ode/error.h>
-
-
-static dMessageFunction *error_function = 0;
-static dMessageFunction *debug_function = 0;
-static dMessageFunction *message_function = 0;
-
-
-extern "C" void dSetErrorHandler (dMessageFunction *fn)
-{
- error_function = fn;
-}
-
-
-extern "C" void dSetDebugHandler (dMessageFunction *fn)
-{
- debug_function = fn;
-}
-
-
-extern "C" void dSetMessageHandler (dMessageFunction *fn)
-{
- message_function = fn;
-}
-
-
-extern "C" dMessageFunction *dGetErrorHandler()
-{
- return error_function;
-}
-
-
-extern "C" dMessageFunction *dGetDebugHandler()
-{
- return debug_function;
-}
-
-
-extern "C" dMessageFunction *dGetMessageHandler()
-{
- return message_function;
-}
-
-
-static void printMessage (int num, const char *msg1, const char *msg2,
- va_list ap)
-{
- fflush (stderr);
- fflush (stdout);
- if (num) fprintf (stderr,"\n%s %d: ",msg1,num);
- else fprintf (stderr,"\n%s: ",msg1);
- vfprintf (stderr,msg2,ap);
- fprintf (stderr,"\n");
- fflush (stderr);
-}
-
-//****************************************************************************
-// unix
-
-#ifndef WIN32
-
-extern "C" void dError (int num, const char *msg, ...)
-{
- va_list ap;
- va_start (ap,msg);
- if (error_function) error_function (num,msg,ap);
- else printMessage (num,"ODE Error",msg,ap);
- exit (1);
-}
-
-
-extern "C" void dDebug (int num, const char *msg, ...)
-{
- va_list ap;
- va_start (ap,msg);
- if (debug_function) debug_function (num,msg,ap);
- else printMessage (num,"ODE INTERNAL ERROR",msg,ap);
- // *((char *)0) = 0; ... commit SEGVicide
- abort();
-}
-
-
-extern "C" void dMessage (int num, const char *msg, ...)
-{
- va_list ap;
- va_start (ap,msg);
- if (message_function) message_function (num,msg,ap);
- else printMessage (num,"ODE Message",msg,ap);
-}
-
-#endif
-
-//****************************************************************************
-// windows
-
-#ifdef WIN32
-
-// isn't cygwin annoying!
-#ifdef CYGWIN
-#define _snprintf snprintf
-#define _vsnprintf vsnprintf
-#endif
-
-
-#include "windows.h"
-
-
-extern "C" void dError (int num, const char *msg, ...)
-{
- va_list ap;
- va_start (ap,msg);
- if (error_function) error_function (num,msg,ap);
- else {
- char s[1000],title[100];
- _snprintf (title,sizeof(title),"ODE Error %d",num);
- _vsnprintf (s,sizeof(s),msg,ap);
- s[sizeof(s)-1] = 0;
- MessageBox(0,s,title,MB_OK | MB_ICONWARNING);
- }
- exit (1);
-}
-
-
-extern "C" void dDebug (int num, const char *msg, ...)
-{
- va_list ap;
- va_start (ap,msg);
- if (debug_function) debug_function (num,msg,ap);
- else {
- char s[1000],title[100];
- _snprintf (title,sizeof(title),"ODE INTERNAL ERROR %d",num);
- _vsnprintf (s,sizeof(s),msg,ap);
- s[sizeof(s)-1] = 0;
- MessageBox(0,s,title,MB_OK | MB_ICONSTOP);
- }
- abort();
-}
-
-
-extern "C" void dMessage (int num, const char *msg, ...)
-{
- va_list ap;
- va_start (ap,msg);
- if (message_function) message_function (num,msg,ap);
- else printMessage (num,"ODE Message",msg,ap);
-}
-
-
-#endif
diff --git a/extern/ode/dist/ode/src/fastdot.c b/extern/ode/dist/ode/src/fastdot.c
deleted file mode 100644
index 148d2dd9e17..00000000000
--- a/extern/ode/dist/ode/src/fastdot.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* generated code, do not edit. */
-
-#include "ode/matrix.h"
-
-
-dReal dDot (const dReal *a, const dReal *b, int n)
-{
- dReal p0,q0,m0,p1,q1,m1,sum;
- sum = 0;
- n -= 2;
- while (n >= 0) {
- p0 = a[0]; q0 = b[0];
- m0 = p0 * q0;
- p1 = a[1]; q1 = b[1];
- m1 = p1 * q1;
- sum += m0;
- sum += m1;
- a += 2;
- b += 2;
- n -= 2;
- }
- n += 2;
- while (n > 0) {
- sum += (*a) * (*b);
- a++;
- b++;
- n--;
- }
- return sum;
-}
diff --git a/extern/ode/dist/ode/src/fastldlt.c b/extern/ode/dist/ode/src/fastldlt.c
deleted file mode 100644
index df2ea6ec229..00000000000
--- a/extern/ode/dist/ode/src/fastldlt.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/* generated code, do not edit. */
-
-#include "ode/matrix.h"
-
-/* solve L*X=B, with B containing 1 right hand sides.
- * L is an n*n lower triangular matrix with ones on the diagonal.
- * L is stored by rows and its leading dimension is lskip.
- * B is an n*1 matrix that contains the right hand sides.
- * B is stored by columns and its leading dimension is also lskip.
- * B is overwritten with X.
- * this processes blocks of 2*2.
- * if this is in the factorizer source file, n must be a multiple of 2.
- */
-
-static void dSolveL1_1 (const dReal *L, dReal *B, int n, int lskip1)
-{
- /* declare variables - Z matrix, p and q vectors, etc */
- dReal Z11,m11,Z21,m21,p1,q1,p2,*ex;
- const dReal *ell;
- int i,j;
- /* compute all 2 x 1 blocks of X */
- for (i=0; i < n; i+=2) {
- /* compute all 2 x 1 block of X, from rows i..i+2-1 */
- /* set the Z matrix to 0 */
- Z11=0;
- Z21=0;
- ell = L + i*lskip1;
- ex = B;
- /* the inner loop that computes outer products and adds them to Z */
- for (j=i-2; j >= 0; j -= 2) {
- /* compute outer product and add it to the Z matrix */
- p1=ell[0];
- q1=ex[0];
- m11 = p1 * q1;
- p2=ell[lskip1];
- m21 = p2 * q1;
- Z11 += m11;
- Z21 += m21;
- /* compute outer product and add it to the Z matrix */
- p1=ell[1];
- q1=ex[1];
- m11 = p1 * q1;
- p2=ell[1+lskip1];
- m21 = p2 * q1;
- /* advance pointers */
- ell += 2;
- ex += 2;
- Z11 += m11;
- Z21 += m21;
- /* end of inner loop */
- }
- /* compute left-over iterations */
- j += 2;
- for (; j > 0; j--) {
- /* compute outer product and add it to the Z matrix */
- p1=ell[0];
- q1=ex[0];
- m11 = p1 * q1;
- p2=ell[lskip1];
- m21 = p2 * q1;
- /* advance pointers */
- ell += 1;
- ex += 1;
- Z11 += m11;
- Z21 += m21;
- }
- /* finish computing the X(i) block */
- Z11 = ex[0] - Z11;
- ex[0] = Z11;
- p1 = ell[lskip1];
- Z21 = ex[1] - Z21 - p1*Z11;
- ex[1] = Z21;
- /* end of outer loop */
- }
-}
-
-/* solve L*X=B, with B containing 2 right hand sides.
- * L is an n*n lower triangular matrix with ones on the diagonal.
- * L is stored by rows and its leading dimension is lskip.
- * B is an n*2 matrix that contains the right hand sides.
- * B is stored by columns and its leading dimension is also lskip.
- * B is overwritten with X.
- * this processes blocks of 2*2.
- * if this is in the factorizer source file, n must be a multiple of 2.
- */
-
-static void dSolveL1_2 (const dReal *L, dReal *B, int n, int lskip1)
-{
- /* declare variables - Z matrix, p and q vectors, etc */
- dReal Z11,m11,Z12,m12,Z21,m21,Z22,m22,p1,q1,p2,q2,*ex;
- const dReal *ell;
- int i,j;
- /* compute all 2 x 2 blocks of X */
- for (i=0; i < n; i+=2) {
- /* compute all 2 x 2 block of X, from rows i..i+2-1 */
- /* set the Z matrix to 0 */
- Z11=0;
- Z12=0;
- Z21=0;
- Z22=0;
- ell = L + i*lskip1;
- ex = B;
- /* the inner loop that computes outer products and adds them to Z */
- for (j=i-2; j >= 0; j -= 2) {
- /* compute outer product and add it to the Z matrix */
- p1=ell[0];
- q1=ex[0];
- m11 = p1 * q1;
- q2=ex[lskip1];
- m12 = p1 * q2;
- p2=ell[lskip1];
- m21 = p2 * q1;
- m22 = p2 * q2;
- Z11 += m11;
- Z12 += m12;
- Z21 += m21;
- Z22 += m22;
- /* compute outer product and add it to the Z matrix */
- p1=ell[1];
- q1=ex[1];
- m11 = p1 * q1;
- q2=ex[1+lskip1];
- m12 = p1 * q2;
- p2=ell[1+lskip1];
- m21 = p2 * q1;
- m22 = p2 * q2;
- /* advance pointers */
- ell += 2;
- ex += 2;
- Z11 += m11;
- Z12 += m12;
- Z21 += m21;
- Z22 += m22;
- /* end of inner loop */
- }
- /* compute left-over iterations */
- j += 2;
- for (; j > 0; j--) {
- /* compute outer product and add it to the Z matrix */
- p1=ell[0];
- q1=ex[0];
- m11 = p1 * q1;
- q2=ex[lskip1];
- m12 = p1 * q2;
- p2=ell[lskip1];
- m21 = p2 * q1;
- m22 = p2 * q2;
- /* advance pointers */
- ell += 1;
- ex += 1;
- Z11 += m11;
- Z12 += m12;
- Z21 += m21;
- Z22 += m22;
- }
- /* finish computing the X(i) block */
- Z11 = ex[0] - Z11;
- ex[0] = Z11;
- Z12 = ex[lskip1] - Z12;
- ex[lskip1] = Z12;
- p1 = ell[lskip1];
- Z21 = ex[1] - Z21 - p1*Z11;
- ex[1] = Z21;
- Z22 = ex[1+lskip1] - Z22 - p1*Z12;
- ex[1+lskip1] = Z22;
- /* end of outer loop */
- }
-}
-
-
-void dFactorLDLT (dReal *A, dReal *d, int n, int nskip1)
-{
- int i,j;
- dReal sum,*ell,*dee,dd,p1,p2,q1,q2,Z11,m11,Z21,m21,Z22,m22;
- if (n < 1) return;
-
- for (i=0; i<=n-2; i += 2) {
- /* solve L*(D*l)=a, l is scaled elements in 2 x i block at A(i,0) */
- dSolveL1_2 (A,A+i*nskip1,i,nskip1);
- /* scale the elements in a 2 x i block at A(i,0), and also */
- /* compute Z = the outer product matrix that we'll need. */
- Z11 = 0;
- Z21 = 0;
- Z22 = 0;
- ell = A+i*nskip1;
- dee = d;
- for (j=i-6; j >= 0; j -= 6) {
- p1 = ell[0];
- p2 = ell[nskip1];
- dd = dee[0];
- q1 = p1*dd;
- q2 = p2*dd;
- ell[0] = q1;
- ell[nskip1] = q2;
- m11 = p1*q1;
- m21 = p2*q1;
- m22 = p2*q2;
- Z11 += m11;
- Z21 += m21;
- Z22 += m22;
- p1 = ell[1];
- p2 = ell[1+nskip1];
- dd = dee[1];
- q1 = p1*dd;
- q2 = p2*dd;
- ell[1] = q1;
- ell[1+nskip1] = q2;
- m11 = p1*q1;
- m21 = p2*q1;
- m22 = p2*q2;
- Z11 += m11;
- Z21 += m21;
- Z22 += m22;
- p1 = ell[2];
- p2 = ell[2+nskip1];
- dd = dee[2];
- q1 = p1*dd;
- q2 = p2*dd;
- ell[2] = q1;
- ell[2+nskip1] = q2;
- m11 = p1*q1;
- m21 = p2*q1;
- m22 = p2*q2;
- Z11 += m11;
- Z21 += m21;
- Z22 += m22;
- p1 = ell[3];
- p2 = ell[3+nskip1];
- dd = dee[3];
- q1 = p1*dd;
- q2 = p2*dd;
- ell[3] = q1;
- ell[3+nskip1] = q2;
- m11 = p1*q1;
- m21 = p2*q1;
- m22 = p2*q2;
- Z11 += m11;
- Z21 += m21;
- Z22 += m22;
- p1 = ell[4];
- p2 = ell[4+nskip1];
- dd = dee[4];
- q1 = p1*dd;
- q2 = p2*dd;
- ell[4] = q1;
- ell[4+nskip1] = q2;
- m11 = p1*q1;
- m21 = p2*q1;
- m22 = p2*q2;
- Z11 += m11;
- Z21 += m21;
- Z22 += m22;
- p1 = ell[5];
- p2 = ell[5+nskip1];
- dd = dee[5];
- q1 = p1*dd;
- q2 = p2*dd;
- ell[5] = q1;
- ell[5+nskip1] = q2;
- m11 = p1*q1;
- m21 = p2*q1;
- m22 = p2*q2;
- Z11 += m11;
- Z21 += m21;
- Z22 += m22;
- ell += 6;
- dee += 6;
- }
- /* compute left-over iterations */
- j += 6;
- for (; j > 0; j--) {
- p1 = ell[0];
- p2 = ell[nskip1];
- dd = dee[0];
- q1 = p1*dd;
- q2 = p2*dd;
- ell[0] = q1;
- ell[nskip1] = q2;
- m11 = p1*q1;
- m21 = p2*q1;
- m22 = p2*q2;
- Z11 += m11;
- Z21 += m21;
- Z22 += m22;
- ell++;
- dee++;
- }
- /* solve for diagonal 2 x 2 block at A(i,i) */
- Z11 = ell[0] - Z11;
- Z21 = ell[nskip1] - Z21;
- Z22 = ell[1+nskip1] - Z22;
- dee = d + i;
- /* factorize 2 x 2 block Z,dee */
- /* factorize row 1 */
- dee[0] = dRecip(Z11);
- /* factorize row 2 */
- sum = 0;
- q1 = Z21;
- q2 = q1 * dee[0];
- Z21 = q2;
- sum += q1*q2;
- dee[1] = dRecip(Z22 - sum);
- /* done factorizing 2 x 2 block */
- ell[nskip1] = Z21;
- }
- /* compute the (less than 2) rows at the bottom */
- switch (n-i) {
- case 0:
- break;
-
- case 1:
- dSolveL1_1 (A,A+i*nskip1,i,nskip1);
- /* scale the elements in a 1 x i block at A(i,0), and also */
- /* compute Z = the outer product matrix that we'll need. */
- Z11 = 0;
- ell = A+i*nskip1;
- dee = d;
- for (j=i-6; j >= 0; j -= 6) {
- p1 = ell[0];
- dd = dee[0];
- q1 = p1*dd;
- ell[0] = q1;
- m11 = p1*q1;
- Z11 += m11;
- p1 = ell[1];
- dd = dee[1];
- q1 = p1*dd;
- ell[1] = q1;
- m11 = p1*q1;
- Z11 += m11;
- p1 = ell[2];
- dd = dee[2];
- q1 = p1*dd;
- ell[2] = q1;
- m11 = p1*q1;
- Z11 += m11;
- p1 = ell[3];
- dd = dee[3];
- q1 = p1*dd;
- ell[3] = q1;
- m11 = p1*q1;
- Z11 += m11;
- p1 = ell[4];
- dd = dee[4];
- q1 = p1*dd;
- ell[4] = q1;
- m11 = p1*q1;
- Z11 += m11;
- p1 = ell[5];
- dd = dee[5];
- q1 = p1*dd;
- ell[5] = q1;
- m11 = p1*q1;
- Z11 += m11;
- ell += 6;
- dee += 6;
- }
- /* compute left-over iterations */
- j += 6;
- for (; j > 0; j--) {
- p1 = ell[0];
- dd = dee[0];
- q1 = p1*dd;
- ell[0] = q1;
- m11 = p1*q1;
- Z11 += m11;
- ell++;
- dee++;
- }
- /* solve for diagonal 1 x 1 block at A(i,i) */
- Z11 = ell[0] - Z11;
- dee = d + i;
- /* factorize 1 x 1 block Z,dee */
- /* factorize row 1 */
- dee[0] = dRecip(Z11);
- /* done factorizing 1 x 1 block */
- break;
-
- default: *((char*)0)=0; /* this should never happen! */
- }
-}
diff --git a/extern/ode/dist/ode/src/fastlsolve.c b/extern/ode/dist/ode/src/fastlsolve.c
deleted file mode 100644
index 0ae99d62d0b..00000000000
--- a/extern/ode/dist/ode/src/fastlsolve.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* generated code, do not edit. */
-
-#include "ode/matrix.h"
-
-/* solve L*X=B, with B containing 1 right hand sides.
- * L is an n*n lower triangular matrix with ones on the diagonal.
- * L is stored by rows and its leading dimension is lskip.
- * B is an n*1 matrix that contains the right hand sides.
- * B is stored by columns and its leading dimension is also lskip.
- * B is overwritten with X.
- * this processes blocks of 4*4.
- * if this is in the factorizer source file, n must be a multiple of 4.
- */
-
-void dSolveL1 (const dReal *L, dReal *B, int n, int lskip1)
-{
- /* declare variables - Z matrix, p and q vectors, etc */
- dReal Z11,Z21,Z31,Z41,p1,q1,p2,p3,p4,*ex;
- const dReal *ell;
- int lskip2,lskip3,i,j;
- /* compute lskip values */
- lskip2 = 2*lskip1;
- lskip3 = 3*lskip1;
- /* compute all 4 x 1 blocks of X */
- for (i=0; i <= n-4; i+=4) {
- /* compute all 4 x 1 block of X, from rows i..i+4-1 */
- /* set the Z matrix to 0 */
- Z11=0;
- Z21=0;
- Z31=0;
- Z41=0;
- ell = L + i*lskip1;
- ex = B;
- /* the inner loop that computes outer products and adds them to Z */
- for (j=i-12; j >= 0; j -= 12) {
- /* load p and q values */
- p1=ell[0];
- q1=ex[0];
- p2=ell[lskip1];
- p3=ell[lskip2];
- p4=ell[lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[1];
- q1=ex[1];
- p2=ell[1+lskip1];
- p3=ell[1+lskip2];
- p4=ell[1+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[2];
- q1=ex[2];
- p2=ell[2+lskip1];
- p3=ell[2+lskip2];
- p4=ell[2+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[3];
- q1=ex[3];
- p2=ell[3+lskip1];
- p3=ell[3+lskip2];
- p4=ell[3+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[4];
- q1=ex[4];
- p2=ell[4+lskip1];
- p3=ell[4+lskip2];
- p4=ell[4+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[5];
- q1=ex[5];
- p2=ell[5+lskip1];
- p3=ell[5+lskip2];
- p4=ell[5+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[6];
- q1=ex[6];
- p2=ell[6+lskip1];
- p3=ell[6+lskip2];
- p4=ell[6+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[7];
- q1=ex[7];
- p2=ell[7+lskip1];
- p3=ell[7+lskip2];
- p4=ell[7+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[8];
- q1=ex[8];
- p2=ell[8+lskip1];
- p3=ell[8+lskip2];
- p4=ell[8+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[9];
- q1=ex[9];
- p2=ell[9+lskip1];
- p3=ell[9+lskip2];
- p4=ell[9+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[10];
- q1=ex[10];
- p2=ell[10+lskip1];
- p3=ell[10+lskip2];
- p4=ell[10+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* load p and q values */
- p1=ell[11];
- q1=ex[11];
- p2=ell[11+lskip1];
- p3=ell[11+lskip2];
- p4=ell[11+lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* advance pointers */
- ell += 12;
- ex += 12;
- /* end of inner loop */
- }
- /* compute left-over iterations */
- j += 12;
- for (; j > 0; j--) {
- /* load p and q values */
- p1=ell[0];
- q1=ex[0];
- p2=ell[lskip1];
- p3=ell[lskip2];
- p4=ell[lskip3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- Z21 += p2 * q1;
- Z31 += p3 * q1;
- Z41 += p4 * q1;
- /* advance pointers */
- ell += 1;
- ex += 1;
- }
- /* finish computing the X(i) block */
- Z11 = ex[0] - Z11;
- ex[0] = Z11;
- p1 = ell[lskip1];
- Z21 = ex[1] - Z21 - p1*Z11;
- ex[1] = Z21;
- p1 = ell[lskip2];
- p2 = ell[1+lskip2];
- Z31 = ex[2] - Z31 - p1*Z11 - p2*Z21;
- ex[2] = Z31;
- p1 = ell[lskip3];
- p2 = ell[1+lskip3];
- p3 = ell[2+lskip3];
- Z41 = ex[3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31;
- ex[3] = Z41;
- /* end of outer loop */
- }
- /* compute rows at end that are not a multiple of block size */
- for (; i < n; i++) {
- /* compute all 1 x 1 block of X, from rows i..i+1-1 */
- /* set the Z matrix to 0 */
- Z11=0;
- ell = L + i*lskip1;
- ex = B;
- /* the inner loop that computes outer products and adds them to Z */
- for (j=i-12; j >= 0; j -= 12) {
- /* load p and q values */
- p1=ell[0];
- q1=ex[0];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[1];
- q1=ex[1];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[2];
- q1=ex[2];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[3];
- q1=ex[3];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[4];
- q1=ex[4];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[5];
- q1=ex[5];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[6];
- q1=ex[6];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[7];
- q1=ex[7];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[8];
- q1=ex[8];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[9];
- q1=ex[9];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[10];
- q1=ex[10];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* load p and q values */
- p1=ell[11];
- q1=ex[11];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* advance pointers */
- ell += 12;
- ex += 12;
- /* end of inner loop */
- }
- /* compute left-over iterations */
- j += 12;
- for (; j > 0; j--) {
- /* load p and q values */
- p1=ell[0];
- q1=ex[0];
- /* compute outer product and add it to the Z matrix */
- Z11 += p1 * q1;
- /* advance pointers */
- ell += 1;
- ex += 1;
- }
- /* finish computing the X(i) block */
- Z11 = ex[0] - Z11;
- ex[0] = Z11;
- }
-}
diff --git a/extern/ode/dist/ode/src/fastltsolve.c b/extern/ode/dist/ode/src/fastltsolve.c
deleted file mode 100644
index eb950f6076a..00000000000
--- a/extern/ode/dist/ode/src/fastltsolve.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/* generated code, do not edit. */
-
-#include "ode/matrix.h"
-
-/* solve L^T * x=b, with b containing 1 right hand side.
- * L is an n*n lower triangular matrix with ones on the diagonal.
- * L is stored by rows and its leading dimension is lskip.
- * b is an n*1 matrix that contains the right hand side.
- * b is overwritten with x.
- * this processes blocks of 4.
- */
-
-void dSolveL1T (const dReal *L, dReal *B, int n, int lskip1)
-{
- /* declare variables - Z matrix, p and q vectors, etc */
- dReal Z11,m11,Z21,m21,Z31,m31,Z41,m41,p1,q1,p2,p3,p4,*ex;
- const dReal *ell;
- int lskip2,lskip3,i,j;
- /* special handling for L and B because we're solving L1 *transpose* */
- L = L + (n-1)*(lskip1+1);
- B = B + n-1;
- lskip1 = -lskip1;
- /* compute lskip values */
- lskip2 = 2*lskip1;
- lskip3 = 3*lskip1;
- /* compute all 4 x 1 blocks of X */
- for (i=0; i <= n-4; i+=4) {
- /* compute all 4 x 1 block of X, from rows i..i+4-1 */
- /* set the Z matrix to 0 */
- Z11=0;
- Z21=0;
- Z31=0;
- Z41=0;
- ell = L - i;
- ex = B;
- /* the inner loop that computes outer products and adds them to Z */
- for (j=i-4; j >= 0; j -= 4) {
- /* load p and q values */
- p1=ell[0];
- q1=ex[0];
- p2=ell[-1];
- p3=ell[-2];
- p4=ell[-3];
- /* compute outer product and add it to the Z matrix */
- m11 = p1 * q1;
- m21 = p2 * q1;
- m31 = p3 * q1;
- m41 = p4 * q1;
- ell += lskip1;
- Z11 += m11;
- Z21 += m21;
- Z31 += m31;
- Z41 += m41;
- /* load p and q values */
- p1=ell[0];
- q1=ex[-1];
- p2=ell[-1];
- p3=ell[-2];
- p4=ell[-3];
- /* compute outer product and add it to the Z matrix */
- m11 = p1 * q1;
- m21 = p2 * q1;
- m31 = p3 * q1;
- m41 = p4 * q1;
- ell += lskip1;
- Z11 += m11;
- Z21 += m21;
- Z31 += m31;
- Z41 += m41;
- /* load p and q values */
- p1=ell[0];
- q1=ex[-2];
- p2=ell[-1];
- p3=ell[-2];
- p4=ell[-3];
- /* compute outer product and add it to the Z matrix */
- m11 = p1 * q1;
- m21 = p2 * q1;
- m31 = p3 * q1;
- m41 = p4 * q1;
- ell += lskip1;
- Z11 += m11;
- Z21 += m21;
- Z31 += m31;
- Z41 += m41;
- /* load p and q values */
- p1=ell[0];
- q1=ex[-3];
- p2=ell[-1];
- p3=ell[-2];
- p4=ell[-3];
- /* compute outer product and add it to the Z matrix */
- m11 = p1 * q1;
- m21 = p2 * q1;
- m31 = p3 * q1;
- m41 = p4 * q1;
- ell += lskip1;
- ex -= 4;
- Z11 += m11;
- Z21 += m21;
- Z31 += m31;
- Z41 += m41;
- /* end of inner loop */
- }
- /* compute left-over iterations */
- j += 4;
- for (; j > 0; j--) {
- /* load p and q values */
- p1=ell[0];
- q1=ex[0];
- p2=ell[-1];
- p3=ell[-2];
- p4=ell[-3];
- /* compute outer product and add it to the Z matrix */
- m11 = p1 * q1;
- m21 = p2 * q1;
- m31 = p3 * q1;
- m41 = p4 * q1;
- ell += lskip1;
- ex -= 1;
- Z11 += m11;
- Z21 += m21;
- Z31 += m31;
- Z41 += m41;
- }
- /* finish computing the X(i) block */
- Z11 = ex[0] - Z11;
- ex[0] = Z11;
- p1 = ell[-1];
- Z21 = ex[-1] - Z21 - p1*Z11;
- ex[-1] = Z21;
- p1 = ell[-2];
- p2 = ell[-2+lskip1];
- Z31 = ex[-2] - Z31 - p1*Z11 - p2*Z21;
- ex[-2] = Z31;
- p1 = ell[-3];
- p2 = ell[-3+lskip1];
- p3 = ell[-3+lskip2];
- Z41 = ex[-3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31;
- ex[-3] = Z41;
- /* end of outer loop */
- }
- /* compute rows at end that are not a multiple of block size */
- for (; i < n; i++) {
- /* compute all 1 x 1 block of X, from rows i..i+1-1 */
- /* set the Z matrix to 0 */
- Z11=0;
- ell = L - i;
- ex = B;
- /* the inner loop that computes outer products and adds them to Z */
- for (j=i-4; j >= 0; j -= 4) {
- /* load p and q values */
- p1=ell[0];
- q1=ex[0];
- /* compute outer product and add it to the Z matrix */
- m11 = p1 * q1;
- ell += lskip1;
- Z11 += m11;
- /* load p and q values */
- p1=ell[0];
- q1=ex[-1];
- /* compute outer product and add it to the Z matrix */
- m11 = p1 * q1;
- ell += lskip1;
- Z11 += m11;
- /* load p and q values */
- p1=ell[0];
- q1=ex[-2];
- /* compute outer product and add it to the Z matrix */
- m11 = p1 * q1;
- ell += lskip1;
- Z11 += m11;
- /* load p and q values */
- p1=ell[0];
- q1=ex[-3];
- /* compute outer product and add it to the Z matrix */
- m11 = p1 * q1;
- ell += lskip1;
- ex -= 4;
- Z11 += m11;
- /* end of inner loop */
- }
- /* compute left-over iterations */
- j += 4;
- for (; j > 0; j--) {
- /* load p and q values */
- p1=ell[0];
- q1=ex[0];
- /* compute outer product and add it to the Z matrix */
- m11 = p1 * q1;
- ell += lskip1;
- ex -= 1;
- Z11 += m11;
- }
- /* finish computing the X(i) block */
- Z11 = ex[0] - Z11;
- ex[0] = Z11;
- }
-}
diff --git a/extern/ode/dist/ode/src/geom.cpp b/extern/ode/dist/ode/src/geom.cpp
deleted file mode 100644
index 1818814a791..00000000000
--- a/extern/ode/dist/ode/src/geom.cpp
+++ /dev/null
@@ -1,2207 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/*
-
-the rule is that only the low level primitive collision functions should set
-dContactGeom::g1 and dContactGeom::g2.
-
-*/
-
-#define SHARED_GEOM_H_INCLUDED_FROM_DEFINING_FILE 1
-#include <ode/common.h>
-#include <ode/geom.h>
-#include <ode/rotation.h>
-#include <ode/odemath.h>
-#include <ode/memory.h>
-#include <ode/misc.h>
-#include <ode/objects.h>
-#include <ode/matrix.h>
-#include "objects.h"
-#include "array.h"
-#include "geom_internal.h"
-
-//****************************************************************************
-// collision utilities.
-
-// given a pointer `p' to a dContactGeom, return the dContactGeom at
-// p + skip bytes.
-
-#define CONTACT(p,skip) ((dContactGeom*) (((char*)p) + (skip)))
-
-
-// if the spheres (p1,r1) and (p2,r2) collide, set the contact `c' and
-// return 1, else return 0.
-
-static int dCollideSpheres (dVector3 p1, dReal r1,
- dVector3 p2, dReal r2, dContactGeom *c)
-{
- // printf ("d=%.2f (%.2f %.2f %.2f) (%.2f %.2f %.2f) r1=%.2f r2=%.2f\n",
- // d,p1[0],p1[1],p1[2],p2[0],p2[1],p2[2],r1,r2);
-
- dReal d = dDISTANCE (p1,p2);
- if (d > (r1 + r2)) return 0;
- if (d <= 0) {
- c->pos[0] = p1[0];
- c->pos[1] = p1[1];
- c->pos[2] = p1[2];
- c->normal[0] = 1;
- c->normal[1] = 0;
- c->normal[2] = 0;
- c->depth = r1 + r2;
- }
- else {
- dReal d1 = dRecip (d);
- c->normal[0] = (p1[0]-p2[0])*d1;
- c->normal[1] = (p1[1]-p2[1])*d1;
- c->normal[2] = (p1[2]-p2[2])*d1;
- dReal k = REAL(0.5) * (r2 - r1 - d);
- c->pos[0] = p1[0] + c->normal[0]*k;
- c->pos[1] = p1[1] + c->normal[1]*k;
- c->pos[2] = p1[2] + c->normal[2]*k;
- c->depth = r1 + r2 - d;
- }
- return 1;
-}
-
-
-// given two lines
-// qa = pa + alpha* ua
-// qb = pb + beta * ub
-// where pa,pb are two points, ua,ub are two unit length vectors, and alpha,
-// beta go from [-inf,inf], return alpha and beta such that qa and qb are
-// as close as possible
-
-static void lineClosestApproach (const dVector3 pa, const dVector3 ua,
- const dVector3 pb, const dVector3 ub,
- dReal *alpha, dReal *beta)
-{
- dVector3 p;
- p[0] = pb[0] - pa[0];
- p[1] = pb[1] - pa[1];
- p[2] = pb[2] - pa[2];
- dReal uaub = dDOT(ua,ub);
- dReal q1 = dDOT(ua,p);
- dReal q2 = -dDOT(ub,p);
- dReal d = 1-uaub*uaub;
- if (d <= 0) {
- // @@@ this needs to be made more robust
- *alpha = 0;
- *beta = 0;
- }
- else {
- d = dRecip(d);
- *alpha = (q1 + uaub*q2)*d;
- *beta = (uaub*q1 + q2)*d;
- }
-}
-
-
-// given two line segments A and B with endpoints a1-a2 and b1-b2, return the
-// points on A and B that are closest to each other (in cp1 and cp2).
-// in the case of parallel lines where there are multiple solutions, a
-// solution involving the endpoint of at least one line will be returned.
-// this will work correctly for zero length lines, e.g. if a1==a2 and/or
-// b1==b2.
-//
-// the algorithm works by applying the voronoi clipping rule to the features
-// of the line segments. the three features of each line segment are the two
-// endpoints and the line between them. the voronoi clipping rule states that,
-// for feature X on line A and feature Y on line B, the closest points PA and
-// PB between X and Y are globally the closest points if PA is in V(Y) and
-// PB is in V(X), where V(X) is the voronoi region of X.
-
-
-void dClosestLineSegmentPoints (dVector3 const a1, dVector3 const a2,
- dVector3 const b1, dVector3 const b2,
- dVector3 cp1, dVector3 cp2)
-{
- dVector3 a1a2,b1b2,a1b1,a1b2,a2b1,a2b2,n;
- dReal la,lb,k,da1,da2,da3,da4,db1,db2,db3,db4,det;
-
-#define SET2(a,b) a[0]=b[0]; a[1]=b[1]; a[2]=b[2];
-#define SET3(a,b,op,c) a[0]=b[0] op c[0]; a[1]=b[1] op c[1]; a[2]=b[2] op c[2];
-
- // check vertex-vertex features
-
- SET3 (a1a2,a2,-,a1);
- SET3 (b1b2,b2,-,b1);
- SET3 (a1b1,b1,-,a1);
- da1 = dDOT(a1a2,a1b1);
- db1 = dDOT(b1b2,a1b1);
- if (da1 <= 0 && db1 >= 0) {
- SET2 (cp1,a1);
- SET2 (cp2,b1);
- return;
- }
-
- SET3 (a1b2,b2,-,a1);
- da2 = dDOT(a1a2,a1b2);
- db2 = dDOT(b1b2,a1b2);
- if (da2 <= 0 && db2 <= 0) {
- SET2 (cp1,a1);
- SET2 (cp2,b2);
- return;
- }
-
- SET3 (a2b1,b1,-,a2);
- da3 = dDOT(a1a2,a2b1);
- db3 = dDOT(b1b2,a2b1);
- if (da3 >= 0 && db3 >= 0) {
- SET2 (cp1,a2);
- SET2 (cp2,b1);
- return;
- }
-
- SET3 (a2b2,b2,-,a2);
- da4 = dDOT(a1a2,a2b2);
- db4 = dDOT(b1b2,a2b2);
- if (da4 >= 0 && db4 <= 0) {
- SET2 (cp1,a2);
- SET2 (cp2,b2);
- return;
- }
-
- // check edge-vertex features.
- // if one or both of the lines has zero length, we will never get to here,
- // so we do not have to worry about the following divisions by zero.
-
- la = dDOT(a1a2,a1a2);
- if (da1 >= 0 && da3 <= 0) {
- k = da1 / la;
- SET3 (n,a1b1,-,k*a1a2);
- if (dDOT(b1b2,n) >= 0) {
- SET3 (cp1,a1,+,k*a1a2);
- SET2 (cp2,b1);
- return;
- }
- }
-
- if (da2 >= 0 && da4 <= 0) {
- k = da2 / la;
- SET3 (n,a1b2,-,k*a1a2);
- if (dDOT(b1b2,n) <= 0) {
- SET3 (cp1,a1,+,k*a1a2);
- SET2 (cp2,b2);
- return;
- }
- }
-
- lb = dDOT(b1b2,b1b2);
- if (db1 <= 0 && db2 >= 0) {
- k = -db1 / lb;
- SET3 (n,-a1b1,-,k*b1b2);
- if (dDOT(a1a2,n) >= 0) {
- SET2 (cp1,a1);
- SET3 (cp2,b1,+,k*b1b2);
- return;
- }
- }
-
- if (db3 <= 0 && db4 >= 0) {
- k = -db3 / lb;
- SET3 (n,-a2b1,-,k*b1b2);
- if (dDOT(a1a2,n) <= 0) {
- SET2 (cp1,a2);
- SET3 (cp2,b1,+,k*b1b2);
- return;
- }
- }
-
- // it must be edge-edge
-
- k = dDOT(a1a2,b1b2);
- det = la*lb - k*k;
- if (det <= 0) {
- // this should never happen, but just in case...
- SET2(cp1,a1);
- SET2(cp2,b1);
- return;
- }
- det = dRecip (det);
- dReal alpha = (lb*da1 - k*db1) * det;
- dReal beta = ( k*da1 - la*db1) * det;
- SET3 (cp1,a1,+,alpha*a1a2);
- SET3 (cp2,b1,+,beta*b1b2);
-
-# undef SET2
-# undef SET3
-}
-
-
-// given a line segment p1-p2 and a box (center 'c', rotation 'R', side length
-// vector 'side'), compute the points of closest approach between the box
-// and the line. return these points in 'lret' (the point on the line) and
-// 'bret' (the point on the box). if the line actually penetrates the box
-// then the solution is not unique, but only one solution will be returned.
-// in this case the solution points will coincide.
-//
-// a simple root finding algorithm is used to find the value of 't' that
-// satisfies:
-// d|D(t)|^2/dt = 0
-// where:
-// |D(t)| = |p(t)-b(t)|
-// where p(t) is a point on the line parameterized by t:
-// p(t) = p1 + t*(p2-p1)
-// and b(t) is that same point clipped to the boundary of the box. in box-
-// relative coordinates d|D(t)|^2/dt is the sum of three x,y,z components
-// each of which looks like this:
-//
-// t_lo /
-// ______/ -->t
-// / t_hi
-// /
-//
-// t_lo and t_hi are the t values where the line passes through the planes
-// corresponding to the sides of the box. the algorithm computes d|D(t)|^2/dt
-// in a piecewise fashion from t=0 to t=1, stopping at the point where
-// d|D(t)|^2/dt crosses from negative to positive.
-
-static void dClosestLineBoxPoints (const dVector3 p1, const dVector3 p2,
- const dVector3 c, const dMatrix3 R,
- const dVector3 side,
- dVector3 lret, dVector3 bret)
-{
- int i;
-
- // compute the start and delta of the line p1-p2 relative to the box.
- // we will do all subsequent computations in this box-relative coordinate
- // system. we have to do a translation and rotation for each point.
- dVector3 tmp,s,v;
- tmp[0] = p1[0] - c[0];
- tmp[1] = p1[1] - c[1];
- tmp[2] = p1[2] - c[2];
- dMULTIPLY1_331 (s,R,tmp);
- tmp[0] = p2[0] - p1[0];
- tmp[1] = p2[1] - p1[1];
- tmp[2] = p2[2] - p1[2];
- dMULTIPLY1_331 (v,R,tmp);
-
- // mirror the line so that v has all components >= 0
- dVector3 sign;
- for (i=0; i<3; i++) {
- if (v[i] < 0) {
- s[i] = -s[i];
- v[i] = -v[i];
- sign[i] = -1;
- }
- else sign[i] = 1;
- }
-
- // compute v^2
- dVector3 v2;
- v2[0] = v[0]*v[0];
- v2[1] = v[1]*v[1];
- v2[2] = v[2]*v[2];
-
- // compute the half-sides of the box
- dReal h[3];
- h[0] = REAL(0.5) * side[0];
- h[1] = REAL(0.5) * side[1];
- h[2] = REAL(0.5) * side[2];
-
- // region is -1,0,+1 depending on which side of the box planes each
- // coordinate is on. tanchor in the next t value at which there is a
- // transition, or the last one if there are no more.
- int region[3];
- dReal tanchor[3];
-
- // find the region and tanchor values for p1
- for (i=0; i<3; i++) {
- if (v[i] > 0) {
- if (s[i] < -h[i]) {
- region[i] = -1;
- tanchor[i] = (-h[i]-s[i])/v[i];
- }
- else {
- region[i] = (s[i] > h[i]);
- tanchor[i] = (h[i]-s[i])/v[i];
- }
- }
- else {
- region[i] = 0;
- tanchor[i] = 2; // this will never be a valid tanchor
- }
- }
-
- // compute d|d|^2/dt for t=0. if it's >= 0 then p1 is the closest point
- dReal t=0;
- dReal dd2dt = 0;
- for (i=0; i<3; i++) dd2dt -= (region[i] ? v2[i] : 0) * tanchor[i];
- if (dd2dt >= 0) goto got_answer;
-
- do {
- // find the point on the line that is at the next clip plane boundary
- dReal next_t = 1;
- for (i=0; i<3; i++) {
- if (tanchor[i] > t && tanchor[i] < 1 && tanchor[i] < next_t)
- next_t = tanchor[i];
- }
-
- // compute d|d|^2/dt for the next t
- dReal next_dd2dt = 0;
- for (i=0; i<3; i++) {
- next_dd2dt += (region[i] ? v2[i] : 0) * (next_t - tanchor[i]);
- }
-
- // if the sign of d|d|^2/dt has changed, solution = the crossover point
- if (next_dd2dt >= 0) {
- dReal m = (next_dd2dt-dd2dt)/(next_t - t);
- t -= dd2dt/m;
- goto got_answer;
- }
-
- // advance to the next anchor point / region
- for (i=0; i<3; i++) {
- if (tanchor[i] == next_t) {
- tanchor[i] = (h[i]-s[i])/v[i];
- region[i]++;
- }
- }
- t = next_t;
- dd2dt = next_dd2dt;
- }
- while (t < 1);
- t = 1;
-
- got_answer:
-
- // compute closest point on the line
- for (i=0; i<3; i++) lret[i] = p1[i] + t*tmp[i]; // note: tmp=p2-p1
-
- // compute closest point on the box
- for (i=0; i<3; i++) {
- tmp[i] = sign[i] * (s[i] + t*v[i]);
- if (tmp[i] < -h[i]) tmp[i] = -h[i];
- else if (tmp[i] > h[i]) tmp[i] = h[i];
- }
- dMULTIPLY0_331 (s,R,tmp);
- for (i=0; i<3; i++) bret[i] = s[i] + c[i];
-}
-
-
-// given a box (R,side), `R' is the rotation matrix for the box, and `side'
-// is a vector of x/y/z side lengths, return the size of the interval of the
-// box projected along the given axis. if the axis has unit length then the
-// return value will be the actual diameter, otherwise the result will be
-// scaled by the axis length.
-
-static inline dReal boxDiameter (const dMatrix3 R, const dVector3 side,
- const dVector3 axis)
-{
- dVector3 q;
- dMULTIPLY1_331 (q,R,axis); // transform axis to body-relative
- return dFabs(q[0])*side[0] + dFabs(q[1])*side[1] + dFabs(q[2])*side[2];
-}
-
-
-// given boxes (p1,R1,side1) and (p1,R1,side1), return 1 if they intersect
-// or 0 if not.
-
-int dBoxTouchesBox (const dVector3 p1, const dMatrix3 R1,
- const dVector3 side1, const dVector3 p2,
- const dMatrix3 R2, const dVector3 side2)
-{
- // two boxes are disjoint if (and only if) there is a separating axis
- // perpendicular to a face from one box or perpendicular to an edge from
- // either box. the following tests are derived from:
- // "OBB Tree: A Hierarchical Structure for Rapid Interference Detection",
- // S.Gottschalk, M.C.Lin, D.Manocha., Proc of ACM Siggraph 1996.
-
- // Rij is R1'*R2, i.e. the relative rotation between R1 and R2.
- // Qij is abs(Rij)
- dVector3 p,pp;
- dReal A1,A2,A3,B1,B2,B3,R11,R12,R13,R21,R22,R23,R31,R32,R33,
- Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33;
-
- // get vector from centers of box 1 to box 2, relative to box 1
- p[0] = p2[0] - p1[0];
- p[1] = p2[1] - p1[1];
- p[2] = p2[2] - p1[2];
- dMULTIPLY1_331 (pp,R1,p); // get pp = p relative to body 1
-
- // get side lengths / 2
- A1 = side1[0]*REAL(0.5); A2 = side1[1]*REAL(0.5); A3 = side1[2]*REAL(0.5);
- B1 = side2[0]*REAL(0.5); B2 = side2[1]*REAL(0.5); B3 = side2[2]*REAL(0.5);
-
- // for the following tests, excluding computation of Rij, in the worst case,
- // 15 compares, 60 adds, 81 multiplies, and 24 absolutes.
- // notation: R1=[u1 u2 u3], R2=[v1 v2 v3]
-
- // separating axis = u1,u2,u3
- R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2);
- Q11 = dFabs(R11); Q12 = dFabs(R12); Q13 = dFabs(R13);
- if (dFabs(pp[0]) > (A1 + B1*Q11 + B2*Q12 + B3*Q13)) return 0;
- R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2);
- Q21 = dFabs(R21); Q22 = dFabs(R22); Q23 = dFabs(R23);
- if (dFabs(pp[1]) > (A2 + B1*Q21 + B2*Q22 + B3*Q23)) return 0;
- R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2);
- Q31 = dFabs(R31); Q32 = dFabs(R32); Q33 = dFabs(R33);
- if (dFabs(pp[2]) > (A3 + B1*Q31 + B2*Q32 + B3*Q33)) return 0;
-
- // separating axis = v1,v2,v3
- if (dFabs(dDOT41(R2+0,p)) > (A1*Q11 + A2*Q21 + A3*Q31 + B1)) return 0;
- if (dFabs(dDOT41(R2+1,p)) > (A1*Q12 + A2*Q22 + A3*Q32 + B2)) return 0;
- if (dFabs(dDOT41(R2+2,p)) > (A1*Q13 + A2*Q23 + A3*Q33 + B3)) return 0;
-
- // separating axis = u1 x (v1,v2,v3)
- if (dFabs(pp[2]*R21-pp[1]*R31) > A2*Q31 + A3*Q21 + B2*Q13 + B3*Q12) return 0;
- if (dFabs(pp[2]*R22-pp[1]*R32) > A2*Q32 + A3*Q22 + B1*Q13 + B3*Q11) return 0;
- if (dFabs(pp[2]*R23-pp[1]*R33) > A2*Q33 + A3*Q23 + B1*Q12 + B2*Q11) return 0;
-
- // separating axis = u2 x (v1,v2,v3)
- if (dFabs(pp[0]*R31-pp[2]*R11) > A1*Q31 + A3*Q11 + B2*Q23 + B3*Q22) return 0;
- if (dFabs(pp[0]*R32-pp[2]*R12) > A1*Q32 + A3*Q12 + B1*Q23 + B3*Q21) return 0;
- if (dFabs(pp[0]*R33-pp[2]*R13) > A1*Q33 + A3*Q13 + B1*Q22 + B2*Q21) return 0;
-
- // separating axis = u3 x (v1,v2,v3)
- if (dFabs(pp[1]*R11-pp[0]*R21) > A1*Q21 + A2*Q11 + B2*Q33 + B3*Q32) return 0;
- if (dFabs(pp[1]*R12-pp[0]*R22) > A1*Q22 + A2*Q12 + B1*Q33 + B3*Q31) return 0;
- if (dFabs(pp[1]*R13-pp[0]*R23) > A1*Q23 + A2*Q13 + B1*Q32 + B2*Q31) return 0;
-
- return 1;
-}
-
-
-// given two boxes (p1,R1,side1) and (p2,R2,side2), collide them together and
-// generate contact points. this returns 0 if there is no contact otherwise
-// it returns the number of contacts generated.
-// `normal' returns the contact normal.
-// `depth' returns the maximum penetration depth along that normal.
-// `code' returns a number indicating the type of contact that was detected:
-// 1,2,3 = box 2 intersects with a face of box 1
-// 4,5,6 = box 1 intersects with a face of box 2
-// 7..15 = edge-edge contact
-// `maxc' is the maximum number of contacts allowed to be generated, i.e.
-// the size of the `contact' array.
-// `contact' and `skip' are the contact array information provided to the
-// collision functions. this function only fills in the position and depth
-// fields.
-//
-// @@@ some stuff to optimize here, reuse code in contact point calculations.
-
-extern "C" int dBoxBox (const dVector3 p1, const dMatrix3 R1,
- const dVector3 side1, const dVector3 p2,
- const dMatrix3 R2, const dVector3 side2,
- dVector3 normal, dReal *depth, int *code,
- int maxc, dContactGeom *contact, int skip)
-{
- dVector3 p,pp,normalC;
- const dReal *normalR = 0;
- dReal A1,A2,A3,B1,B2,B3,R11,R12,R13,R21,R22,R23,R31,R32,R33,
- Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33,s,s2,l;
- int i,invert_normal;
-
- // get vector from centers of box 1 to box 2, relative to box 1
- p[0] = p2[0] - p1[0];
- p[1] = p2[1] - p1[1];
- p[2] = p2[2] - p1[2];
- dMULTIPLY1_331 (pp,R1,p); // get pp = p relative to body 1
-
- // get side lengths / 2
- A1 = side1[0]*REAL(0.5); A2 = side1[1]*REAL(0.5); A3 = side1[2]*REAL(0.5);
- B1 = side2[0]*REAL(0.5); B2 = side2[1]*REAL(0.5); B3 = side2[2]*REAL(0.5);
-
- // Rij is R1'*R2, i.e. the relative rotation between R1 and R2
- R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2);
- R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2);
- R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2);
-
- Q11 = dFabs(R11); Q12 = dFabs(R12); Q13 = dFabs(R13);
- Q21 = dFabs(R21); Q22 = dFabs(R22); Q23 = dFabs(R23);
- Q31 = dFabs(R31); Q32 = dFabs(R32); Q33 = dFabs(R33);
-
- // for all 15 possible separating axes:
- // * see if the axis separates the boxes. if so, return 0.
- // * find the depth of the penetration along the separating axis (s2)
- // * if this is the largest depth so far, record it.
- // the normal vector will be set to the separating axis with the smallest
- // depth. note: normalR is set to point to a column of R1 or R2 if that is
- // the smallest depth normal so far. otherwise normalR is 0 and normalC is
- // set to a vector relative to body 1. invert_normal is 1 if the sign of
- // the normal should be flipped.
-
-#define TEST(expr1,expr2,norm,cc) \
- s2 = dFabs(expr1) - (expr2); \
- if (s2 > 0) return 0; \
- if (s2 > s) { \
- s = s2; \
- normalR = norm; \
- invert_normal = ((expr1) < 0); \
- *code = (cc); \
- }
-
- s = -dInfinity;
- invert_normal = 0;
- *code = 0;
-
- // separating axis = u1,u2,u3
- TEST (pp[0],(A1 + B1*Q11 + B2*Q12 + B3*Q13),R1+0,1);
- TEST (pp[1],(A2 + B1*Q21 + B2*Q22 + B3*Q23),R1+1,2);
- TEST (pp[2],(A3 + B1*Q31 + B2*Q32 + B3*Q33),R1+2,3);
-
- // separating axis = v1,v2,v3
- TEST (dDOT41(R2+0,p),(A1*Q11 + A2*Q21 + A3*Q31 + B1),R2+0,4);
- TEST (dDOT41(R2+1,p),(A1*Q12 + A2*Q22 + A3*Q32 + B2),R2+1,5);
- TEST (dDOT41(R2+2,p),(A1*Q13 + A2*Q23 + A3*Q33 + B3),R2+2,6);
-
- // note: cross product axes need to be scaled when s is computed.
- // normal (n1,n2,n3) is relative to box 1.
-#undef TEST
-#define TEST(expr1,expr2,n1,n2,n3,cc) \
- s2 = dFabs(expr1) - (expr2); \
- if (s2 > 0) return 0; \
- l = dSqrt ((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \
- if (l > 0) { \
- s2 /= l; \
- if (s2 > s) { \
- s = s2; \
- normalR = 0; \
- normalC[0] = (n1)/l; normalC[1] = (n2)/l; normalC[2] = (n3)/l; \
- invert_normal = ((expr1) < 0); \
- *code = (cc); \
- } \
- }
-
- // separating axis = u1 x (v1,v2,v3)
- TEST(pp[2]*R21-pp[1]*R31,(A2*Q31+A3*Q21+B2*Q13+B3*Q12),0,-R31,R21,7);
- TEST(pp[2]*R22-pp[1]*R32,(A2*Q32+A3*Q22+B1*Q13+B3*Q11),0,-R32,R22,8);
- TEST(pp[2]*R23-pp[1]*R33,(A2*Q33+A3*Q23+B1*Q12+B2*Q11),0,-R33,R23,9);
-
- // separating axis = u2 x (v1,v2,v3)
- TEST(pp[0]*R31-pp[2]*R11,(A1*Q31+A3*Q11+B2*Q23+B3*Q22),R31,0,-R11,10);
- TEST(pp[0]*R32-pp[2]*R12,(A1*Q32+A3*Q12+B1*Q23+B3*Q21),R32,0,-R12,11);
- TEST(pp[0]*R33-pp[2]*R13,(A1*Q33+A3*Q13+B1*Q22+B2*Q21),R33,0,-R13,12);
-
- // separating axis = u3 x (v1,v2,v3)
- TEST(pp[1]*R11-pp[0]*R21,(A1*Q21+A2*Q11+B2*Q33+B3*Q32),-R21,R11,0,13);
- TEST(pp[1]*R12-pp[0]*R22,(A1*Q22+A2*Q12+B1*Q33+B3*Q31),-R22,R12,0,14);
- TEST(pp[1]*R13-pp[0]*R23,(A1*Q23+A2*Q13+B1*Q32+B2*Q31),-R23,R13,0,15);
-
-#undef TEST
-
- // if we get to this point, the boxes interpenetrate. compute the normal
- // in global coordinates.
- if (normalR) {
- normal[0] = normalR[0];
- normal[1] = normalR[4];
- normal[2] = normalR[8];
- }
- else {
- dMULTIPLY0_331 (normal,R1,normalC);
- }
- if (invert_normal) {
- normal[0] = -normal[0];
- normal[1] = -normal[1];
- normal[2] = -normal[2];
- }
- *depth = -s;
-
- // compute contact point(s)
-
- if (*code > 6) {
- // an edge from box 1 touches an edge from box 2.
- // find a point pa on the intersecting edge of box 1
- dVector3 pa;
- dReal sign;
- for (i=0; i<3; i++) pa[i] = p1[i];
- sign = (dDOT14(normal,R1+0) > 0) ? REAL(1.0) : REAL(-1.0);
- for (i=0; i<3; i++) pa[i] += sign * A1 * R1[i*4];
- sign = (dDOT14(normal,R1+1) > 0) ? REAL(1.0) : REAL(-1.0);
- for (i=0; i<3; i++) pa[i] += sign * A2 * R1[i*4+1];
- sign = (dDOT14(normal,R1+2) > 0) ? REAL(1.0) : REAL(-1.0);
- for (i=0; i<3; i++) pa[i] += sign * A3 * R1[i*4+2];
-
- // find a point pb on the intersecting edge of box 2
- dVector3 pb;
- for (i=0; i<3; i++) pb[i] = p2[i];
- sign = (dDOT14(normal,R2+0) > 0) ? REAL(-1.0) : REAL(1.0);
- for (i=0; i<3; i++) pb[i] += sign * B1 * R2[i*4];
- sign = (dDOT14(normal,R2+1) > 0) ? REAL(-1.0) : REAL(1.0);
- for (i=0; i<3; i++) pb[i] += sign * B2 * R2[i*4+1];
- sign = (dDOT14(normal,R2+2) > 0) ? REAL(-1.0) : REAL(1.0);
- for (i=0; i<3; i++) pb[i] += sign * B3 * R2[i*4+2];
-
- dReal alpha,beta;
- dVector3 ua,ub;
- for (i=0; i<3; i++) ua[i] = R1[((*code)-7)/3 + i*4];
- for (i=0; i<3; i++) ub[i] = R2[((*code)-7)%3 + i*4];
-
- lineClosestApproach (pa,ua,pb,ub,&alpha,&beta);
- for (i=0; i<3; i++) pa[i] += ua[i]*alpha;
- for (i=0; i<3; i++) pb[i] += ub[i]*beta;
-
- for (i=0; i<3; i++) contact[0].pos[i] = REAL(0.5)*(pa[i]+pb[i]);
- contact[0].depth = *depth;
- return 1;
- }
-
- // okay, we have a face-something intersection (because the separating
- // axis is perpendicular to a face).
-
- // @@@ temporary: make deepest vertex on the "other" box the contact point.
- // @@@ this kind of works, but we need multiple contact points for stability,
- // @@@ especially for face-face contact.
-
- dVector3 vertex;
- if (*code <= 3) {
- // face from box 1 touches a vertex/edge/face from box 2.
- dReal sign;
- for (i=0; i<3; i++) vertex[i] = p2[i];
- sign = (dDOT14(normal,R2+0) > 0) ? REAL(-1.0) : REAL(1.0);
- for (i=0; i<3; i++) vertex[i] += sign * B1 * R2[i*4];
- sign = (dDOT14(normal,R2+1) > 0) ? REAL(-1.0) : REAL(1.0);
- for (i=0; i<3; i++) vertex[i] += sign * B2 * R2[i*4+1];
- sign = (dDOT14(normal,R2+2) > 0) ? REAL(-1.0) : REAL(1.0);
- for (i=0; i<3; i++) vertex[i] += sign * B3 * R2[i*4+2];
- }
- else {
- // face from box 2 touches a vertex/edge/face from box 1.
- dReal sign;
- for (i=0; i<3; i++) vertex[i] = p1[i];
- sign = (dDOT14(normal,R1+0) > 0) ? REAL(1.0) : REAL(-1.0);
- for (i=0; i<3; i++) vertex[i] += sign * A1 * R1[i*4];
- sign = (dDOT14(normal,R1+1) > 0) ? REAL(1.0) : REAL(-1.0);
- for (i=0; i<3; i++) vertex[i] += sign * A2 * R1[i*4+1];
- sign = (dDOT14(normal,R1+2) > 0) ? REAL(1.0) : REAL(-1.0);
- for (i=0; i<3; i++) vertex[i] += sign * A3 * R1[i*4+2];
- }
- for (i=0; i<3; i++) contact[0].pos[i] = vertex[i];
- contact[0].depth = *depth;
- return 1;
-}
-
-//****************************************************************************
-// general support for geometry objects and classes
-
-struct dColliderEntry {
- dColliderFn *fn; // collider function
- int mode; // 1 = reverse o1 and o2, 2 = no function available
-};
-
-static dArray<dxGeomClass*> *classes=0;
-
-// function pointers and modes for n^2 class collider functions. this is an
-// n*n matrix stored by row. the functions pointers are extracted from the
-// class get-collider-function function.
-static dArray<dColliderEntry> *colliders=0;
-
-
-static inline void initCollisionArrays()
-{
- if (classes==0) {
- // old way:
- // classes = (dArray<dxGeomClass*> *) dAllocNoFree (sizeof(dArrayBase));
- // classes->constructor();
- classes = new dArray<dxGeomClass*>;
- classes->setSize (1); // force allocation of array data memory
- dAllocDontReport (classes);
- dAllocDontReport (classes->data());
- classes->setSize (0);
- }
- if (colliders==0) {
- // old way:
- // colliders=(dArray<dColliderEntry> *)dAllocNoFree (sizeof(dArrayBase));
- // colliders->constructor();
- colliders = new dArray<dColliderEntry>;
- colliders->setSize (1); // force allocation of array data memory
- dAllocDontReport (colliders);
- dAllocDontReport (colliders->data());
- colliders->setSize (0);
- }
-}
-
-
-int dCreateGeomClass (const dGeomClass *c)
-{
- dUASSERT(c && c->bytes >= 0 && c->collider && c->aabb,"bad geom class");
- initCollisionArrays();
-
- int n = classes->size();
- dxGeomClass *gc = (dxGeomClass*) dAlloc (sizeof(dxGeomClass));
- dAllocDontReport (gc);
- gc->collider = c->collider;
- gc->aabb = c->aabb;
- gc->aabb_test = c->aabb_test;
- gc->dtor = c->dtor;
- gc->num = n;
- gc->size = SIZEOF_DXGEOM + c->bytes;
- classes->push (gc);
-
- // make room for n^2 class collider function pointers - these entries will
- // be filled as dCollide() is called.
- colliders->setSize ((n+1)*(n+1));
- memset (colliders->data(),0,(n+1)*(n+1)*sizeof(dColliderEntry));
-
- return n;
-}
-
-
-int dCollide (dxGeom *o1, dxGeom *o2, int flags, dContactGeom *contact,
- int skip)
-{
- int i,c1,c2,a1,a2,count,swap;
- dColliderFn *fn;
- dAASSERT(o1 && o2 && contact);
- dUASSERT(classes && colliders,"no registered geometry classes");
-
- // no contacts if both geoms on the same body, and the body is not 0
- if (o1->body == o2->body && o1->body) return 0;
-
- dColliderEntry *colliders2 = colliders->data();
- c1 = o1->_class->num;
- c2 = o2->_class->num;
- a1 = c1 * classes->size() + c2; // address 1 in collider array
- a2 = c2 * classes->size() + c1; // address 2 in collider array
- swap = 0; // set to 1 to swap normals before returning
-
- // return if there are no collider functions available
- if ((colliders2[a1].mode==2) || (colliders2[a2].mode==2)) return 0;
-
- if ((fn = colliders2[a1].fn)) {
- swap = colliders2[a1].mode;
- if (swap) count = (*fn) (o2,o1,flags,contact,skip);
- else count = (*fn) (o1,o2,flags,contact,skip);
- }
- else if ((fn = (*classes)[c1]->collider (c2))) {
- colliders2 [a2].fn = fn;
- colliders2 [a2].mode = 1;
- colliders2 [a1].fn = fn; // do mode=0 assignment second so that
- colliders2 [a1].mode = 0; // diagonal entries will have mode 0
- count = (*fn) (o1,o2,flags,contact,skip);
- swap = 0;
- }
- else if ((fn = (*classes)[c2]->collider (c1))) {
- colliders2 [a1].fn = fn;
- colliders2 [a1].mode = 1;
- colliders2 [a2].fn = fn; // do mode=0 assignment second so that
- colliders2 [a2].mode = 0; // diagonal entries will have mode 0
- count = (*fn) (o2,o1,flags,contact,skip);
- swap = 1;
- }
- else {
- colliders2[a1].mode = 2;
- colliders2[a2].mode = 2;
- return 0;
- }
-
- if (swap) {
- for (i=0; i<count; i++) {
- dContactGeom *c = CONTACT(contact,skip*i);
- c->normal[0] = -c->normal[0];
- c->normal[1] = -c->normal[1];
- c->normal[2] = -c->normal[2];
- dxGeom *tmp = c->g1;
- c->g1 = c->g2;
- c->g2 = tmp;
- }
- }
-
- return count;
-}
-
-
-int dGeomGetClass (dxGeom *g)
-{
- dAASSERT (g);
- return g->_class->num;
-}
-
-
-void dGeomSetData (dxGeom *g, void *data)
-{
- dAASSERT (g);
- g->data = data;
-}
-
-
-void *dGeomGetData (dxGeom *g)
-{
- dAASSERT (g);
- return g->data;
-}
-
-
-void dGeomSetBody (dxGeom *g, dBodyID b)
-{
- dAASSERT (g);
- if (b) {
- if (!g->body) dFree (g->pos,sizeof(dxPosR));
- g->body = b;
- g->pos = b->pos;
- g->R = b->R;
- }
- else {
- if (g->body) {
- dxPosR *pr = (dxPosR*) dAlloc (sizeof(dxPosR));
- g->pos = pr->pos;
- g->R = pr->R;
- memcpy (g->pos,g->body->pos,sizeof(g->pos));
- memcpy (g->R,g->body->R,sizeof(g->R));
- g->body = 0;
- }
- }
-}
-
-
-dBodyID dGeomGetBody (dxGeom *g)
-{
- dAASSERT (g);
- return g->body;
-}
-
-
-void dGeomSetPosition (dxGeom *g, dReal x, dReal y, dReal z)
-{
- dAASSERT (g);
- if (g->body) dBodySetPosition (g->body,x,y,z);
- else {
- g->pos[0] = x;
- g->pos[1] = y;
- g->pos[2] = z;
- }
-}
-
-
-void dGeomSetRotation (dxGeom *g, const dMatrix3 R)
-{
- dAASSERT (g);
- if (g->body) dBodySetRotation (g->body,R);
- else memcpy (g->R,R,sizeof(dMatrix3));
-}
-
-
-const dReal * dGeomGetPosition (dxGeom *g)
-{
- dAASSERT (g);
- return g->pos;
-}
-
-
-const dReal * dGeomGetRotation (dxGeom *g)
-{
- dAASSERT (g);
- return g->R;
-}
-
-
-// for external use only. use the CLASSDATA macro inside ODE.
-
-void * dGeomGetClassData (dxGeom *g)
-{
- dAASSERT (g);
- return (void*) CLASSDATA(g);
-}
-
-
-dxGeom * dCreateGeom (int classnum)
-{
- dUASSERT (classes && colliders && classnum >= 0 &&
- classnum < classes->size(),"bad class number");
- int size = (*classes)[classnum]->size;
- dxGeom *geom = (dxGeom*) dAlloc (size);
- memset (geom,0,size); // everything is initially zeroed
-
- geom->_class = (*classes)[classnum];
- geom->data = 0;
- geom->body = 0;
-
- dxPosR *pr = (dxPosR*) dAlloc (sizeof(dxPosR));
- geom->pos = pr->pos;
- geom->R = pr->R;
- dSetZero (geom->pos,4);
- dRSetIdentity (geom->R);
-
- return geom;
-}
-
-
-void dGeomDestroy (dxGeom *g)
-{
- dAASSERT (g);
- if (g->spaceid) dSpaceRemove (g->spaceid,g);
- if (g->_class->dtor) g->_class->dtor (g);
- if (!g->body) dFree (g->pos,sizeof(dxPosR));
- dFree (g,g->_class->size);
-}
-
-
-void dGeomGetAABB (dxGeom *g, dReal aabb[6])
-{
- dAASSERT (g);
- g->_class->aabb (g,aabb);
-}
-
-
-dReal *dGeomGetSpaceAABB (dxGeom *g)
-{
- dAASSERT (g);
- return g->space_aabb;
-}
-
-//****************************************************************************
-// data for the standard classes
-
-struct dxSphere {
- dReal radius; // sphere radius
-};
-
-struct dxBox {
- dVector3 side; // side lengths (x,y,z)
-};
-
-struct dxCCylinder { // capped cylinder
- dReal radius,lz; // radius, length along z axis */
-};
-
-struct dxPlane {
- dReal p[4];
-};
-
-struct dxGeomGroup {
- dArray<dxGeom*> parts; // all the geoms that make up the group
-};
-
-//****************************************************************************
-// primitive collision functions
-// same interface as dCollide().
-// S=sphere, B=box, C=capped cylinder, P=plane, G=group, T=transform
-
-int dCollideSS (const dxGeom *o1, const dxGeom *o2, int flags,
- dContactGeom *contact, int skip)
-{
- dIASSERT (skip >= (int)sizeof(dContactGeom));
- dIASSERT (o1->_class->num == dSphereClass);
- dIASSERT (o2->_class->num == dSphereClass);
- dxSphere *s1 = (dxSphere*) CLASSDATA(o1);
- dxSphere *s2 = (dxSphere*) CLASSDATA(o2);
- contact->g1 = const_cast<dxGeom*> (o1);
- contact->g2 = const_cast<dxGeom*> (o2);
- return dCollideSpheres (o1->pos,s1->radius,
- o2->pos,s2->radius,contact);
-}
-
-
-int dCollideSB (const dxGeom *o1, const dxGeom *o2, int flags,
- dContactGeom *contact, int skip)
-{
- // this is easy. get the sphere center `p' relative to the box, and then clip
- // that to the boundary of the box (call that point `q'). if q is on the
- // boundary of the box and |p-q| is <= sphere radius, they touch.
- // if q is inside the box, the sphere is inside the box, so set a contact
- // normal to push the sphere to the closest box edge.
-
- dVector3 l,t,p,q,r;
- dReal depth;
- int onborder = 0;
-
- dIASSERT (skip >= (int)sizeof(dContactGeom));
- dIASSERT (o1->_class->num == dSphereClass);
- dIASSERT (o2->_class->num == dBoxClass);
- dxSphere *sphere = (dxSphere*) CLASSDATA(o1);
- dxBox *box = (dxBox*) CLASSDATA(o2);
-
- contact->g1 = const_cast<dxGeom*> (o1);
- contact->g2 = const_cast<dxGeom*> (o2);
-
- p[0] = o1->pos[0] - o2->pos[0];
- p[1] = o1->pos[1] - o2->pos[1];
- p[2] = o1->pos[2] - o2->pos[2];
-
- l[0] = box->side[0]*REAL(0.5);
- t[0] = dDOT14(p,o2->R);
- if (t[0] < -l[0]) { t[0] = -l[0]; onborder = 1; }
- if (t[0] > l[0]) { t[0] = l[0]; onborder = 1; }
-
- l[1] = box->side[1]*REAL(0.5);
- t[1] = dDOT14(p,o2->R+1);
- if (t[1] < -l[1]) { t[1] = -l[1]; onborder = 1; }
- if (t[1] > l[1]) { t[1] = l[1]; onborder = 1; }
-
- t[2] = dDOT14(p,o2->R+2);
- l[2] = box->side[2]*REAL(0.5);
- if (t[2] < -l[2]) { t[2] = -l[2]; onborder = 1; }
- if (t[2] > l[2]) { t[2] = l[2]; onborder = 1; }
-
- if (!onborder) {
- // sphere center inside box. find largest `t' value
- dReal max = dFabs(t[0]);
- int maxi = 0;
- for (int i=1; i<3; i++) {
- dReal tt = dFabs(t[i]);
- if (tt > max) {
- max = tt;
- maxi = i;
- }
- }
- // contact position = sphere center
- contact->pos[0] = o1->pos[0];
- contact->pos[1] = o1->pos[1];
- contact->pos[2] = o1->pos[2];
- // contact normal aligned with box edge along largest `t' value
- dVector3 tmp;
- tmp[0] = 0;
- tmp[1] = 0;
- tmp[2] = 0;
- tmp[maxi] = (t[maxi] > 0) ? REAL(1.0) : REAL(-1.0);
- dMULTIPLY0_331 (contact->normal,o2->R,tmp);
- // contact depth = distance to wall along normal plus radius
- contact->depth = l[maxi] - max + sphere->radius;
- return 1;
- }
-
- t[3] = 0; //@@@ hmmm
- dMULTIPLY0_331 (q,o2->R,t);
- r[0] = p[0] - q[0];
- r[1] = p[1] - q[1];
- r[2] = p[2] - q[2];
- depth = sphere->radius - dSqrt(dDOT(r,r));
- if (depth < 0) return 0;
- contact->pos[0] = q[0] + o2->pos[0];
- contact->pos[1] = q[1] + o2->pos[1];
- contact->pos[2] = q[2] + o2->pos[2];
- contact->normal[0] = r[0];
- contact->normal[1] = r[1];
- contact->normal[2] = r[2];
- dNormalize3 (contact->normal);
- contact->depth = depth;
- return 1;
-}
-
-
-int dCollideSP (const dxGeom *o1, const dxGeom *o2, int flags,
- dContactGeom *contact, int skip)
-{
- dIASSERT (skip >= (int)sizeof(dContactGeom));
- dIASSERT (o1->_class->num == dSphereClass);
- dIASSERT (o2->_class->num == dPlaneClass);
- contact->g1 = const_cast<dxGeom*> (o1);
- contact->g2 = const_cast<dxGeom*> (o2);
- dxSphere *sphere = (dxSphere*) CLASSDATA(o1);
- dxPlane *plane = (dxPlane*) CLASSDATA(o2);
- dReal k = dDOT (o1->pos,plane->p);
- dReal depth = plane->p[3] - k + sphere->radius;
- if (depth >= 0) {
- contact->normal[0] = plane->p[0];
- contact->normal[1] = plane->p[1];
- contact->normal[2] = plane->p[2];
- contact->pos[0] = o1->pos[0] - plane->p[0] * sphere->radius;
- contact->pos[1] = o1->pos[1] - plane->p[1] * sphere->radius;
- contact->pos[2] = o1->pos[2] - plane->p[2] * sphere->radius;
- contact->depth = depth;
- return 1;
- }
- else return 0;
-}
-
-
-int dCollideBB (const dxGeom *o1, const dxGeom *o2, int flags,
- dContactGeom *contact, int skip)
-{
- dVector3 normal;
- dReal depth;
- int code;
- dxBox *b1 = (dxBox*) CLASSDATA(o1);
- dxBox *b2 = (dxBox*) CLASSDATA(o2);
- int num = dBoxBox (o1->pos,o1->R,b1->side, o2->pos,o2->R,b2->side,
- normal,&depth,&code,flags & NUMC_MASK,contact,skip);
- for (int i=0; i<num; i++) {
- CONTACT(contact,i*skip)->normal[0] = -normal[0];
- CONTACT(contact,i*skip)->normal[1] = -normal[1];
- CONTACT(contact,i*skip)->normal[2] = -normal[2];
- CONTACT(contact,i*skip)->g1 = const_cast<dxGeom*> (o1);
- CONTACT(contact,i*skip)->g2 = const_cast<dxGeom*> (o2);
- }
- return num;
-}
-
-
-int dCollideBP (const dxGeom *o1, const dxGeom *o2,
- int flags, dContactGeom *contact, int skip)
-{
- dIASSERT (skip >= (int)sizeof(dContactGeom));
- dIASSERT (o1->_class->num == dBoxClass);
- dIASSERT (o2->_class->num == dPlaneClass);
- contact->g1 = const_cast<dxGeom*> (o1);
- contact->g2 = const_cast<dxGeom*> (o2);
- dxBox *box = (dxBox*) CLASSDATA(o1);
- dxPlane *plane = (dxPlane*) CLASSDATA(o2);
- int ret = 0;
-
- //@@@ problem: using 4-vector (plane->p) as 3-vector (normal).
- const dReal *R = o1->R; // rotation of box
- const dReal *n = plane->p; // normal vector
-
- // project sides lengths along normal vector, get absolute values
- dReal Q1 = dDOT14(n,R+0);
- dReal Q2 = dDOT14(n,R+1);
- dReal Q3 = dDOT14(n,R+2);
- dReal A1 = box->side[0] * Q1;
- dReal A2 = box->side[1] * Q2;
- dReal A3 = box->side[2] * Q3;
- dReal B1 = dFabs(A1);
- dReal B2 = dFabs(A2);
- dReal B3 = dFabs(A3);
-
- // early exit test
- dReal depth = plane->p[3] + REAL(0.5)*(B1+B2+B3) - dDOT(n,o1->pos);
- if (depth < 0) return 0;
-
- // find number of contacts requested
- int maxc = flags & NUMC_MASK;
- if (maxc < 1) maxc = 1;
- if (maxc > 3) maxc = 3; // no more than 3 contacts per box allowed
-
- // find deepest point
- dVector3 p;
- p[0] = o1->pos[0];
- p[1] = o1->pos[1];
- p[2] = o1->pos[2];
-#define FOO(i,op) \
- p[0] op REAL(0.5)*box->side[i] * R[0+i]; \
- p[1] op REAL(0.5)*box->side[i] * R[4+i]; \
- p[2] op REAL(0.5)*box->side[i] * R[8+i];
-#define BAR(i,iinc) if (A ## iinc > 0) { FOO(i,-=) } else { FOO(i,+=) }
- BAR(0,1);
- BAR(1,2);
- BAR(2,3);
-#undef FOO
-#undef BAR
-
- // the deepest point is the first contact point
- contact->pos[0] = p[0];
- contact->pos[1] = p[1];
- contact->pos[2] = p[2];
- contact->normal[0] = n[0];
- contact->normal[1] = n[1];
- contact->normal[2] = n[2];
- contact->depth = depth;
- ret = 1; // ret is number of contact points found so far
- if (maxc == 1) goto done;
-
- // get the second and third contact points by starting from `p' and going
- // along the two sides with the smallest projected length.
-
-#define FOO(i,j,op) \
- CONTACT(contact,i*skip)->pos[0] = p[0] op box->side[j] * R[0+j]; \
- CONTACT(contact,i*skip)->pos[1] = p[1] op box->side[j] * R[4+j]; \
- CONTACT(contact,i*skip)->pos[2] = p[2] op box->side[j] * R[8+j];
-#define BAR(ctact,side,sideinc) \
- depth -= B ## sideinc; \
- if (depth < 0) goto done; \
- if (A ## sideinc > 0) { FOO(ctact,side,+) } else { FOO(ctact,side,-) } \
- CONTACT(contact,ctact*skip)->depth = depth; \
- ret++;
-
- CONTACT(contact,skip)->normal[0] = n[0];
- CONTACT(contact,skip)->normal[1] = n[1];
- CONTACT(contact,skip)->normal[2] = n[2];
- if (maxc == 3) {
- CONTACT(contact,2*skip)->normal[0] = n[0];
- CONTACT(contact,2*skip)->normal[1] = n[1];
- CONTACT(contact,2*skip)->normal[2] = n[2];
- }
-
- if (B1 < B2) {
- if (B3 < B1) goto use_side_3; else {
- BAR(1,0,1); // use side 1
- if (maxc == 2) goto done;
- if (B2 < B3) goto contact2_2; else goto contact2_3;
- }
- }
- else {
- if (B3 < B2) {
- use_side_3: // use side 3
- BAR(1,2,3);
- if (maxc == 2) goto done;
- if (B1 < B2) goto contact2_1; else goto contact2_2;
- }
- else {
- BAR(1,1,2); // use side 2
- if (maxc == 2) goto done;
- if (B1 < B3) goto contact2_1; else goto contact2_3;
- }
- }
-
- contact2_1: BAR(2,0,1); goto done;
- contact2_2: BAR(2,1,2); goto done;
- contact2_3: BAR(2,2,3); goto done;
-#undef FOO
-#undef BAR
-
- done:
- for (int i=0; i<ret; i++) {
- CONTACT(contact,i*skip)->g1 = const_cast<dxGeom*> (o1);
- CONTACT(contact,i*skip)->g2 = const_cast<dxGeom*> (o2);
- }
- return ret;
-}
-
-
-int dCollideCS (const dxGeom *o1, const dxGeom *o2, int flags,
- dContactGeom *contact, int skip)
-{
- dIASSERT (skip >= (int)sizeof(dContactGeom));
- dIASSERT (o1->_class->num == dCCylinderClass);
- dIASSERT (o2->_class->num == dSphereClass);
- contact->g1 = const_cast<dxGeom*> (o1);
- contact->g2 = const_cast<dxGeom*> (o2);
- dxCCylinder *ccyl = (dxCCylinder*) CLASSDATA(o1);
- dxSphere *sphere = (dxSphere*) CLASSDATA(o2);
-
- // find the point on the cylinder axis that is closest to the sphere
- dReal alpha =
- o1->R[2] * (o2->pos[0] - o1->pos[0]) +
- o1->R[6] * (o2->pos[1] - o1->pos[1]) +
- o1->R[10] * (o2->pos[2] - o1->pos[2]);
- dReal lz2 = ccyl->lz * REAL(0.5);
- if (alpha > lz2) alpha = lz2;
- if (alpha < -lz2) alpha = -lz2;
-
- // collide the spheres
- dVector3 p;
- p[0] = o1->pos[0] + alpha * o1->R[2];
- p[1] = o1->pos[1] + alpha * o1->R[6];
- p[2] = o1->pos[2] + alpha * o1->R[10];
- return dCollideSpheres (p,ccyl->radius,o2->pos,sphere->radius,contact);
-}
-
-
-int dCollideCB (const dxGeom *o1, const dxGeom *o2, int flags,
- dContactGeom *contact, int skip)
-{
- dIASSERT (skip >= (int)sizeof(dContactGeom));
- dIASSERT (o1->_class->num == dCCylinderClass);
- dIASSERT (o2->_class->num == dBoxClass);
- contact->g1 = const_cast<dxGeom*> (o1);
- contact->g2 = const_cast<dxGeom*> (o2);
- dxCCylinder *cyl = (dxCCylinder*) CLASSDATA(o1);
- dxBox *box = (dxBox*) CLASSDATA(o2);
-
- // get p1,p2 = cylinder axis endpoints, get radius
- dVector3 p1,p2;
- dReal clen = cyl->lz * REAL(0.5);
- p1[0] = o1->pos[0] + clen * o1->R[2];
- p1[1] = o1->pos[1] + clen * o1->R[6];
- p1[2] = o1->pos[2] + clen * o1->R[10];
- p2[0] = o1->pos[0] - clen * o1->R[2];
- p2[1] = o1->pos[1] - clen * o1->R[6];
- p2[2] = o1->pos[2] - clen * o1->R[10];
- dReal radius = cyl->radius;
-
- // copy out box center, rotation matrix, and side array
- dReal *c = o2->pos;
- dReal *R = o2->R;
- dReal *side = box->side;
-
- // get the closest point between the cylinder axis and the box
- dVector3 pl,pb;
- dClosestLineBoxPoints (p1,p2,c,R,side,pl,pb);
-
- // generate contact point
- return dCollideSpheres (pl,radius,pb,0,contact);
-}
-
-
-// this returns at most one contact point when the two cylinder's axes are not
-// aligned, and at most two (for stability) when they are aligned.
-// the algorithm minimizes the distance between two "sample spheres" that are
-// positioned along the cylinder axes according to:
-// sphere1 = pos1 + alpha1 * axis1
-// sphere2 = pos2 + alpha2 * axis2
-// alpha1 and alpha2 are limited to +/- half the length of the cylinders.
-// the algorithm works by finding a solution that has both alphas free, or
-// a solution that has one or both alphas fixed to the ends of the cylinder.
-
-int dCollideCC (const dxGeom *o1, const dxGeom *o2,
- int flags, dContactGeom *contact, int skip)
-{
- int i;
- const dReal tolerance = REAL(1e-5);
-
- dIASSERT (skip >= (int)sizeof(dContactGeom));
- dIASSERT (o1->_class->num == dCCylinderClass);
- dIASSERT (o2->_class->num == dCCylinderClass);
- contact->g1 = const_cast<dxGeom*> (o1);
- contact->g2 = const_cast<dxGeom*> (o2);
- dxCCylinder *cyl1 = (dxCCylinder*) CLASSDATA(o1);
- dxCCylinder *cyl2 = (dxCCylinder*) CLASSDATA(o2);
-
- // copy out some variables, for convenience
- dReal lz1 = cyl1->lz * REAL(0.5);
- dReal lz2 = cyl2->lz * REAL(0.5);
- dReal *pos1 = o1->pos;
- dReal *pos2 = o2->pos;
- dReal axis1[3],axis2[3];
- axis1[0] = o1->R[2];
- axis1[1] = o1->R[6];
- axis1[2] = o1->R[10];
- axis2[0] = o2->R[2];
- axis2[1] = o2->R[6];
- axis2[2] = o2->R[10];
-
- dReal alpha1,alpha2,sphere1[3],sphere2[3];
- int fix1 = 0; // 0 if alpha1 is free, +/-1 to fix at +/- lz1
- int fix2 = 0; // 0 if alpha2 is free, +/-1 to fix at +/- lz2
-
- for (int count=0; count<9; count++) {
- // find a trial solution by fixing or not fixing the alphas
- if (fix1) {
- if (fix2) {
- // alpha1 and alpha2 are fixed, so the solution is easy
- if (fix1 > 0) alpha1 = lz1; else alpha1 = -lz1;
- if (fix2 > 0) alpha2 = lz2; else alpha2 = -lz2;
- for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i];
- for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i];
- }
- else {
- // fix alpha1 but let alpha2 be free
- if (fix1 > 0) alpha1 = lz1; else alpha1 = -lz1;
- for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i];
- alpha2 = (axis2[0]*(sphere1[0]-pos2[0]) +
- axis2[1]*(sphere1[1]-pos2[1]) +
- axis2[2]*(sphere1[2]-pos2[2]));
- for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i];
- }
- }
- else {
- if (fix2) {
- // fix alpha2 but let alpha1 be free
- if (fix2 > 0) alpha2 = lz2; else alpha2 = -lz2;
- for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i];
- alpha1 = (axis1[0]*(sphere2[0]-pos1[0]) +
- axis1[1]*(sphere2[1]-pos1[1]) +
- axis1[2]*(sphere2[2]-pos1[2]));
- for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i];
- }
- else {
- // let alpha1 and alpha2 be free
- // compute determinant of d(d^2)\d(alpha) jacobian
- dReal a1a2 = dDOT (axis1,axis2);
- dReal det = REAL(1.0)-a1a2*a1a2;
- if (det < tolerance) {
- // the cylinder axes (almost) parallel, so we will generate up to two
- // contacts. the solution matrix is rank deficient so alpha1 and
- // alpha2 are related by:
- // alpha2 = alpha1 + (pos1-pos2)'*axis1 (if axis1==axis2)
- // or alpha2 = -(alpha1 + (pos1-pos2)'*axis1) (if axis1==-axis2)
- // first compute where the two cylinders overlap in alpha1 space:
- if (a1a2 < 0) {
- axis2[0] = -axis2[0];
- axis2[1] = -axis2[1];
- axis2[2] = -axis2[2];
- }
- dReal q[3];
- for (i=0; i<3; i++) q[i] = pos1[i]-pos2[i];
- dReal k = dDOT (axis1,q);
- dReal a1lo = -lz1;
- dReal a1hi = lz1;
- dReal a2lo = -lz2 - k;
- dReal a2hi = lz2 - k;
- dReal lo = (a1lo > a2lo) ? a1lo : a2lo;
- dReal hi = (a1hi < a2hi) ? a1hi : a2hi;
- if (lo <= hi) {
- int num_contacts = flags & NUMC_MASK;
- if (num_contacts >= 2 && lo < hi) {
- // generate up to two contacts. if one of those contacts is
- // not made, fall back on the one-contact strategy.
- for (i=0; i<3; i++) sphere1[i] = pos1[i] + lo*axis1[i];
- for (i=0; i<3; i++) sphere2[i] = pos2[i] + (lo+k)*axis2[i];
- int n1 = dCollideSpheres (sphere1,cyl1->radius,
- sphere2,cyl2->radius,contact);
- if (n1) {
- for (i=0; i<3; i++) sphere1[i] = pos1[i] + hi*axis1[i];
- for (i=0; i<3; i++) sphere2[i] = pos2[i] + (hi+k)*axis2[i];
- dContactGeom *c2 = CONTACT(contact,skip);
- int n2 = dCollideSpheres (sphere1,cyl1->radius,
- sphere2,cyl2->radius, c2);
- if (n2) {
- c2->g1 = const_cast<dxGeom*> (o1);
- c2->g2 = const_cast<dxGeom*> (o2);
- return 2;
- }
- }
- }
-
- // just one contact to generate, so put it in the middle of
- // the range
- alpha1 = (lo + hi) * REAL(0.5);
- alpha2 = alpha1 + k;
- for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i];
- for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i];
- return dCollideSpheres (sphere1,cyl1->radius,
- sphere2,cyl2->radius,contact);
- }
- else return 0;
- }
- det = REAL(1.0)/det;
- dReal delta[3];
- for (i=0; i<3; i++) delta[i] = pos1[i] - pos2[i];
- dReal q1 = dDOT (delta,axis1);
- dReal q2 = dDOT (delta,axis2);
- alpha1 = det*(a1a2*q2-q1);
- alpha2 = det*(q2-a1a2*q1);
- for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i];
- for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i];
- }
- }
-
- // if the alphas are outside their allowed ranges then fix them and
- // try again
- if (fix1==0) {
- if (alpha1 < -lz1) {
- fix1 = -1;
- continue;
- }
- if (alpha1 > lz1) {
- fix1 = 1;
- continue;
- }
- }
- if (fix2==0) {
- if (alpha2 < -lz2) {
- fix2 = -1;
- continue;
- }
- if (alpha2 > lz2) {
- fix2 = 1;
- continue;
- }
- }
-
- // unfix the alpha variables if the local distance gradient indicates
- // that we are not yet at the minimum
- dReal tmp[3];
- for (i=0; i<3; i++) tmp[i] = sphere1[i] - sphere2[i];
- if (fix1) {
- dReal gradient = dDOT (tmp,axis1);
- if ((fix1 > 0 && gradient > 0) || (fix1 < 0 && gradient < 0)) {
- fix1 = 0;
- continue;
- }
- }
- if (fix2) {
- dReal gradient = -dDOT (tmp,axis2);
- if ((fix2 > 0 && gradient > 0) || (fix2 < 0 && gradient < 0)) {
- fix2 = 0;
- continue;
- }
- }
- return dCollideSpheres (sphere1,cyl1->radius,sphere2,cyl2->radius,contact);
- }
- // if we go through the loop too much, then give up. we should NEVER get to
- // this point (i hope).
- dMessage (0,"dCollideCC(): too many iterations");
- return 0;
-}
-
-
-int dCollideCP (const dxGeom *o1, const dxGeom *o2, int flags,
- dContactGeom *contact, int skip)
-{
- dIASSERT (skip >= (int)sizeof(dContactGeom));
- dIASSERT (o1->_class->num == dCCylinderClass);
- dIASSERT (o2->_class->num == dPlaneClass);
- dxCCylinder *ccyl = (dxCCylinder*) CLASSDATA(o1);
- dxPlane *plane = (dxPlane*) CLASSDATA(o2);
-
- // collide the deepest capping sphere with the plane
- dReal sign = (dDOT14 (plane->p,o1->R+2) > 0) ? REAL(-1.0) : REAL(1.0);
- dVector3 p;
- p[0] = o1->pos[0] + o1->R[2] * ccyl->lz * REAL(0.5) * sign;
- p[1] = o1->pos[1] + o1->R[6] * ccyl->lz * REAL(0.5) * sign;
- p[2] = o1->pos[2] + o1->R[10] * ccyl->lz * REAL(0.5) * sign;
-
- dReal k = dDOT (p,plane->p);
- dReal depth = plane->p[3] - k + ccyl->radius;
- if (depth < 0) return 0;
- contact->normal[0] = plane->p[0];
- contact->normal[1] = plane->p[1];
- contact->normal[2] = plane->p[2];
- contact->pos[0] = p[0] - plane->p[0] * ccyl->radius;
- contact->pos[1] = p[1] - plane->p[1] * ccyl->radius;
- contact->pos[2] = p[2] - plane->p[2] * ccyl->radius;
- contact->depth = depth;
-
- int ncontacts = 1;
- if ((flags & NUMC_MASK) >= 2) {
- // collide the other capping sphere with the plane
- p[0] = o1->pos[0] - o1->R[2] * ccyl->lz * REAL(0.5) * sign;
- p[1] = o1->pos[1] - o1->R[6] * ccyl->lz * REAL(0.5) * sign;
- p[2] = o1->pos[2] - o1->R[10] * ccyl->lz * REAL(0.5) * sign;
-
- k = dDOT (p,plane->p);
- depth = plane->p[3] - k + ccyl->radius;
- if (depth >= 0) {
- dContactGeom *c2 = CONTACT(contact,skip);
- c2->normal[0] = plane->p[0];
- c2->normal[1] = plane->p[1];
- c2->normal[2] = plane->p[2];
- c2->pos[0] = p[0] - plane->p[0] * ccyl->radius;
- c2->pos[1] = p[1] - plane->p[1] * ccyl->radius;
- c2->pos[2] = p[2] - plane->p[2] * ccyl->radius;
- c2->depth = depth;
- ncontacts = 2;
- }
- }
-
- for (int i=0; i < ncontacts; i++) {
- CONTACT(contact,i*skip)->g1 = const_cast<dxGeom*> (o1);
- CONTACT(contact,i*skip)->g2 = const_cast<dxGeom*> (o2);
- }
- return ncontacts;
-}
-
-
-// this collides a group with another geom. the other geom can also be a
-// group, but this case is not handled specially.
-
-int dCollideG (const dxGeom *o1, const dxGeom *o2, int flags,
- dContactGeom *contact, int skip)
-{
- dxGeomGroup *gr = (dxGeomGroup*) CLASSDATA(o1);
- int numleft = flags & NUMC_MASK;
- if (numleft == 0) numleft = 1;
- flags &= ~NUMC_MASK;
- int num=0,i=0;
- while (i < gr->parts.size() && numleft > 0) {
- int n = dCollide (gr->parts[i],const_cast<dxGeom*>(o2),
- flags | numleft,contact,skip);
- contact = CONTACT (contact,skip*n);
- numleft -= n;
- num += n;
- i++;
- }
- return num;
-}
-
-//****************************************************************************
-// standard classes
-
-SHAREDLIBEXPORT int dSphereClass = -1;
-SHAREDLIBEXPORT int dBoxClass = -1;
-SHAREDLIBEXPORT int dCCylinderClass = -1;
-SHAREDLIBEXPORT int dPlaneClass = -1;
-
-
-static dColliderFn * dSphereColliderFn (int num)
-{
- if (num == dSphereClass) return (dColliderFn *) &dCollideSS;
- if (num == dBoxClass) return (dColliderFn *) &dCollideSB;
- if (num == dPlaneClass) return (dColliderFn *) &dCollideSP;
- return 0;
-}
-
-
-static void dSphereAABB (dxGeom *geom, dReal aabb[6])
-{
- dxSphere *s = (dxSphere*) CLASSDATA(geom);
- aabb[0] = geom->pos[0] - s->radius;
- aabb[1] = geom->pos[0] + s->radius;
- aabb[2] = geom->pos[1] - s->radius;
- aabb[3] = geom->pos[1] + s->radius;
- aabb[4] = geom->pos[2] - s->radius;
- aabb[5] = geom->pos[2] + s->radius;
-}
-
-
-static dColliderFn * dBoxColliderFn (int num)
-{
- if (num == dBoxClass) return (dColliderFn *) &dCollideBB;
- if (num == dPlaneClass) return (dColliderFn *) &dCollideBP;
- return 0;
-}
-
-
-static void dBoxAABB (dxGeom *geom, dReal aabb[6])
-{
- dxBox *b = (dxBox*) CLASSDATA(geom);
- dReal xrange = REAL(0.5) * (dFabs (geom->R[0] * b->side[0]) +
- dFabs (geom->R[1] * b->side[1]) + dFabs (geom->R[2] * b->side[2]));
- dReal yrange = REAL(0.5) * (dFabs (geom->R[4] * b->side[0]) +
- dFabs (geom->R[5] * b->side[1]) + dFabs (geom->R[6] * b->side[2]));
- dReal zrange = REAL(0.5) * (dFabs (geom->R[8] * b->side[0]) +
- dFabs (geom->R[9] * b->side[1]) + dFabs (geom->R[10] * b->side[2]));
- aabb[0] = geom->pos[0] - xrange;
- aabb[1] = geom->pos[0] + xrange;
- aabb[2] = geom->pos[1] - yrange;
- aabb[3] = geom->pos[1] + yrange;
- aabb[4] = geom->pos[2] - zrange;
- aabb[5] = geom->pos[2] + zrange;
-}
-
-
-static dColliderFn * dCCylinderColliderFn (int num)
-{
- if (num == dSphereClass) return (dColliderFn *) &dCollideCS;
- if (num == dPlaneClass) return (dColliderFn *) &dCollideCP;
- if (num == dCCylinderClass) return (dColliderFn *) &dCollideCC;
- if (num == dBoxClass) return (dColliderFn *) &dCollideCB;
- return 0;
-}
-
-
-static void dCCylinderAABB (dxGeom *geom, dReal aabb[6])
-{
- dxCCylinder *c = (dxCCylinder*) CLASSDATA(geom);
- dReal xrange = dFabs(geom->R[2] * c->lz) * REAL(0.5) + c->radius;
- dReal yrange = dFabs(geom->R[6] * c->lz) * REAL(0.5) + c->radius;
- dReal zrange = dFabs(geom->R[10] * c->lz) * REAL(0.5) + c->radius;
- aabb[0] = geom->pos[0] - xrange;
- aabb[1] = geom->pos[0] + xrange;
- aabb[2] = geom->pos[1] - yrange;
- aabb[3] = geom->pos[1] + yrange;
- aabb[4] = geom->pos[2] - zrange;
- aabb[5] = geom->pos[2] + zrange;
-}
-
-
-dColliderFn * dPlaneColliderFn (int num)
-{
- return 0;
-}
-
-
-static void dPlaneAABB (dxGeom *geom, dReal aabb[6])
-{
- // @@@ planes that have normal vectors aligned along an axis can use a
- // @@@ less comprehensive bounding box.
- aabb[0] = -dInfinity;
- aabb[1] = dInfinity;
- aabb[2] = -dInfinity;
- aabb[3] = dInfinity;
- aabb[4] = -dInfinity;
- aabb[5] = dInfinity;
-}
-
-
-dxGeom *dCreateSphere (dSpaceID space, dReal radius)
-{
- dAASSERT (radius > 0);
- if (dSphereClass == -1) {
- dGeomClass c;
- c.bytes = sizeof (dxSphere);
- c.collider = &dSphereColliderFn;
- c.aabb = &dSphereAABB;
- c.aabb_test = 0;
- c.dtor = 0;
- dSphereClass = dCreateGeomClass (&c);
- }
-
- dxGeom *g = dCreateGeom (dSphereClass);
- if (space) dSpaceAdd (space,g);
- dxSphere *s = (dxSphere*) CLASSDATA(g);
- s->radius = radius;
- return g;
-}
-
-
-dxGeom *dCreateBox (dSpaceID space, dReal lx, dReal ly, dReal lz)
-{
- dAASSERT (lx > 0 && ly > 0 && lz > 0);
- if (dBoxClass == -1) {
- dGeomClass c;
- c.bytes = sizeof (dxBox);
- c.collider = &dBoxColliderFn;
- c.aabb = &dBoxAABB;
- c.aabb_test = 0;
- c.dtor = 0;
- dBoxClass = dCreateGeomClass (&c);
- }
-
- dxGeom *g = dCreateGeom (dBoxClass);
- if (space) dSpaceAdd (space,g);
- dxBox *b = (dxBox*) CLASSDATA(g);
- b->side[0] = lx;
- b->side[1] = ly;
- b->side[2] = lz;
- return g;
-}
-
-
-dxGeom * dCreateCCylinder (dSpaceID space, dReal radius, dReal length)
-{
- dAASSERT (radius > 0 && length > 0);
- if (dCCylinderClass == -1) {
- dGeomClass c;
- c.bytes = sizeof (dxCCylinder);
- c.collider = &dCCylinderColliderFn;
- c.aabb = &dCCylinderAABB;
- c.aabb_test = 0;
- c.dtor = 0;
- dCCylinderClass = dCreateGeomClass (&c);
- }
-
- dxGeom *g = dCreateGeom (dCCylinderClass);
- if (space) dSpaceAdd (space,g);
- dxCCylinder *c = (dxCCylinder*) CLASSDATA(g);
- c->radius = radius;
- c->lz = length;
- return g;
-}
-
-
-dxGeom *dCreatePlane (dSpaceID space,
- dReal a, dReal b, dReal c, dReal d)
-{
- if (dPlaneClass == -1) {
- dGeomClass c;
- c.bytes = sizeof (dxPlane);
- c.collider = &dPlaneColliderFn;
- c.aabb = &dPlaneAABB;
- c.aabb_test = 0;
- c.dtor = 0;
- dPlaneClass = dCreateGeomClass (&c);
- }
-
- dxGeom *g = dCreateGeom (dPlaneClass);
- if (space) dSpaceAdd (space,g);
- dxPlane *p = (dxPlane*) CLASSDATA(g);
-
- // make sure plane normal has unit length
- dReal l = a*a + b*b + c*c;
- if (l > 0) {
- l = dRecipSqrt(l);
- p->p[0] = a*l;
- p->p[1] = b*l;
- p->p[2] = c*l;
- p->p[3] = d*l;
- }
- else {
- p->p[0] = 1;
- p->p[1] = 0;
- p->p[2] = 0;
- p->p[3] = 0;
- }
- return g;
-}
-
-
-void dGeomSphereSetRadius (dGeomID g, dReal radius)
-{
- dUASSERT (g && g->_class->num == dSphereClass,"argument not a sphere");
- dAASSERT (radius > 0);
- dxSphere *s = (dxSphere*) CLASSDATA(g);
- s->radius = radius;
-}
-
-
-void dGeomBoxSetLengths (dGeomID g, dReal lx, dReal ly, dReal lz)
-{
- dUASSERT (g && g->_class->num == dBoxClass,"argument not a box");
- dAASSERT (lx > 0 && ly > 0 && lz > 0);
- dxBox *b = (dxBox*) CLASSDATA(g);
- b->side[0] = lx;
- b->side[1] = ly;
- b->side[2] = lz;
-}
-
-
-void dGeomPlaneSetParams (dGeomID g, dReal a, dReal b, dReal c, dReal d)
-{
- dUASSERT (g && g->_class->num == dPlaneClass,"argument not a plane");
- dxPlane *p = (dxPlane*) CLASSDATA(g);
- p->p[0] = a;
- p->p[1] = b;
- p->p[2] = c;
- p->p[3] = d;
-}
-
-
-void dGeomCCylinderSetParams (dGeomID g, dReal radius, dReal length)
-{
- dUASSERT (g && g->_class->num == dCCylinderClass,"argument not a ccylinder");
- dAASSERT (radius > 0 && length > 0);
- dxCCylinder *c = (dxCCylinder*) CLASSDATA(g);
- c->radius = radius;
- c->lz = length;
-}
-
-
-dReal dGeomSphereGetRadius (dGeomID g)
-{
- dUASSERT (g && g->_class->num == dSphereClass,"argument not a sphere");
- dxSphere *s = (dxSphere*) CLASSDATA(g);
- return s->radius;
-}
-
-
-void dGeomBoxGetLengths (dGeomID g, dVector3 result)
-{
- dUASSERT (g && g->_class->num == dBoxClass,"argument not a box");
- dxBox *b = (dxBox*) CLASSDATA(g);
- result[0] = b->side[0];
- result[1] = b->side[1];
- result[2] = b->side[2];
-}
-
-
-void dGeomPlaneGetParams (dGeomID g, dVector4 result)
-{
- dUASSERT (g && g->_class->num == dPlaneClass,"argument not a plane");
- dxPlane *p = (dxPlane*) CLASSDATA(g);
- result[0] = p->p[0];
- result[1] = p->p[1];
- result[2] = p->p[2];
- result[3] = p->p[3];
-}
-
-
-void dGeomCCylinderGetParams (dGeomID g, dReal *radius, dReal *length)
-{
- dUASSERT (g && g->_class->num == dCCylinderClass,"argument not a ccylinder");
- dxCCylinder *c = (dxCCylinder*) CLASSDATA(g);
- *radius = c->radius;
- *length = c->lz;
-}
-
-//****************************************************************************
-// geom group
-
-int dGeomGroupClass = -1;
-
-static dColliderFn * dGeomGroupColliderFn (int num)
-{
- return (dColliderFn *) &dCollideG;
-}
-
-
-static void dGeomGroupAABB (dxGeom *geom, dReal aabb[6])
-{
- dxGeomGroup *gr = (dxGeomGroup*) CLASSDATA(geom);
- aabb[0] = dInfinity;
- aabb[1] = -dInfinity;
- aabb[2] = dInfinity;
- aabb[3] = -dInfinity;
- aabb[4] = dInfinity;
- aabb[5] = -dInfinity;
- int i,j;
- for (i=0; i < gr->parts.size(); i++) {
- dReal aabb2[6];
- gr->parts[i]->_class->aabb (gr->parts[i],aabb2);
- for (j=0; j<6; j += 2) if (aabb2[j] < aabb[j]) aabb[j] = aabb2[j];
- for (j=1; j<6; j += 2) if (aabb2[j] > aabb[j]) aabb[j] = aabb2[j];
- }
-}
-
-
-static void dGeomGroupDtor (dxGeom *geom)
-{
- dxGeomGroup *gr = (dxGeomGroup*) CLASSDATA(geom);
- gr->parts.~dArray();
-}
-
-
-dxGeom *dCreateGeomGroup (dSpaceID space)
-{
- if (dGeomGroupClass == -1) {
- dGeomClass c;
- c.bytes = sizeof (dxGeomGroup);
- c.collider = &dGeomGroupColliderFn;
- c.aabb = &dGeomGroupAABB;
- c.aabb_test = 0;
- c.dtor = &dGeomGroupDtor;
- dGeomGroupClass = dCreateGeomClass (&c);
- }
-
- dxGeom *g = dCreateGeom (dGeomGroupClass);
- if (space) dSpaceAdd (space,g);
- dxGeomGroup *gr = (dxGeomGroup*) CLASSDATA(g);
- gr->parts.constructor();
- return g;
-}
-
-
-void dGeomGroupAdd (dxGeom *g, dxGeom *x)
-{
- dUASSERT (g && g->_class->num == dGeomGroupClass,"argument not a geomgroup");
- dxGeomGroup *gr = (dxGeomGroup*) CLASSDATA(g);
- gr->parts.push (x);
-}
-
-
-void dGeomGroupRemove (dxGeom *g, dxGeom *x)
-{
- dUASSERT (g && g->_class->num == dGeomGroupClass,"argument not a geomgroup");
- dxGeomGroup *gr = (dxGeomGroup*) CLASSDATA(g);
- for (int i=0; i < gr->parts.size(); i++) {
- if (gr->parts[i] == x) {
- gr->parts.remove (i);
- return;
- }
- }
-}
-
-
-int dGeomGroupGetNumGeoms (dxGeom *g)
-{
- dUASSERT (g && g->_class->num == dGeomGroupClass,"argument not a geomgroup");
- dxGeomGroup *gr = (dxGeomGroup*) CLASSDATA(g);
- return gr->parts.size();
-}
-
-
-dxGeom * dGeomGroupGetGeom (dxGeom *g, int i)
-{
- dUASSERT (g && g->_class->num == dGeomGroupClass,"argument not a geomgroup");
- dxGeomGroup *gr = (dxGeomGroup*) CLASSDATA(g);
- dAASSERT (i >= 0 && i < gr->parts.size());
- return gr->parts[i];
-}
-
-//****************************************************************************
-// transformed geom
-
-int dGeomTransformClass = -1;
-
-struct dxGeomTransform {
- dxGeom *obj; // object that is being transformed
- int cleanup; // 1 to destroy obj when destroyed
- int infomode; // 1 to put Tx geom in dContactGeom g1
- dVector3 final_pos; // final tx (body tx + relative tx) of the object.
- dMatrix3 final_R; // this is only set if the AABB function is called
-}; // by space collision before the collide fn is called
-
-
-// compute final pos and R for the encapsulated geom object
-
-static void compute_final_tx (const dxGeom *g)
-{
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(g);
- dMULTIPLY0_331 (tr->final_pos,g->R,tr->obj->pos);
- tr->final_pos[0] += g->pos[0];
- tr->final_pos[1] += g->pos[1];
- tr->final_pos[2] += g->pos[2];
- dMULTIPLY0_333 (tr->final_R,g->R,tr->obj->R);
-}
-
-
-
-// this collides a transformed geom with another geom. the other geom can
-// also be a transformed geom, but this case is not handled specially.
-
-int dCollideT (const dxGeom *o1, const dxGeom *o2, int flags,
- dContactGeom *contact, int skip)
-{
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(o1);
- if (!tr->obj) return 0;
- dUASSERT (tr->obj->spaceid==0,
- "GeomTransform encapsulated object must not be in a space");
- dUASSERT (tr->obj->body==0,
- "GeomTransform encapsulated object must not be attach to a body");
-
- // backup the relative pos and R pointers of the encapsulated geom object,
- // and the body pointer
- dReal *posbak = tr->obj->pos;
- dReal *Rbak = tr->obj->R;
- dxBody *bodybak = tr->obj->body;
-
- // compute temporary pos and R for the encapsulated geom object
- if (!o1->space_aabb) compute_final_tx (o1);
- tr->obj->pos = tr->final_pos;
- tr->obj->R = tr->final_R;
- tr->obj->body = o1->body;
-
- // do the collision
- int n = dCollide (tr->obj,const_cast<dxGeom*>(o2),flags,contact,skip);
-
- // if required, adjust the 'g1' values in the generated contacts so that
- // thay indicated the GeomTransform object instead of the encapsulated
- // object.
- if (tr->infomode) {
- for (int i=0; i<n; i++) {
- dContactGeom *c = CONTACT(contact,skip*i);
- c->g1 = const_cast<dxGeom*> (o1);
- }
- }
-
- // restore the pos, R and body
- tr->obj->pos = posbak;
- tr->obj->R = Rbak;
- tr->obj->body = bodybak;
- return n;
-}
-
-
-static dColliderFn * dGeomTransformColliderFn (int num)
-{
- return (dColliderFn *) &dCollideT;
-}
-
-
-static void dGeomTransformAABB (dxGeom *geom, dReal aabb[6])
-{
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(geom);
- if (!tr->obj) {
- dSetZero (aabb,6);
- return;
- }
-
- // backup the relative pos and R pointers of the encapsulated geom object
- dReal *posbak = tr->obj->pos;
- dReal *Rbak = tr->obj->R;
-
- // compute temporary pos and R for the encapsulated geom object
- compute_final_tx (geom);
- tr->obj->pos = tr->final_pos;
- tr->obj->R = tr->final_R;
-
- // compute the AABB
- tr->obj->_class->aabb (tr->obj,aabb);
-
- // restore the pos and R
- tr->obj->pos = posbak;
- tr->obj->R = Rbak;
-}
-
-
-static void dGeomTransformDtor (dxGeom *geom)
-{
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(geom);
- if (tr->obj && tr->cleanup) {
- dGeomDestroy (tr->obj);
- }
-}
-
-
-dxGeom *dCreateGeomTransform (dSpaceID space)
-{
- if (dGeomTransformClass == -1) {
- dGeomClass c;
- c.bytes = sizeof (dxGeomTransform);
- c.collider = &dGeomTransformColliderFn;
- c.aabb = &dGeomTransformAABB;
- c.aabb_test = 0;
- c.dtor = dGeomTransformDtor;
- dGeomTransformClass = dCreateGeomClass (&c);
- }
-
- dxGeom *g = dCreateGeom (dGeomTransformClass);
- if (space) dSpaceAdd (space,g);
-
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(g);
- tr->obj = 0;
- tr->cleanup = 0;
- tr->infomode = 0;
- dSetZero (tr->final_pos,4);
- dRSetIdentity (tr->final_R);
-
- return g;
-}
-
-
-void dGeomTransformSetGeom (dxGeom *g, dxGeom *obj)
-{
- dUASSERT (g && g->_class->num == dGeomTransformClass,
- "argument not a geom transform");
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(g);
- if (tr->obj && tr->cleanup) {
- dGeomDestroy (tr->obj);
- }
- tr->obj = obj;
-}
-
-
-dxGeom * dGeomTransformGetGeom (dxGeom *g)
-{
- dUASSERT (g && g->_class->num == dGeomTransformClass,
- "argument not a geom transform");
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(g);
- return tr->obj;
-}
-
-
-void dGeomTransformSetCleanup (dGeomID g, int mode)
-{
- dUASSERT (g && g->_class->num == dGeomTransformClass,
- "argument not a geom transform");
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(g);
- tr->cleanup = mode;
-}
-
-
-int dGeomTransformGetCleanup (dGeomID g)
-{
- dUASSERT (g && g->_class->num == dGeomTransformClass,
- "argument not a geom transform");
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(g);
- return tr->cleanup;
-}
-
-
-void dGeomTransformSetInfo (dGeomID g, int mode)
-{
- dUASSERT (g && g->_class->num == dGeomTransformClass,
- "argument not a geom transform");
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(g);
- tr->infomode = mode;
-}
-
-
-int dGeomTransformGetInfo (dGeomID g)
-{
- dUASSERT (g && g->_class->num == dGeomTransformClass,
- "argument not a geom transform");
- dxGeomTransform *tr = (dxGeomTransform*) CLASSDATA(g);
- return tr->infomode;
-}
-
-//****************************************************************************
-// other utility functions
-
-void dInfiniteAABB (dxGeom *geom, dReal aabb[6])
-{
- aabb[0] = -dInfinity;
- aabb[1] = dInfinity;
- aabb[2] = -dInfinity;
- aabb[3] = dInfinity;
- aabb[4] = -dInfinity;
- aabb[5] = dInfinity;
-}
-
-
-void dCloseODE()
-{
- if (colliders) {
- delete colliders;
- colliders = 0;
- }
- if (classes) {
- for (int i=0; i < classes->size(); i++) {
- dFree ((*classes)[i], sizeof (dxGeomClass));
- }
- delete classes;
- classes = 0;
- }
-
- // reset geom class vars
- dSphereClass = -1;
- dBoxClass = -1;
- dCCylinderClass = -1;
- dPlaneClass = -1;
- dGeomGroupClass = -1;
- dGeomTransformClass = -1;
-
- // if you're using contrib code you may want to uncomment the following:
- // dTriListClass = -1;
- // dRayClass = -1;
-}
diff --git a/extern/ode/dist/ode/src/geom_internal.h b/extern/ode/dist/ode/src/geom_internal.h
deleted file mode 100644
index 63be589ffe0..00000000000
--- a/extern/ode/dist/ode/src/geom_internal.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_GEOM_INTERNAL_H_
-#define _ODE_GEOM_INTERNAL_H_
-
-
-// mask for the number-of-contacts field in the dCollide() flags parameter
-#define NUMC_MASK (0xffff)
-
-
-// internal info for geometry class
-
-struct dxGeomClass {
- dGetColliderFnFn *collider;
- dGetAABBFn *aabb;
- dAABBTestFn *aabb_test;
- dGeomDtorFn *dtor;
- int num; // class number
- int size; // total size of object, including extra data area
-};
-
-
-// position vector and rotation matrix for geometry objects that are not
-// connected to bodies.
-
-struct dxPosR {
- dVector3 pos;
- dMatrix3 R;
-};
-
-
-// common data for all geometry objects. the class-specific data area follows
-// this structure. pos and R will either point to a separately allocated
-// buffer (if body is 0 - pos points to the dxPosR object) or to the pos and
-// R of the body (if body nonzero).
-
-struct dxGeom { // a dGeomID is a pointer to this
- dxGeomClass *_class; // class of this object
- void *data; // user data pointer
- dBodyID body; // dynamics body associated with this object (if any)
- dReal *pos; // pointer to object's position vector
- dReal *R; // pointer to object's rotation matrix
- dSpaceID spaceid; // the space this object is in
- dGeomSpaceData space; // reserved for use by space this object is in
- dReal *space_aabb; // ptr to aabb array held by dSpaceCollide() fn
- // class-specific data follows here, with proper alignment.
-};
-
-
-// this is the size of the dxGeom structure rounded up to a multiple of 16
-// bytes. any class specific data that comes after this will have the correct
-// alignment.
-
-#define SIZEOF_DXGEOM dEFFICIENT_SIZE(sizeof(dxGeom))
-
-
-// given a pointer to a dxGeom, return a pointer to the class data that
-// follows it.
-
-#define CLASSDATA(geomptr) (((char*)geomptr) + SIZEOF_DXGEOM)
-
-#endif
-
diff --git a/extern/ode/dist/ode/src/joint.cpp b/extern/ode/dist/ode/src/joint.cpp
deleted file mode 100644
index 74e4c34cc71..00000000000
--- a/extern/ode/dist/ode/src/joint.cpp
+++ /dev/null
@@ -1,2160 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/*
-
-design note: the general principle for giving a joint the option of connecting
-to the static environment (i.e. the absolute frame) is to check the second
-body (joint->node[1].body), and if it is zero then behave as if its body
-transform is the identity.
-
-*/
-
-#include <ode/odemath.h>
-#include <ode/rotation.h>
-#include <ode/matrix.h>
-#include "joint.h"
-
-//****************************************************************************
-// externs
-
-extern "C" void dBodyAddTorque (dBodyID, dReal fx, dReal fy, dReal fz);
-extern "C" void dBodyAddForce (dBodyID, dReal fx, dReal fy, dReal fz);
-
-//****************************************************************************
-// utility
-
-// set three "ball-and-socket" rows in the constraint equation, and the
-// corresponding right hand side.
-
-static inline void setBall (dxJoint *joint, dxJoint::Info2 *info,
- dVector3 anchor1, dVector3 anchor2)
-{
- // anchor points in global coordinates with respect to body PORs.
- dVector3 a1,a2;
-
- int s = info->rowskip;
-
- // set jacobian
- info->J1l[0] = 1;
- info->J1l[s+1] = 1;
- info->J1l[2*s+2] = 1;
- dMULTIPLY0_331 (a1,joint->node[0].body->R,anchor1);
- dCROSSMAT (info->J1a,a1,s,-,+);
- if (joint->node[1].body) {
- info->J2l[0] = -1;
- info->J2l[s+1] = -1;
- info->J2l[2*s+2] = -1;
- dMULTIPLY0_331 (a2,joint->node[1].body->R,anchor2);
- dCROSSMAT (info->J2a,a2,s,+,-);
- }
-
- // set right hand side
- dReal k = info->fps * info->erp;
- if (joint->node[1].body) {
- for (int j=0; j<3; j++) {
- info->c[j] = k * (a2[j] + joint->node[1].body->pos[j] -
- a1[j] - joint->node[0].body->pos[j]);
- }
- }
- else {
- for (int j=0; j<3; j++) {
- info->c[j] = k * (anchor2[j] - a1[j] -
- joint->node[0].body->pos[j]);
- }
- }
-}
-
-
-// this is like setBall(), except that `axis' is a unit length vector
-// (in global coordinates) that should be used for the first jacobian
-// position row (the other two row vectors will be derived from this).
-// `erp1' is the erp value to use along the axis.
-
-static inline void setBall2 (dxJoint *joint, dxJoint::Info2 *info,
- dVector3 anchor1, dVector3 anchor2,
- dVector3 axis, dReal erp1)
-{
- // anchor points in global coordinates with respect to body PORs.
- dVector3 a1,a2;
-
- int i,s = info->rowskip;
-
- // get vectors normal to the axis. in setBall() axis,q1,q2 is [1 0 0],
- // [0 1 0] and [0 0 1], which makes everything much easier.
- dVector3 q1,q2;
- dPlaneSpace (axis,q1,q2);
-
- // set jacobian
- for (i=0; i<3; i++) info->J1l[i] = axis[i];
- for (i=0; i<3; i++) info->J1l[s+i] = q1[i];
- for (i=0; i<3; i++) info->J1l[2*s+i] = q2[i];
- dMULTIPLY0_331 (a1,joint->node[0].body->R,anchor1);
- dCROSS (info->J1a,=,a1,axis);
- dCROSS (info->J1a+s,=,a1,q1);
- dCROSS (info->J1a+2*s,=,a1,q2);
- if (joint->node[1].body) {
- for (i=0; i<3; i++) info->J2l[i] = -axis[i];
- for (i=0; i<3; i++) info->J2l[s+i] = -q1[i];
- for (i=0; i<3; i++) info->J2l[2*s+i] = -q2[i];
- dMULTIPLY0_331 (a2,joint->node[1].body->R,anchor2);
- dCROSS (info->J2a,= -,a2,axis);
- dCROSS (info->J2a+s,= -,a2,q1);
- dCROSS (info->J2a+2*s,= -,a2,q2);
- }
-
- // set right hand side - measure error along (axis,q1,q2)
- dReal k1 = info->fps * erp1;
- dReal k = info->fps * info->erp;
-
- for (i=0; i<3; i++) a1[i] += joint->node[0].body->pos[i];
- if (joint->node[1].body) {
- for (i=0; i<3; i++) a2[i] += joint->node[1].body->pos[i];
- info->c[0] = k1 * (dDOT(axis,a2) - dDOT(axis,a1));
- info->c[1] = k * (dDOT(q1,a2) - dDOT(q1,a1));
- info->c[2] = k * (dDOT(q2,a2) - dDOT(q2,a1));
- }
- else {
- info->c[0] = k1 * (dDOT(axis,anchor2) - dDOT(axis,a1));
- info->c[1] = k * (dDOT(q1,anchor2) - dDOT(q1,a1));
- info->c[2] = k * (dDOT(q2,anchor2) - dDOT(q2,a1));
- }
-}
-
-
-// compute anchor points relative to bodies
-
-static void setAnchors (dxJoint *j, dReal x, dReal y, dReal z,
- dVector3 anchor1, dVector3 anchor2)
-{
- if (j->node[0].body) {
- dReal q[4];
- q[0] = x - j->node[0].body->pos[0];
- q[1] = y - j->node[0].body->pos[1];
- q[2] = z - j->node[0].body->pos[2];
- q[3] = 0;
- dMULTIPLY1_331 (anchor1,j->node[0].body->R,q);
- if (j->node[1].body) {
- q[0] = x - j->node[1].body->pos[0];
- q[1] = y - j->node[1].body->pos[1];
- q[2] = z - j->node[1].body->pos[2];
- q[3] = 0;
- dMULTIPLY1_331 (anchor2,j->node[1].body->R,q);
- }
- else {
- anchor2[0] = x;
- anchor2[1] = y;
- anchor2[2] = z;
- }
- }
- anchor1[3] = 0;
- anchor2[3] = 0;
-}
-
-
-// compute axes relative to bodies. axis2 can be 0
-
-static void setAxes (dxJoint *j, dReal x, dReal y, dReal z,
- dVector3 axis1, dVector3 axis2)
-{
- if (j->node[0].body) {
- dReal q[4];
- q[0] = x;
- q[1] = y;
- q[2] = z;
- q[3] = 0;
- dNormalize3 (q);
- dMULTIPLY1_331 (axis1,j->node[0].body->R,q);
- if (axis2) {
- if (j->node[1].body) {
- dMULTIPLY1_331 (axis2,j->node[1].body->R,q);
- }
- else {
- axis2[0] = x;
- axis2[1] = y;
- axis2[2] = z;
- }
- axis2[3] = 0;
- }
- }
- axis1[3] = 0;
-}
-
-
-static void getAnchor (dxJoint *j, dVector3 result, dVector3 anchor1)
-{
- if (j->node[0].body) {
- dMULTIPLY0_331 (result,j->node[0].body->R,anchor1);
- result[0] += j->node[0].body->pos[0];
- result[1] += j->node[0].body->pos[1];
- result[2] += j->node[0].body->pos[2];
- }
-}
-
-
-static void getAxis (dxJoint *j, dVector3 result, dVector3 axis1)
-{
- if (j->node[0].body) {
- dMULTIPLY0_331 (result,j->node[0].body->R,axis1);
- }
-}
-
-
-// given two bodies (body1,body2), the hinge axis that they are connected by
-// w.r.t. body1 (axis), and the initial relative orientation between them
-// (q_initial), return the relative rotation angle. the initial relative
-// orientation corresponds to an angle of zero. if body2 is 0 then measure the
-// angle between body1 and the static frame.
-//
-// this will not return the correct angle if the bodies rotate along any axis
-// other than the given hinge axis.
-
-static dReal getHingeAngle (dxBody *body1, dxBody *body2, dVector3 axis,
- dQuaternion q_initial)
-{
- // the angle between the two bodies is extracted from the quaternion that
- // represents the relative rotation between them. recall that a quaternion
- // q is:
- // [s,v] = [ cos(theta/2) , sin(theta/2) * u ]
- // where s is a scalar and v is a 3-vector. u is a unit length axis and
- // theta is a rotation along that axis. we can get theta/2 by:
- // theta/2 = atan2 ( sin(theta/2) , cos(theta/2) )
- // but we can't get sin(theta/2) directly, only its absolute value, i.e.:
- // |v| = |sin(theta/2)| * |u|
- // = |sin(theta/2)|
- // using this value will have a strange effect. recall that there are two
- // quaternion representations of a given rotation, q and -q. typically as
- // a body rotates along the axis it will go through a complete cycle using
- // one representation and then the next cycle will use the other
- // representation. this corresponds to u pointing in the direction of the
- // hinge axis and then in the opposite direction. the result is that theta
- // will appear to go "backwards" every other cycle. here is a fix: if u
- // points "away" from the direction of the hinge (motor) axis (i.e. more
- // than 90 degrees) then use -q instead of q. this represents the same
- // rotation, but results in the cos(theta/2) value being sign inverted.
-
- // get qrel = relative rotation between the two bodies
- dQuaternion qrel;
- if (body2) {
- dQuaternion qq;
- dQMultiply1 (qq,body1->q,body2->q);
- dQMultiply2 (qrel,qq,q_initial);
- }
- else {
- // pretend body2->q is the identity
- dQMultiply3 (qrel,body1->q,q_initial);
- }
-
- // extract the angle from the quaternion. cost2 = cos(theta/2),
- // sint2 = |sin(theta/2)|
- dReal cost2 = qrel[0];
- dReal sint2 = dSqrt (qrel[1]*qrel[1]+qrel[2]*qrel[2]+qrel[3]*qrel[3]);
- dReal theta = (dDOT(qrel+1,axis) >= 0) ? // @@@ padding assumptions
- (2 * dAtan2(sint2,cost2)) : // if u points in direction of axis
- (2 * dAtan2(sint2,-cost2)); // if u points in opposite direction
-
- // the angle we get will be between 0..2*pi, but we want to return angles
- // between -pi..pi
- if (theta > M_PI) theta -= 2*M_PI;
-
- // the angle we've just extracted has the wrong sign
- theta = -theta;
-
- return theta;
-}
-
-//****************************************************************************
-// dxJointLimitMotor
-
-void dxJointLimitMotor::init (dxWorld *world)
-{
- vel = 0;
- fmax = 0;
- lostop = -dInfinity;
- histop = dInfinity;
- fudge_factor = 1;
- normal_cfm = world->global_cfm;
- stop_erp = world->global_erp;
- stop_cfm = world->global_cfm;
- bounce = 0;
- limit = 0;
- limit_err = 0;
-}
-
-
-void dxJointLimitMotor::set (int num, dReal value)
-{
- switch (num) {
- case dParamLoStop:
- if (value <= histop) lostop = value;
- break;
- case dParamHiStop:
- if (value >= lostop) histop = value;
- break;
- case dParamVel:
- vel = value;
- break;
- case dParamFMax:
- if (value >= 0) fmax = value;
- break;
- case dParamFudgeFactor:
- if (value >= 0 && value <= 1) fudge_factor = value;
- break;
- case dParamBounce:
- bounce = value;
- break;
- case dParamCFM:
- normal_cfm = value;
- break;
- case dParamStopERP:
- stop_erp = value;
- break;
- case dParamStopCFM:
- stop_cfm = value;
- break;
- }
-}
-
-
-dReal dxJointLimitMotor::get (int num)
-{
- switch (num) {
- case dParamLoStop: return lostop;
- case dParamHiStop: return histop;
- case dParamVel: return vel;
- case dParamFMax: return fmax;
- case dParamFudgeFactor: return fudge_factor;
- case dParamBounce: return bounce;
- case dParamCFM: return normal_cfm;
- case dParamStopERP: return stop_erp;
- case dParamStopCFM: return stop_cfm;
- default: return 0;
- }
-}
-
-
-int dxJointLimitMotor::testRotationalLimit (dReal angle)
-{
- if (angle <= lostop) {
- limit = 1;
- limit_err = angle - lostop;
- return 1;
- }
- else if (angle >= histop) {
- limit = 2;
- limit_err = angle - histop;
- return 1;
- }
- else {
- limit = 0;
- return 0;
- }
-}
-
-
-int dxJointLimitMotor::addLimot (dxJoint *joint,
- dxJoint::Info2 *info, int row,
- dVector3 ax1, int rotational)
-{
- int srow = row * info->rowskip;
-
- // if the joint is powered, or has joint limits, add in the extra row
- int powered = fmax > 0;
- if (powered || limit) {
- dReal *J1 = rotational ? info->J1a : info->J1l;
- dReal *J2 = rotational ? info->J2a : info->J2l;
-
- J1[srow+0] = ax1[0];
- J1[srow+1] = ax1[1];
- J1[srow+2] = ax1[2];
- if (joint->node[1].body) {
- J2[srow+0] = -ax1[0];
- J2[srow+1] = -ax1[1];
- J2[srow+2] = -ax1[2];
- }
-
- // if we're limited low and high simultaneously, the joint motor is
- // ineffective
- if (limit && (lostop == histop)) powered = 0;
-
- if (powered) {
- info->cfm[row] = normal_cfm;
- if (! limit) {
- info->c[row] = vel;
- info->lo[row] = -fmax;
- info->hi[row] = fmax;
- }
- else {
- // the joint is at a limit, AND is being powered. if the joint is
- // being powered into the limit then we apply the maximum motor force
- // in that direction, because the motor is working against the
- // immovable limit. if the joint is being powered away from the limit
- // then we have problems because actually we need *two* lcp
- // constraints to handle this case. so we fake it and apply some
- // fraction of the maximum force. the fraction to use can be set as
- // a fudge factor.
-
- dReal fm = fmax;
- if (vel > 0) fm = -fm;
-
- // if we're powering away from the limit, apply the fudge factor
- if ((limit==1 && vel > 0) || (limit==2 && vel < 0)) fm *= fudge_factor;
-
- if (rotational) {
- dBodyAddTorque (joint->node[0].body,-fm*ax1[0],-fm*ax1[1],
- -fm*ax1[2]);
- if (joint->node[1].body)
- dBodyAddTorque (joint->node[1].body,fm*ax1[0],fm*ax1[1],fm*ax1[2]);
- }
- else {
- dBodyAddForce (joint->node[0].body,-fm*ax1[0],-fm*ax1[1],-fm*ax1[2]);
- if (joint->node[1].body)
- dBodyAddForce (joint->node[1].body,fm*ax1[0],fm*ax1[1],fm*ax1[2]);
- }
- }
- }
-
- if (limit) {
- dReal k = info->fps * stop_erp;
- info->c[row] = -k * limit_err;
- info->cfm[row] = stop_cfm;
-
- if (lostop == histop) {
- // limited low and high simultaneously
- info->lo[row] = -dInfinity;
- info->hi[row] = dInfinity;
- }
- else {
- if (limit == 1) {
- // low limit
- info->lo[row] = 0;
- info->hi[row] = dInfinity;
- }
- else {
- // high limit
- info->lo[row] = -dInfinity;
- info->hi[row] = 0;
- }
-
- // deal with bounce
- if (bounce > 0) {
- // calculate joint velocity
- dReal vel;
- if (rotational) {
- vel = dDOT(joint->node[0].body->avel,ax1);
- if (joint->node[1].body)
- vel -= dDOT(joint->node[1].body->avel,ax1);
- }
- else {
- vel = dDOT(joint->node[0].body->lvel,ax1);
- if (joint->node[1].body)
- vel -= dDOT(joint->node[1].body->lvel,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) {
- dReal newc = -bounce * vel;
- if (newc > info->c[row]) info->c[row] = newc;
- }
- }
- else {
- // high limit - all those computations are reversed
- if (vel > 0) {
- dReal newc = -bounce * vel;
- if (newc < info->c[row]) info->c[row] = newc;
- }
- }
- }
- }
- }
- return 1;
- }
- else return 0;
-}
-
-//****************************************************************************
-// ball and socket
-
-static void ballInit (dxJointBall *j)
-{
- dSetZero (j->anchor1,4);
- dSetZero (j->anchor2,4);
-}
-
-
-static void ballGetInfo1 (dxJointBall *j, dxJoint::Info1 *info)
-{
- info->m = 3;
- info->nub = 3;
-}
-
-
-static void ballGetInfo2 (dxJointBall *joint, dxJoint::Info2 *info)
-{
- setBall (joint,info,joint->anchor1,joint->anchor2);
-}
-
-
-extern "C" void dJointSetBallAnchor (dxJointBall *joint,
- dReal x, dReal y, dReal z)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dball_vtable,"joint is not a ball");
- setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2);
-}
-
-
-extern "C" void dJointGetBallAnchor (dxJointBall *joint, dVector3 result)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(result,"bad result argument");
- dUASSERT(joint->vtable == &__dball_vtable,"joint is not a ball");
- getAnchor (joint,result,joint->anchor1);
-}
-
-
-dxJoint::Vtable __dball_vtable = {
- sizeof(dxJointBall),
- (dxJoint::init_fn*) ballInit,
- (dxJoint::getInfo1_fn*) ballGetInfo1,
- (dxJoint::getInfo2_fn*) ballGetInfo2,
- dJointTypeBall};
-
-//****************************************************************************
-// hinge
-
-static void hingeInit (dxJointHinge *j)
-{
- dSetZero (j->anchor1,4);
- dSetZero (j->anchor2,4);
- dSetZero (j->axis1,4);
- j->axis1[0] = 1;
- dSetZero (j->axis2,4);
- j->axis2[0] = 1;
- dSetZero (j->qrel,4);
- j->limot.init (j->world);
-}
-
-
-static void hingeGetInfo1 (dxJointHinge *j, dxJoint::Info1 *info)
-{
- info->nub = 5;
-
- // see if joint is powered
- if (j->limot.fmax > 0)
- info->m = 6; // powered hinge needs an extra constraint row
- else info->m = 5;
-
- // see if we're at a joint limit.
- if ((j->limot.lostop >= -M_PI || j->limot.histop <= M_PI) &&
- j->limot.lostop <= j->limot.histop) {
- dReal angle = getHingeAngle (j->node[0].body,j->node[1].body,j->axis1,
- j->qrel);
- if (j->limot.testRotationalLimit (angle)) info->m = 6;
- }
-}
-
-
-static void hingeGetInfo2 (dxJointHinge *joint, dxJoint::Info2 *info)
-{
- // set the three ball-and-socket rows
- setBall (joint,info,joint->anchor1,joint->anchor2);
-
- // set the two hinge rows. 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.
-
- dVector3 ax1; // length 1 joint axis in global coordinates, from 1st body
- dVector3 p,q; // plane space vectors for ax1
- dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1);
- dPlaneSpace (ax1,p,q);
-
- int s3=3*info->rowskip;
- int s4=4*info->rowskip;
-
- info->J1a[s3+0] = p[0];
- info->J1a[s3+1] = p[1];
- info->J1a[s3+2] = p[2];
- info->J1a[s4+0] = q[0];
- info->J1a[s4+1] = q[1];
- info->J1a[s4+2] = q[2];
-
- if (joint->node[1].body) {
- info->J2a[s3+0] = -p[0];
- info->J2a[s3+1] = -p[1];
- info->J2a[s3+2] = -p[2];
- info->J2a[s4+0] = -q[0];
- info->J2a[s4+1] = -q[1];
- info->J2a[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.
-
- dVector3 ax2,b;
- if (joint->node[1].body) {
- dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2);
- }
- else {
- ax2[0] = joint->axis2[0];
- ax2[1] = joint->axis2[1];
- ax2[2] = joint->axis2[2];
- }
- dCROSS (b,=,ax1,ax2);
- dReal k = info->fps * info->erp;
- info->c[3] = k * dDOT(b,p);
- info->c[4] = k * dDOT(b,q);
-
- // if the hinge is powered, or has joint limits, add in the stuff
- joint->limot.addLimot (joint,info,5,ax1,1);
-}
-
-
-// compute initial relative rotation body1 -> body2, or env -> body1
-
-static void hingeComputeInitialRelativeRotation (dxJointHinge *joint)
-{
- if (joint->node[0].body) {
- if (joint->node[1].body) {
- dQMultiply1 (joint->qrel,joint->node[0].body->q,joint->node[1].body->q);
- }
- else {
- // set joint->qrel to the transpose of the first body q
- joint->qrel[0] = joint->node[0].body->q[0];
- for (int i=1; i<4; i++) joint->qrel[i] = -joint->node[0].body->q[i];
- }
- }
-}
-
-
-extern "C" void dJointSetHingeAnchor (dxJointHinge *joint,
- dReal x, dReal y, dReal z)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge");
- setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2);
- hingeComputeInitialRelativeRotation (joint);
-}
-
-
-extern "C" void dJointSetHingeAxis (dxJointHinge *joint,
- dReal x, dReal y, dReal z)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge");
- setAxes (joint,x,y,z,joint->axis1,joint->axis2);
- hingeComputeInitialRelativeRotation (joint);
-}
-
-
-extern "C" void dJointGetHingeAnchor (dxJointHinge *joint, dVector3 result)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(result,"bad result argument");
- dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge");
- getAnchor (joint,result,joint->anchor1);
-}
-
-
-extern "C" void dJointGetHingeAxis (dxJointHinge *joint, dVector3 result)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(result,"bad result argument");
- dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge");
- getAxis (joint,result,joint->axis1);
-}
-
-
-extern "C" void dJointSetHingeParam (dxJointHinge *joint,
- int parameter, dReal value)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge");
- joint->limot.set (parameter,value);
-}
-
-
-extern "C" dReal dJointGetHingeParam (dxJointHinge *joint, int parameter)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge");
- return joint->limot.get (parameter);
-}
-
-
-extern "C" dReal dJointGetHingeAngle (dxJointHinge *joint)
-{
- dAASSERT(joint);
- dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a hinge");
- if (joint->node[0].body) {
- return getHingeAngle (joint->node[0].body,joint->node[1].body,joint->axis1,
- joint->qrel);
- }
- else return 0;
-}
-
-
-extern "C" dReal dJointGetHingeAngleRate (dxJointHinge *joint)
-{
- dAASSERT(joint);
- dUASSERT(joint->vtable == &__dhinge_vtable,"joint is not a Hinge");
- if (joint->node[0].body) {
- dVector3 axis;
- dMULTIPLY0_331 (axis,joint->node[0].body->R,joint->axis1);
- dReal rate = dDOT(axis,joint->node[0].body->avel);
- if (joint->node[1].body) rate -= dDOT(axis,joint->node[1].body->avel);
- return rate;
- }
- else return 0;
-}
-
-
-dxJoint::Vtable __dhinge_vtable = {
- sizeof(dxJointHinge),
- (dxJoint::init_fn*) hingeInit,
- (dxJoint::getInfo1_fn*) hingeGetInfo1,
- (dxJoint::getInfo2_fn*) hingeGetInfo2,
- dJointTypeHinge};
-
-//****************************************************************************
-// slider
-
-static void sliderInit (dxJointSlider *j)
-{
- dSetZero (j->axis1,4);
- j->axis1[0] = 1;
- dSetZero (j->qrel,4);
- dSetZero (j->offset,4);
- j->limot.init (j->world);
-}
-
-
-extern "C" dReal dJointGetSliderPosition (dxJointSlider *joint)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider");
-
- // get axis1 in global coordinates
- dVector3 ax1,q;
- dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1);
-
- if (joint->node[1].body) {
- // get body2 + offset point in global coordinates
- dMULTIPLY0_331 (q,joint->node[1].body->R,joint->offset);
- for (int i=0; i<3; i++) q[i] = joint->node[0].body->pos[i] - q[i] -
- joint->node[1].body->pos[i];
- }
- else {
- for (int i=0; i<3; i++) q[i] = joint->node[0].body->pos[i] -
- joint->offset[i];
-
- }
- return dDOT(ax1,q);
-}
-
-
-extern "C" dReal dJointGetSliderPositionRate (dxJointSlider *joint)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider");
-
- // get axis1 in global coordinates
- dVector3 ax1;
- dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1);
-
- if (joint->node[1].body) {
- return dDOT(ax1,joint->node[0].body->lvel) -
- dDOT(ax1,joint->node[1].body->lvel);
- }
- else {
- return dDOT(ax1,joint->node[0].body->lvel);
- }
-}
-
-
-static void sliderGetInfo1 (dxJointSlider *j, dxJoint::Info1 *info)
-{
- info->nub = 5;
-
- // see if joint is powered
- if (j->limot.fmax > 0)
- info->m = 6; // powered slider needs an extra constraint row
- else info->m = 5;
-
- // see if we're at a joint limit.
- j->limot.limit = 0;
- if ((j->limot.lostop > -dInfinity || j->limot.histop < dInfinity) &&
- j->limot.lostop <= j->limot.histop) {
- // measure joint position
- dReal pos = dJointGetSliderPosition (j);
- if (pos <= j->limot.lostop) {
- j->limot.limit = 1;
- j->limot.limit_err = pos - j->limot.lostop;
- info->m = 6;
- }
- else if (pos >= j->limot.histop) {
- j->limot.limit = 2;
- j->limot.limit_err = pos - j->limot.histop;
- info->m = 6;
- }
- }
-}
-
-
-static void sliderGetInfo2 (dxJointSlider *joint, dxJoint::Info2 *info)
-{
- int i,s = info->rowskip;
- int s2=2*s,s3=3*s,s4=4*s;
-
- // pull out pos and R for both bodies. also get the `connection'
- // vector pos2-pos1.
-
- dReal *pos1,*pos2,*R1,*R2;
- dVector3 c;
- pos1 = joint->node[0].body->pos;
- R1 = joint->node[0].body->R;
- if (joint->node[1].body) {
- pos2 = joint->node[1].body->pos;
- R2 = joint->node[1].body->R;
- for (i=0; i<3; i++) c[i] = pos2[i] - pos1[i];
- }
- else {
- pos2 = 0;
- R2 = 0;
- }
-
- // 3 rows to make body rotations equal
- info->J1a[0] = 1;
- info->J1a[s+1] = 1;
- info->J1a[s2+2] = 1;
- if (joint->node[1].body) {
- info->J2a[0] = -1;
- info->J2a[s+1] = -1;
- info->J2a[s2+2] = -1;
- }
-
- // remaining 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 substitute (w1+w2)/2 for w1, as w1 is supposed to equal w2.
-
- dVector3 ax1; // joint axis in global coordinates (unit length)
- dVector3 p,q; // plane space of ax1
- dMULTIPLY0_331 (ax1,R1,joint->axis1);
- dPlaneSpace (ax1,p,q);
- if (joint->node[1].body) {
- dVector3 tmp;
- dCROSS (tmp, = REAL(0.5) * ,c,p);
- for (i=0; i<3; i++) info->J2a[s3+i] = tmp[i];
- for (i=0; i<3; i++) info->J2a[s3+i] = tmp[i];
- dCROSS (tmp, = REAL(0.5) * ,c,q);
- for (i=0; i<3; i++) info->J2a[s4+i] = tmp[i];
- for (i=0; i<3; i++) info->J2a[s4+i] = tmp[i];
- for (i=0; i<3; i++) info->J2l[s3+i] = -p[i];
- for (i=0; i<3; i++) info->J2l[s4+i] = -q[i];
- }
- for (i=0; i<3; i++) info->J1l[s3+i] = p[i];
- for (i=0; i<3; i++) info->J1l[s4+i] = q[i];
-
- // compute the right hand side. the first three elements will result in
- // relative angular velocity of the two bodies - this is set to bring them
- // back into alignment. the correcting angular velocity is
- // |angular_velocity| = angle/time = erp*theta / stepsize
- // = (erp*fps) * theta
- // angular_velocity = |angular_velocity| * u
- // = (erp*fps) * theta * u
- // where rotation along unit length axis u by theta brings body 2's frame
- // to qrel with respect to body 1's frame. using a small angle approximation
- // for sin(), this gives
- // angular_velocity = (erp*fps) * 2 * v
- // where the quaternion of the relative rotation between the two bodies is
- // q = [cos(theta/2) sin(theta/2)*u] = [s v]
-
- // get qerr = relative rotation (rotation error) between two bodies
- dQuaternion qerr,e;
- if (joint->node[1].body) {
- dQuaternion qq;
- dQMultiply1 (qq,joint->node[0].body->q,joint->node[1].body->q);
- dQMultiply2 (qerr,qq,joint->qrel);
- }
- else {
- dQMultiply3 (qerr,joint->node[0].body->q,joint->qrel);
- }
- if (qerr[0] < 0) {
- qerr[1] = -qerr[1]; // adjust sign of qerr to make theta small
- qerr[2] = -qerr[2];
- qerr[3] = -qerr[3];
- }
- dMULTIPLY0_331 (e,joint->node[0].body->R,qerr+1); // @@@ bad SIMD padding!
- dReal k = info->fps * info->erp;
- info->c[0] = 2*k * e[0];
- info->c[1] = 2*k * e[1];
- info->c[2] = 2*k * e[2];
-
- // compute last two elements of right hand side. we want to align the offset
- // point (in body 2's frame) with the center of body 1.
- if (joint->node[1].body) {
- dVector3 ofs; // offset point in global coordinates
- dMULTIPLY0_331 (ofs,R2,joint->offset);
- for (i=0; i<3; i++) c[i] += ofs[i];
- info->c[3] = k * dDOT(p,c);
- info->c[4] = k * dDOT(q,c);
- }
- else {
- dVector3 ofs; // offset point in global coordinates
- for (i=0; i<3; i++) ofs[i] = joint->offset[i] - pos1[i];
- info->c[3] = k * dDOT(p,ofs);
- info->c[4] = k * dDOT(q,ofs);
- }
-
- // if the slider is powered, or has joint limits, add in the extra row
- joint->limot.addLimot (joint,info,5,ax1,0);
-}
-
-
-extern "C" void dJointSetSliderAxis (dxJointSlider *joint,
- dReal x, dReal y, dReal z)
-{
- int i;
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider");
- setAxes (joint,x,y,z,joint->axis1,0);
-
- // compute initial relative rotation body1 -> body2, or env -> body1
- // also compute center of body1 w.r.t body 2
- if (joint->node[1].body) {
- dQMultiply1 (joint->qrel,joint->node[0].body->q,joint->node[1].body->q);
- dVector3 c;
- for (i=0; i<3; i++)
- c[i] = joint->node[0].body->pos[i] - joint->node[1].body->pos[i];
- dMULTIPLY1_331 (joint->offset,joint->node[1].body->R,c);
- }
- else {
- // set joint->qrel to the transpose of the first body's q
- joint->qrel[0] = joint->node[0].body->q[0];
- for (i=1; i<4; i++) joint->qrel[i] = -joint->node[0].body->q[i];
- for (i=0; i<3; i++) joint->offset[i] = joint->node[0].body->pos[i];
- }
-}
-
-
-extern "C" void dJointGetSliderAxis (dxJointSlider *joint, dVector3 result)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(result,"bad result argument");
- dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider");
- getAxis (joint,result,joint->axis1);
-}
-
-
-extern "C" void dJointSetSliderParam (dxJointSlider *joint,
- int parameter, dReal value)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider");
- joint->limot.set (parameter,value);
-}
-
-
-extern "C" dReal dJointGetSliderParam (dxJointSlider *joint, int parameter)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dslider_vtable,"joint is not a slider");
- return joint->limot.get (parameter);
-}
-
-
-dxJoint::Vtable __dslider_vtable = {
- sizeof(dxJointSlider),
- (dxJoint::init_fn*) sliderInit,
- (dxJoint::getInfo1_fn*) sliderGetInfo1,
- (dxJoint::getInfo2_fn*) sliderGetInfo2,
- dJointTypeSlider};
-
-//****************************************************************************
-// contact
-
-static void contactInit (dxJointContact *j)
-{
- // default frictionless contact. hmmm, this info gets overwritten straight
- // away anyway, so why bother?
- j->contact.surface.mode = 0;
- j->contact.surface.mu = 0;
- dSetZero (j->contact.geom.pos,4);
- dSetZero (j->contact.geom.normal,4);
- j->contact.geom.depth = 0;
-}
-
-
-static void contactGetInfo1 (dxJointContact *j, dxJoint::Info1 *info)
-{
- // make sure mu's >= 0, then calculate number of constraint rows and number
- // of unbounded rows.
- int m = 1, nub=0;
- if (j->contact.surface.mu < 0) j->contact.surface.mu = 0;
- if (j->contact.surface.mode & dContactMu2) {
- if (j->contact.surface.mu > 0) m++;
- if (j->contact.surface.mu2 < 0) j->contact.surface.mu2 = 0;
- if (j->contact.surface.mu2 > 0) m++;
- if (j->contact.surface.mu == dInfinity) nub ++;
- if (j->contact.surface.mu2 == dInfinity) nub ++;
- }
- else {
- if (j->contact.surface.mu > 0) m += 2;
- if (j->contact.surface.mu == dInfinity) nub += 2;
- }
-
- j->the_m = m;
- info->m = m;
- info->nub = nub;
-}
-
-
-static void contactGetInfo2 (dxJointContact *j, dxJoint::Info2 *info)
-{
- int i,s = info->rowskip;
- int s2 = 2*s;
-
- // get normal, with sign adjusted for body1/body2 polarity
- dVector3 normal;
- if (j->flags & dJOINT_REVERSE) {
- normal[0] = j->contact.geom.normal[0];
- normal[1] = j->contact.geom.normal[1];
- normal[2] = j->contact.geom.normal[2];
- }
- else {
- normal[0] = - j->contact.geom.normal[0];
- normal[1] = - j->contact.geom.normal[1];
- normal[2] = - j->contact.geom.normal[2];
- }
- normal[3] = 0; // @@@ hmmm
-
- // c1,c2 = contact points with respect to body PORs
- dVector3 c1,c2;
- for (i=0; i<3; i++) c1[i] = j->contact.geom.pos[i] - j->node[0].body->pos[i];
-
- // set jacobian for normal
- info->J1l[0] = normal[0];
- info->J1l[1] = normal[1];
- info->J1l[2] = normal[2];
- dCROSS (info->J1a,=,c1,normal);
- if (j->node[1].body) {
- for (i=0; i<3; i++) c2[i] = j->contact.geom.pos[i] -
- j->node[1].body->pos[i];
- info->J2l[0] = -normal[0];
- info->J2l[1] = -normal[1];
- info->J2l[2] = -normal[2];
- dCROSS (info->J2a,= -,c2,normal);
- }
-
- // set right hand side and cfm value for normal
- dReal erp = info->erp;
- if (j->contact.surface.mode & dContactSoftERP)
- erp = j->contact.surface.soft_erp;
- dReal k = info->fps * erp;
- info->c[0] = k*j->contact.geom.depth;
- if (j->contact.surface.mode & dContactSoftCFM)
- info->cfm[0] = j->contact.surface.soft_cfm;
-
- // deal with bounce
- if (j->contact.surface.mode & dContactBounce) {
- // calculate outgoing velocity (-ve for incoming contact)
- dReal outgoing = dDOT(info->J1l,j->node[0].body->lvel) +
- dDOT(info->J1a,j->node[0].body->avel);
- if (j->node[1].body) {
- outgoing += dDOT(info->J2l,j->node[1].body->lvel) +
- dDOT(info->J2a,j->node[1].body->avel);
- }
- // only apply bounce if the outgoing velocity is greater than the
- // threshold, and if the resulting c[0] exceeds what we already have.
- if (j->contact.surface.bounce_vel >= 0 &&
- (-outgoing) > j->contact.surface.bounce_vel) {
- dReal newc = - j->contact.surface.bounce * outgoing;
- if (newc > info->c[0]) info->c[0] = newc;
- }
- }
-
- // set LCP limits for normal
- info->lo[0] = 0;
- info->hi[0] = dInfinity;
-
- // now do jacobian for tangential forces
- dVector3 t1,t2; // two vectors tangential to normal
-
- // first friction direction
- if (j->the_m >= 2) {
- if (j->contact.surface.mode & dContactFDir1) { // use fdir1 ?
- t1[0] = j->contact.fdir1[0];
- t1[1] = j->contact.fdir1[1];
- t1[2] = j->contact.fdir1[2];
- dCROSS (t2,=,normal,t1);
- }
- else {
- dPlaneSpace (normal,t1,t2);
- }
- info->J1l[s+0] = t1[0];
- info->J1l[s+1] = t1[1];
- info->J1l[s+2] = t1[2];
- dCROSS (info->J1a+s,=,c1,t1);
- if (j->node[1].body) {
- info->J2l[s+0] = -t1[0];
- info->J2l[s+1] = -t1[1];
- info->J2l[s+2] = -t1[2];
- dCROSS (info->J2a+s,= -,c2,t1);
- }
- // set right hand side
- if (j->contact.surface.mode & dContactMotion1) {
- info->c[1] = j->contact.surface.motion1;
- }
- // set LCP bounds and friction index. this depends on the approximation
- // mode
- info->lo[1] = -j->contact.surface.mu;
- info->hi[1] = j->contact.surface.mu;
- if (j->contact.surface.mode & dContactApprox1_1) info->findex[1] = 0;
-
- // set slip (constraint force mixing)
- if (j->contact.surface.mode & dContactSlip1)
- info->cfm[1] = j->contact.surface.slip1;
- }
-
- // second friction direction
- if (j->the_m >= 3) {
- info->J1l[s2+0] = t2[0];
- info->J1l[s2+1] = t2[1];
- info->J1l[s2+2] = t2[2];
- dCROSS (info->J1a+s2,=,c1,t2);
- if (j->node[1].body) {
- info->J2l[s2+0] = -t2[0];
- info->J2l[s2+1] = -t2[1];
- info->J2l[s2+2] = -t2[2];
- dCROSS (info->J2a+s2,= -,c2,t2);
- }
- // set right hand side
- if (j->contact.surface.mode & dContactMotion2) {
- info->c[2] = j->contact.surface.motion2;
- }
- // set LCP bounds and friction index. this depends on the approximation
- // mode
- if (j->contact.surface.mode & dContactMu2) {
- info->lo[2] = -j->contact.surface.mu2;
- info->hi[2] = j->contact.surface.mu2;
- }
- else {
- info->lo[2] = -j->contact.surface.mu;
- info->hi[2] = j->contact.surface.mu;
- }
- if (j->contact.surface.mode & dContactApprox1_2) info->findex[2] = 0;
-
- // set slip (constraint force mixing)
- if (j->contact.surface.mode & dContactSlip2)
- info->cfm[2] = j->contact.surface.slip2;
- }
-}
-
-
-dxJoint::Vtable __dcontact_vtable = {
- sizeof(dxJointContact),
- (dxJoint::init_fn*) contactInit,
- (dxJoint::getInfo1_fn*) contactGetInfo1,
- (dxJoint::getInfo2_fn*) contactGetInfo2,
- dJointTypeContact};
-
-//****************************************************************************
-// hinge 2. note that this joint must be attached to two bodies for it to work
-
-static dReal measureHinge2Angle (dxJointHinge2 *joint)
-{
- dVector3 a1,a2;
- dMULTIPLY0_331 (a1,joint->node[1].body->R,joint->axis2);
- dMULTIPLY1_331 (a2,joint->node[0].body->R,a1);
- dReal x = dDOT(joint->v1,a2);
- dReal y = dDOT(joint->v2,a2);
- return -dAtan2 (y,x);
-}
-
-
-static void hinge2Init (dxJointHinge2 *j)
-{
- dSetZero (j->anchor1,4);
- dSetZero (j->anchor2,4);
- dSetZero (j->axis1,4);
- j->axis1[0] = 1;
- dSetZero (j->axis2,4);
- j->axis2[1] = 1;
- j->c0 = 0;
- j->s0 = 0;
-
- dSetZero (j->v1,4);
- j->v1[0] = 1;
- dSetZero (j->v2,4);
- j->v2[1] = 1;
-
- j->limot1.init (j->world);
- j->limot2.init (j->world);
-
- j->susp_erp = j->world->global_erp;
- j->susp_cfm = j->world->global_cfm;
-
- j->flags |= dJOINT_TWOBODIES;
-}
-
-
-static void hinge2GetInfo1 (dxJointHinge2 *j, dxJoint::Info1 *info)
-{
- info->m = 4;
- info->nub = 4;
-
- // see if we're powered or at a joint limit for axis 1
- int atlimit=0;
- if ((j->limot1.lostop >= -M_PI || j->limot1.histop <= M_PI) &&
- j->limot1.lostop <= j->limot1.histop) {
- dReal angle = measureHinge2Angle (j);
- if (j->limot1.testRotationalLimit (angle)) atlimit = 1;
- }
- if (atlimit || j->limot1.fmax > 0) info->m++;
-
- // see if we're powering axis 2 (we currently never limit this axis)
- j->limot2.limit = 0;
- if (j->limot2.fmax > 0) info->m++;
-}
-
-
-// macro that computes ax1,ax2 = axis 1 and 2 in global coordinates (they are
-// relative to body 1 and 2 initially) and then computes the constrained
-// rotational axis as the cross product of ax1 and ax2.
-// the sin and cos of the angle between axis 1 and 2 is computed, this comes
-// from dot and cross product rules.
-
-#define HINGE2_GET_AXIS_INFO(axis,sin_angle,cos_angle) \
- dVector3 ax1,ax2; \
- dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1); \
- dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2); \
- dCROSS (axis,=,ax1,ax2); \
- sin_angle = dSqrt (axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]); \
- cos_angle = dDOT (ax1,ax2);
-
-
-static void hinge2GetInfo2 (dxJointHinge2 *joint, dxJoint::Info2 *info)
-{
- // get information we need to set the hinge row
- dReal s,c;
- dVector3 q;
- HINGE2_GET_AXIS_INFO (q,s,c);
- dNormalize3 (q); // @@@ quicker: divide q by s ?
-
- // set the three ball-and-socket rows (aligned to the suspension axis ax1)
- setBall2 (joint,info,joint->anchor1,joint->anchor2,ax1,joint->susp_erp);
-
- // set the hinge row
- int s3=3*info->rowskip;
- info->J1a[s3+0] = q[0];
- info->J1a[s3+1] = q[1];
- info->J1a[s3+2] = q[2];
- if (joint->node[1].body) {
- info->J2a[s3+0] = -q[0];
- info->J2a[s3+1] = -q[1];
- info->J2a[s3+2] = -q[2];
- }
-
- // compute the right hand side for the constrained rotational DOF.
- // axis 1 and axis 2 are separated by an angle `theta'. the desired
- // separation angle is theta0. sin(theta0) and cos(theta0) are recorded
- // in the joint structure. the correcting angular velocity is:
- // |angular_velocity| = angle/time = erp*(theta0-theta) / stepsize
- // = (erp*fps) * (theta0-theta)
- // (theta0-theta) can be computed using the following small-angle-difference
- // approximation:
- // theta0-theta ~= tan(theta0-theta)
- // = sin(theta0-theta)/cos(theta0-theta)
- // = (c*s0 - s*c0) / (c*c0 + s*s0)
- // = c*s0 - s*c0 assuming c*c0 + s*s0 ~= 1
- // where c = cos(theta), s = sin(theta)
- // c0 = cos(theta0), s0 = sin(theta0)
-
- dReal k = info->fps * info->erp;
- info->c[3] = k * (joint->c0 * s - joint->s0 * c);
-
- // if the axis1 hinge is powered, or has joint limits, add in more stuff
- int row = 4 + joint->limot1.addLimot (joint,info,4,ax1,1);
-
- // if the axis2 hinge is powered, add in more stuff
- joint->limot2.addLimot (joint,info,row,ax2,1);
-
- // set parameter for the suspension
- info->cfm[0] = joint->susp_cfm;
-}
-
-
-// compute vectors v1 and v2 (embedded in body1), used to measure angle
-// between body 1 and body 2
-
-static void makeHinge2V1andV2 (dxJointHinge2 *joint)
-{
- if (joint->node[0].body) {
- // get axis 1 and 2 in global coords
- dVector3 ax1,ax2,v;
- dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1);
- dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2);
-
- // don't do anything if the axis1 or axis2 vectors are zero or the same
- if ((ax1[0]==0 && ax1[1]==0 && ax1[2]==0) ||
- (ax2[0]==0 && ax2[1]==0 && ax2[2]==0) ||
- (ax1[0]==ax2[0] && ax1[1]==ax2[1] && ax1[2]==ax2[2])) return;
-
- // modify axis 2 so it's perpendicular to axis 1
- dReal k = dDOT(ax1,ax2);
- for (int i=0; i<3; i++) ax2[i] -= k*ax1[i];
- dNormalize3 (ax2);
-
- // make v1 = modified axis2, v2 = axis1 x (modified axis2)
- dCROSS (v,=,ax1,ax2);
- dMULTIPLY1_331 (joint->v1,joint->node[0].body->R,ax2);
- dMULTIPLY1_331 (joint->v2,joint->node[0].body->R,v);
- }
-}
-
-
-extern "C" void dJointSetHinge2Anchor (dxJointHinge2 *joint,
- dReal x, dReal y, dReal z)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2);
- makeHinge2V1andV2 (joint);
-}
-
-
-extern "C" void dJointSetHinge2Axis1 (dxJointHinge2 *joint,
- dReal x, dReal y, dReal z)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- if (joint->node[0].body) {
- dReal q[4];
- q[0] = x;
- q[1] = y;
- q[2] = z;
- q[3] = 0;
- dNormalize3 (q);
- dMULTIPLY1_331 (joint->axis1,joint->node[0].body->R,q);
- joint->axis1[3] = 0;
-
- // compute the sin and cos of the angle between axis 1 and axis 2
- dVector3 ax;
- HINGE2_GET_AXIS_INFO(ax,joint->s0,joint->c0);
- }
- makeHinge2V1andV2 (joint);
-}
-
-
-extern "C" void dJointSetHinge2Axis2 (dxJointHinge2 *joint,
- dReal x, dReal y, dReal z)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- if (joint->node[1].body) {
- dReal q[4];
- q[0] = x;
- q[1] = y;
- q[2] = z;
- q[3] = 0;
- dNormalize3 (q);
- dMULTIPLY1_331 (joint->axis2,joint->node[1].body->R,q);
- joint->axis1[3] = 0;
-
- // compute the sin and cos of the angle between axis 1 and axis 2
- dVector3 ax;
- HINGE2_GET_AXIS_INFO(ax,joint->s0,joint->c0);
- }
- makeHinge2V1andV2 (joint);
-}
-
-
-extern "C" void dJointSetHinge2Param (dxJointHinge2 *joint,
- int parameter, dReal value)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- if ((parameter & 0xff00) == 0x100) {
- joint->limot2.set (parameter & 0xff,value);
- }
- else {
- if (parameter == dParamSuspensionERP) joint->susp_erp = value;
- else if (parameter == dParamSuspensionCFM) joint->susp_cfm = value;
- else joint->limot1.set (parameter,value);
- }
-}
-
-
-extern "C" void dJointGetHinge2Anchor (dxJointHinge2 *joint, dVector3 result)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(result,"bad result argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- getAnchor (joint,result,joint->anchor1);
-}
-
-
-extern "C" void dJointGetHinge2Axis1 (dxJointHinge2 *joint, dVector3 result)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(result,"bad result argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- if (joint->node[0].body) {
- dMULTIPLY0_331 (result,joint->node[0].body->R,joint->axis1);
- }
-}
-
-
-extern "C" void dJointGetHinge2Axis2 (dxJointHinge2 *joint, dVector3 result)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(result,"bad result argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- if (joint->node[1].body) {
- dMULTIPLY0_331 (result,joint->node[1].body->R,joint->axis2);
- }
-}
-
-
-extern "C" dReal dJointGetHinge2Param (dxJointHinge2 *joint, int parameter)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- if ((parameter & 0xff00) == 0x100) {
- return joint->limot2.get (parameter & 0xff);
- }
- else {
- if (parameter == dParamSuspensionERP) return joint->susp_erp;
- else if (parameter == dParamSuspensionCFM) return joint->susp_cfm;
- else return joint->limot1.get (parameter);
- }
-}
-
-
-extern "C" dReal dJointGetHinge2Angle1 (dxJointHinge2 *joint)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- if (joint->node[0].body) return measureHinge2Angle (joint);
- else return 0;
-}
-
-
-extern "C" dReal dJointGetHinge2Angle1Rate (dxJointHinge2 *joint)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- if (joint->node[0].body) {
- dVector3 axis;
- dMULTIPLY0_331 (axis,joint->node[0].body->R,joint->axis1);
- dReal rate = dDOT(axis,joint->node[0].body->avel);
- if (joint->node[1].body) rate -= dDOT(axis,joint->node[1].body->avel);
- return rate;
- }
- else return 0;
-}
-
-
-extern "C" dReal dJointGetHinge2Angle2Rate (dxJointHinge2 *joint)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dhinge2_vtable,"joint is not a hinge2");
- if (joint->node[0].body && joint->node[1].body) {
- dVector3 axis;
- dMULTIPLY0_331 (axis,joint->node[1].body->R,joint->axis2);
- dReal rate = dDOT(axis,joint->node[0].body->avel);
- if (joint->node[1].body) rate -= dDOT(axis,joint->node[1].body->avel);
- return rate;
- }
- else return 0;
-}
-
-
-dxJoint::Vtable __dhinge2_vtable = {
- sizeof(dxJointHinge2),
- (dxJoint::init_fn*) hinge2Init,
- (dxJoint::getInfo1_fn*) hinge2GetInfo1,
- (dxJoint::getInfo2_fn*) hinge2GetInfo2,
- dJointTypeHinge2};
-
-//****************************************************************************
-// universal
-
-static void universalInit (dxJointUniversal *j)
-{
- dSetZero (j->anchor1,4);
- dSetZero (j->anchor2,4);
- dSetZero (j->axis1,4);
- j->axis1[0] = 1;
- dSetZero (j->axis2,4);
- j->axis2[1] = 1;
-}
-
-
-static void universalGetInfo1 (dxJointUniversal *j, dxJoint::Info1 *info)
-{
- info->nub = 4;
- info->m = 4;
-}
-
-
-static void universalGetInfo2 (dxJointUniversal *joint, dxJoint::Info2 *info)
-{
- // set the three ball-and-socket rows
- setBall (joint,info,joint->anchor1,joint->anchor2);
-
- // set the universal joint row. the angular velocity about an axis
- // perpendicular to both joint axes should be equal. thus the constraint
- // equation is
- // p*w1 - p*w2 = 0
- // where p is a vector normal to both joint axes, and w1 and w2
- // are the angular velocity vectors of the two bodies.
-
- // length 1 joint axis in global coordinates, from each body
- dVector3 ax1, ax2;
- // length 1 vector perpendicular to ax1 and ax2. Neither body can rotate
- // about this.
- dVector3 p;
-
- // This says "ax1 = joint->node[0].body->R * joint->axis1"
- dMULTIPLY0_331 (ax1,joint->node[0].body->R,joint->axis1);
- if (joint->node[1].body) {
- dMULTIPLY0_331 (ax2,joint->node[1].body->R,joint->axis2);
- }
- else {
- ax2[0] = joint->axis2[0];
- ax2[1] = joint->axis2[1];
- ax2[2] = joint->axis2[2];
- }
-
- // if ax1 and ax2 are almost parallel, p won't be perpendicular to them.
- // Is there some more robust way to do this?
- dCROSS(p, =, ax1, ax2);
- dNormalize3(p);
-
- int s3=3*info->rowskip;
-
- info->J1a[s3+0] = p[0];
- info->J1a[s3+1] = p[1];
- info->J1a[s3+2] = p[2];
-
- if (joint->node[1].body) {
- info->J2a[s3+0] = -p[0];
- info->J2a[s3+1] = -p[1];
- info->J2a[s3+2] = -p[2];
- }
-
- // compute the right hand side of the constraint equation. set relative
- // body velocities along p to bring the axes back to perpendicular.
- // If ax1, ax2 are unit length joint axes as computed from body1 and
- // body2, we need to rotate both bodies along the axis p. If theta
- // is the angle between ax1 and ax2, we need an angular velocity
- // along p to cover the angle erp * (theta - Pi/2) in one step:
- //
- // |angular_velocity| = angle/time = erp*(theta - Pi/2) / stepsize
- // = (erp*fps) * (theta - Pi/2)
- //
- // if theta is close to Pi/2,
- // theta - Pi/2 ~= cos(theta), so
- // |angular_velocity| = (erp*fps) * (ax1 dot ax2)
-
- info->c[3] = info->fps * info->erp * - dDOT(ax1, ax2);
-}
-
-
-extern "C" void dJointSetUniversalAnchor (dxJointUniversal *joint,
- dReal x, dReal y, dReal z)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal");
- setAnchors (joint,x,y,z,joint->anchor1,joint->anchor2);
-}
-
-
-extern "C" void dJointSetUniversalAxis1 (dxJointUniversal *joint,
- dReal x, dReal y, dReal z)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal");
- if (joint->node[0].body) {
- dReal q[4];
- q[0] = x;
- q[1] = y;
- q[2] = z;
- q[3] = 0;
- dNormalize3 (q);
- dMULTIPLY1_331 (joint->axis1,joint->node[0].body->R,q);
- }
- joint->axis1[3] = 0;
-}
-
-
-extern "C" void dJointSetUniversalAxis2 (dxJointUniversal *joint,
- dReal x, dReal y, dReal z)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal");
- if (joint->node[1].body) {
- dReal q[4];
- q[0] = x;
- q[1] = y;
- q[2] = z;
- q[3] = 0;
- dNormalize3 (q);
- dMULTIPLY1_331 (joint->axis2,joint->node[1].body->R,q);
- }
- joint->axis2[3] = 0;
-}
-
-
-extern "C" void dJointGetUniversalAnchor (dxJointUniversal *joint,
- dVector3 result)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(result,"bad result argument");
- dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal");
- getAnchor (joint,result,joint->anchor1);
-}
-
-
-extern "C" void dJointGetUniversalAxis1 (dxJointUniversal *joint,
- dVector3 result)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(result,"bad result argument");
- dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal");
- if (joint->node[0].body) {
- dMULTIPLY0_331 (result, joint->node[0].body->R, joint->axis1);
- }
-}
-
-
-extern "C" void dJointGetUniversalAxis2 (dxJointUniversal *joint,
- dVector3 result)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(result,"bad result argument");
- dUASSERT(joint->vtable == &__duniversal_vtable,"joint is not a universal");
- if (joint->node[1].body) {
- dMULTIPLY0_331 (result, joint->node[1].body->R, joint->axis2);
- }
-}
-
-
-dxJoint::Vtable __duniversal_vtable = {
- sizeof(dxJointUniversal),
- (dxJoint::init_fn*) universalInit,
- (dxJoint::getInfo1_fn*) universalGetInfo1,
- (dxJoint::getInfo2_fn*) universalGetInfo2,
- dJointTypeUniversal};
-
-//****************************************************************************
-// angular motor
-
-static void amotorInit (dxJointAMotor *j)
-{
- int i;
- j->num = 0;
- j->mode = dAMotorUser;
- for (i=0; i<3; i++) {
- j->rel[i] = 0;
- dSetZero (j->axis[i],4);
- j->limot[i].init (j->world);
- j->angle[i] = 0;
- }
- dSetZero (j->reference1,4);
- dSetZero (j->reference2,4);
-
- j->flags |= dJOINT_TWOBODIES;
-}
-
-
-// compute the 3 axes in global coordinates
-
-static void amotorComputeGlobalAxes (dxJointAMotor *joint, dVector3 ax[3])
-{
- if (joint->mode == dAMotorEuler) {
- // special handling for euler mode
- dMULTIPLY0_331 (ax[0],joint->node[0].body->R,joint->axis[0]);
- dMULTIPLY0_331 (ax[2],joint->node[1].body->R,joint->axis[2]);
- dCROSS (ax[1],=,ax[2],ax[0]);
- dNormalize3 (ax[1]);
- }
- else {
- for (int i=0; i < joint->num; i++) {
- if (joint->rel[i] == 1) {
- // relative to b1
- dMULTIPLY0_331 (ax[i],joint->node[0].body->R,joint->axis[i]);
- }
- if (joint->rel[i] == 2) {
- // relative to b2
- dMULTIPLY0_331 (ax[i],joint->node[1].body->R,joint->axis[i]);
- }
- else {
- // global - just copy it
- ax[i][0] = joint->axis[i][0];
- ax[i][1] = joint->axis[i][1];
- ax[i][2] = joint->axis[i][2];
- }
- }
- }
-}
-
-
-static void amotorComputeEulerAngles (dxJointAMotor *joint, dVector3 ax[3])
-{
- // assumptions:
- // global axes already calculated --> ax
- // axis[0] is relative to body 1 --> global ax[0]
- // axis[2] is relative to body 2 --> global ax[2]
- // ax[1] = ax[2] x ax[0]
- // original ax[0] and ax[2] are perpendicular
- // reference1 is perpendicular to ax[0] (in body 1 frame)
- // reference2 is perpendicular to ax[2] (in body 2 frame)
- // all ax[] and reference vectors are unit length
-
- // calculate references in global frame
- dVector3 ref1,ref2;
- dMULTIPLY0_331 (ref1,joint->node[0].body->R,joint->reference1);
- dMULTIPLY0_331 (ref2,joint->node[1].body->R,joint->reference2);
-
- // get q perpendicular to both ax[0] and ref1, get first euler angle
- dVector3 q;
- dCROSS (q,=,ax[0],ref1);
- joint->angle[0] = -dAtan2 (dDOT(ax[2],q),dDOT(ax[2],ref1));
-
- // get q perpendicular to both ax[0] and ax[1], get second euler angle
- dCROSS (q,=,ax[0],ax[1]);
- joint->angle[1] = -dAtan2 (dDOT(ax[2],ax[0]),dDOT(ax[2],q));
-
- // get q perpendicular to both ax[1] and ax[2], get third euler angle
- dCROSS (q,=,ax[1],ax[2]);
- joint->angle[2] = -dAtan2 (dDOT(ref2,ax[1]), dDOT(ref2,q));
-}
-
-
-// set the reference vectors as follows:
-// * reference1 = current axis[2] relative to body 1
-// * reference2 = current axis[0] relative to body 2
-// this assumes that:
-// * axis[0] is relative to body 1
-// * axis[2] is relative to body 2
-
-static void amotorSetEulerReferenceVectors (dxJointAMotor *j)
-{
- if (j->node[0].body && j->node[1].body) {
- dVector3 r; // axis[2] and axis[0] in global coordinates
- dMULTIPLY0_331 (r,j->node[1].body->R,j->axis[2]);
- dMULTIPLY1_331 (j->reference1,j->node[0].body->R,r);
- dMULTIPLY0_331 (r,j->node[0].body->R,j->axis[0]);
- dMULTIPLY1_331 (j->reference2,j->node[1].body->R,r);
- }
-}
-
-
-static void amotorGetInfo1 (dxJointAMotor *j, dxJoint::Info1 *info)
-{
- info->m = 0;
- info->nub = 0;
-
- // compute the axes and angles, if in euler mode
- if (j->mode == dAMotorEuler) {
- dVector3 ax[3];
- amotorComputeGlobalAxes (j,ax);
- amotorComputeEulerAngles (j,ax);
- }
-
- // see if we're powered or at a joint limit for each axis
- for (int i=0; i < j->num; i++) {
- if (j->limot[i].testRotationalLimit (j->angle[i]) ||
- j->limot[i].fmax > 0) {
- info->m++;
- }
- }
-}
-
-
-static void amotorGetInfo2 (dxJointAMotor *joint, dxJoint::Info2 *info)
-{
- int i;
-
- // compute the axes (if not global)
- dVector3 ax[3];
- amotorComputeGlobalAxes (joint,ax);
-
- // 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.
-
- dVector3 *axptr[3];
- axptr[0] = &ax[0];
- axptr[1] = &ax[1];
- axptr[2] = &ax[2];
-
- dVector3 ax0_cross_ax1;
- dVector3 ax1_cross_ax2;
- if (joint->mode == dAMotorEuler) {
- dCROSS (ax0_cross_ax1,=,ax[0],ax[1]);
- axptr[2] = &ax0_cross_ax1;
- dCROSS (ax1_cross_ax2,=,ax[1],ax[2]);
- axptr[0] = &ax1_cross_ax2;
- }
-
- int row=0;
- for (i=0; i < joint->num; i++) {
- row += joint->limot[i].addLimot (joint,info,row,*(axptr[i]),1);
- }
-}
-
-
-extern "C" void dJointSetAMotorNumAxes (dxJointAMotor *joint, int num)
-{
- dAASSERT(joint && num >= 0 && num <= 3);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- if (joint->mode == dAMotorEuler) {
- joint->num = 3;
- }
- else {
- if (num < 0) num = 0;
- if (num > 3) num = 3;
- joint->num = num;
- }
-}
-
-
-extern "C" void dJointSetAMotorAxis (dxJointAMotor *joint, int anum, int rel,
- dReal x, dReal y, dReal z)
-{
- dAASSERT(joint && anum >= 0 && anum <= 2 && rel >= 0 && rel <= 2);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- if (anum < 0) anum = 0;
- if (anum > 2) anum = 2;
- joint->rel[anum] = rel;
-
- // x,y,z is always in global coordinates regardless of rel, so we may have
- // to convert it to be relative to a body
- dVector3 r;
- r[0] = x;
- r[1] = y;
- r[2] = z;
- r[3] = 0;
- if (rel > 0) {
- if (rel==1) {
- dMULTIPLY1_331 (joint->axis[anum],joint->node[0].body->R,r);
- }
- else {
- dMULTIPLY1_331 (joint->axis[anum],joint->node[1].body->R,r);
- }
- }
- else {
- joint->axis[anum][0] = r[0];
- joint->axis[anum][1] = r[1];
- joint->axis[anum][2] = r[2];
- }
- dNormalize3 (joint->axis[anum]);
- if (joint->mode == dAMotorEuler) amotorSetEulerReferenceVectors (joint);
-}
-
-
-extern "C" void dJointSetAMotorAngle (dxJointAMotor *joint, int anum,
- dReal angle)
-{
- dAASSERT(joint && anum >= 0 && anum < 3);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- if (joint->mode == dAMotorUser) {
- if (anum < 0) anum = 0;
- if (anum > 3) anum = 3;
- joint->angle[anum] = angle;
- }
-}
-
-
-extern "C" void dJointSetAMotorParam (dxJointAMotor *joint, int parameter,
- dReal value)
-{
- dAASSERT(joint);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- int anum = parameter >> 8;
- if (anum < 0) anum = 0;
- if (anum > 2) anum = 2;
- parameter &= 0xff;
- joint->limot[anum].set (parameter, value);
-}
-
-
-extern "C" void dJointSetAMotorMode (dxJointAMotor *joint, int mode)
-{
- dAASSERT(joint);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- joint->mode = mode;
- if (joint->mode == dAMotorEuler) {
- joint->num = 3;
- amotorSetEulerReferenceVectors (joint);
- }
-}
-
-
-extern "C" int dJointGetAMotorNumAxes (dxJointAMotor *joint)
-{
- dAASSERT(joint);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- return joint->num;
-}
-
-
-extern "C" void dJointGetAMotorAxis (dxJointAMotor *joint, int anum,
- dVector3 result)
-{
- dAASSERT(joint && anum >= 0 && anum < 3);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- if (anum < 0) anum = 0;
- if (anum > 2) anum = 2;
- if (joint->rel[anum] > 0) {
- if (joint->rel[anum]==1) {
- dMULTIPLY0_331 (result,joint->node[0].body->R,joint->axis[anum]);
- }
- else {
- dMULTIPLY0_331 (result,joint->node[1].body->R,joint->axis[anum]);
- }
- }
- else {
- result[0] = joint->axis[anum][0];
- result[1] = joint->axis[anum][1];
- result[2] = joint->axis[anum][2];
- }
-}
-
-
-extern "C" int dJointGetAMotorAxisRel (dxJointAMotor *joint, int anum)
-{
- dAASSERT(joint && anum >= 0 && anum < 3);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- if (anum < 0) anum = 0;
- if (anum > 2) anum = 2;
- return joint->rel[anum];
-}
-
-
-extern "C" dReal dJointGetAMotorAngle (dxJointAMotor *joint, int anum)
-{
- dAASSERT(joint && anum >= 0 && anum < 3);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- if (anum < 0) anum = 0;
- if (anum > 3) anum = 3;
- return joint->angle[anum];
-}
-
-
-extern "C" dReal dJointGetAMotorAngleRate (dxJointAMotor *joint, int anum)
-{
- // @@@
- dDebug (0,"not yet implemented");
- return 0;
-}
-
-
-extern "C" dReal dJointGetAMotorParam (dxJointAMotor *joint, int parameter)
-{
- dAASSERT(joint);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- int anum = parameter >> 8;
- if (anum < 0) anum = 0;
- if (anum > 2) anum = 2;
- parameter &= 0xff;
- return joint->limot[anum].get (parameter);
-}
-
-
-extern "C" int dJointGetAMotorMode (dxJointAMotor *joint)
-{
- dAASSERT(joint);
- dUASSERT(joint->vtable == &__damotor_vtable,"joint is not an amotor");
- return joint->mode;
-}
-
-
-dxJoint::Vtable __damotor_vtable = {
- sizeof(dxJointAMotor),
- (dxJoint::init_fn*) amotorInit,
- (dxJoint::getInfo1_fn*) amotorGetInfo1,
- (dxJoint::getInfo2_fn*) amotorGetInfo2,
- dJointTypeAMotor};
-
-//****************************************************************************
-// fixed joint
-
-static void fixedInit (dxJointFixed *j)
-{
- dSetZero (j->offset,4);
-}
-
-
-static void fixedGetInfo1 (dxJointFixed *j, dxJoint::Info1 *info)
-{
- info->m = 6;
- info->nub = 6;
-}
-
-
-static void fixedGetInfo2 (dxJointFixed *joint, dxJoint::Info2 *info)
-{
- int s = info->rowskip;
-
- // set jacobian
- info->J1l[0] = 1;
- info->J1l[s+1] = 1;
- info->J1l[2*s+2] = 1;
- info->J1a[3*s] = 1;
- info->J1a[4*s+1] = 1;
- info->J1a[5*s+2] = 1;
-
- dVector3 ofs;
- if (joint->node[1].body) {
- dMULTIPLY0_331 (ofs,joint->node[0].body->R,joint->offset);
- dCROSSMAT (info->J1a,ofs,s,+,-);
- info->J2l[0] = -1;
- info->J2l[s+1] = -1;
- info->J2l[2*s+2] = -1;
- info->J2a[3*s] = -1;
- info->J2a[4*s+1] = -1;
- info->J2a[5*s+2] = -1;
- }
-
- // set right hand side for the first three rows (linear)
- dReal k = info->fps * info->erp;
- if (joint->node[1].body) {
- for (int j=0; j<3; j++)
- info->c[j] = k * (joint->node[1].body->pos[j] -
- joint->node[0].body->pos[j] + ofs[j]);
- }
- else {
- for (int j=0; j<3; j++)
- info->c[j] = k * (joint->offset[j] - joint->node[0].body->pos[j]);
- }
-
- // set right hand side for the next three rows (angular). this code is
- // borrowed from the slider, so look at the comments there.
- // @@@ make a function common to both the slider and this joint !!!
-
- // get qerr = relative rotation (rotation error) between two bodies
- dQuaternion qerr,e;
- if (joint->node[1].body) {
- dQMultiply1 (qerr,joint->node[0].body->q,joint->node[1].body->q);
- }
- else {
- qerr[0] = joint->node[0].body->q[0];
- for (int i=1; i<4; i++) qerr[i] = -joint->node[0].body->q[i];
- }
- if (qerr[0] < 0) {
- qerr[1] = -qerr[1]; // adjust sign of qerr to make theta small
- qerr[2] = -qerr[2];
- qerr[3] = -qerr[3];
- }
- dMULTIPLY0_331 (e,joint->node[0].body->R,qerr+1); // @@@ bad SIMD padding!
- info->c[3] = 2*k * e[0];
- info->c[4] = 2*k * e[1];
- info->c[5] = 2*k * e[2];
-}
-
-
-extern "C" void dJointSetFixed (dxJointFixed *joint)
-{
- dUASSERT(joint,"bad joint argument");
- dUASSERT(joint->vtable == &__dfixed_vtable,"joint is not fixed");
- int i;
-
- // compute the offset between the bodies
- if (joint->node[0].body) {
- if (joint->node[1].body) {
- dReal ofs[4];
- for (i=0; i<4; i++) ofs[i] = joint->node[0].body->pos[i];
- for (i=0; i<4; i++) ofs[i] -= joint->node[1].body->pos[i];
- dMULTIPLY1_331 (joint->offset,joint->node[0].body->R,ofs);
- }
- else {
- for (i=0; i<4; i++) joint->offset[i] = joint->node[0].body->pos[i];
- }
- }
-}
-
-
-dxJoint::Vtable __dfixed_vtable = {
- sizeof(dxJointFixed),
- (dxJoint::init_fn*) fixedInit,
- (dxJoint::getInfo1_fn*) fixedGetInfo1,
- (dxJoint::getInfo2_fn*) fixedGetInfo2,
- dJointTypeFixed};
-
-//****************************************************************************
-// null joint
-
-static void nullGetInfo1 (dxJointNull *j, dxJoint::Info1 *info)
-{
- info->m = 0;
- info->nub = 0;
-}
-
-
-static void nullGetInfo2 (dxJointNull *joint, dxJoint::Info2 *info)
-{
- dDebug (0,"this should never get called");
-}
-
-
-dxJoint::Vtable __dnull_vtable = {
- sizeof(dxJointNull),
- (dxJoint::init_fn*) 0,
- (dxJoint::getInfo1_fn*) nullGetInfo1,
- (dxJoint::getInfo2_fn*) nullGetInfo2,
- dJointTypeNull};
diff --git a/extern/ode/dist/ode/src/joint.h b/extern/ode/dist/ode/src/joint.h
deleted file mode 100644
index e0362ffa829..00000000000
--- a/extern/ode/dist/ode/src/joint.h
+++ /dev/null
@@ -1,260 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_JOINT_H_
-#define _ODE_JOINT_H_
-
-
-#include "objects.h"
-#include <ode/contact.h>
-#include "obstack.h"
-
-
-// joint flags
-enum {
- // if this flag is set, the joint was allocated in a joint group
- dJOINT_INGROUP = 1,
-
- // if this flag is set, the joint was attached with arguments (0,body).
- // our convention is to treat all attaches as (body,0), i.e. so node[0].body
- // is always nonzero, so this flag records the fact that the arguments were
- // swapped.
- dJOINT_REVERSE = 2,
-
- // if this flag is set, the joint can not have just one body attached to it,
- // it must have either zero or two bodies attached.
- dJOINT_TWOBODIES = 4
-};
-
-
-// there are two of these nodes in the joint, one for each connection to a
-// body. these are node of a linked list kept by each body of it's connecting
-// joints. but note that the body pointer in each node points to the body that
-// makes use of the *other* node, not this node. this trick makes it a bit
-// easier to traverse the body/joint graph.
-
-struct dxJointNode {
- dxJoint *joint; // pointer to enclosing dxJoint object
- dxBody *body; // *other* body this joint is connected to
- dxJointNode *next; // next node in body's list of connected joints
-};
-
-
-struct dxJoint : public dObject {
- // naming convention: the "first" body this is connected to is node[0].body,
- // and the "second" body is node[1].body. if this joint is only connected
- // to one body then the second body is 0.
-
- // info returned by getInfo1 function. the constraint dimension is m (<=6).
- // i.e. that is the total number of rows in the jacobian. `nub' is the
- // number of unbounded variables (which have lo,hi = -/+ infinity).
-
- struct Info1 {
- int m,nub;
- };
-
- // info returned by getInfo2 function
-
- struct Info2 {
- // integrator parameters: frames per second (1/stepsize), default error
- // reduction parameter (0..1).
- dReal 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.
- dReal *J1l,*J1a,*J2l,*J2a;
-
- // 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.
- dReal *c,*cfm;
-
- // lo and hi limits for variables (set to -/+ infinity on entry).
- dReal *lo,*hi;
-
- // 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 function table: size of the joint structure, function pointers.
- // we do it this way instead of using C++ virtual functions because
- // sometimes we need to allocate joints ourself within a memory pool.
-
- typedef void init_fn (dxJoint *joint);
- typedef void getInfo1_fn (dxJoint *joint, Info1 *info);
- typedef void getInfo2_fn (dxJoint *joint, Info2 *info);
- struct Vtable {
- int size;
- init_fn *init;
- getInfo1_fn *getInfo1;
- getInfo2_fn *getInfo2;
- int typenum; // a dJointTypeXXX type number
- };
-
- Vtable *vtable; // virtual function table
- int flags; // dJOINT_xxx flags
- dxJointNode node[2]; // connections to bodies. node[1].body can be 0
- dJointFeedback *feedback; // optional feedback structure
-};
-
-
-// joint group. NOTE: any joints in the group that have their world destroyed
-// will have their world pointer set to 0.
-
-struct dxJointGroup : public dBase {
- int num; // number of joints on the stack
- dObStack stack; // a stack of (possibly differently sized) dxJoint
-}; // objects.
-
-
-// common limit and motor information for a single joint axis of movement
-struct dxJointLimitMotor {
- dReal vel,fmax; // powered joint: velocity, max force
- dReal lostop,histop; // joint limits, relative to initial position
- dReal fudge_factor; // when powering away from joint limits
- dReal normal_cfm; // cfm to use when not at a stop
- dReal stop_erp,stop_cfm; // erp and cfm for when at joint limit
- dReal bounce; // restitution factor
- // variables used between getInfo1() and getInfo2()
- int limit; // 0=free, 1=at lo limit, 2=at hi limit
- dReal limit_err; // if at limit, amount over limit
-
- void init (dxWorld *);
- void set (int num, dReal value);
- dReal get (int num);
- int testRotationalLimit (dReal angle);
- int addLimot (dxJoint *joint, dxJoint::Info2 *info, int row,
- dVector3 ax1, int rotational);
-};
-
-
-// ball and socket
-
-struct dxJointBall : public dxJoint {
- dVector3 anchor1; // anchor w.r.t first body
- dVector3 anchor2; // anchor w.r.t second body
-};
-extern struct dxJoint::Vtable __dball_vtable;
-
-
-// hinge
-
-struct dxJointHinge : public dxJoint {
- dVector3 anchor1; // anchor w.r.t first body
- dVector3 anchor2; // anchor w.r.t second body
- dVector3 axis1; // axis w.r.t first body
- dVector3 axis2; // axis w.r.t second body
- dQuaternion qrel; // initial relative rotation body1 -> body2
- dxJointLimitMotor limot; // limit and motor information
-};
-extern struct dxJoint::Vtable __dhinge_vtable;
-
-
-// universal
-
-struct dxJointUniversal : public dxJoint {
- dVector3 anchor1; // anchor w.r.t first body
- dVector3 anchor2; // anchor w.r.t second body
- dVector3 axis1; // axis w.r.t first body
- dVector3 axis2; // axis w.r.t second body
-};
-extern struct dxJoint::Vtable __duniversal_vtable;
-
-
-// slider. if body2 is 0 then qrel is the absolute rotation of body1 and
-// offset is the position of body1 center along axis1.
-
-struct dxJointSlider : public dxJoint {
- dVector3 axis1; // axis w.r.t first body
- dQuaternion qrel; // initial relative rotation body1 -> body2
- dVector3 offset; // point relative to body2 that should be
- // aligned with body1 center along axis1
- dxJointLimitMotor limot; // limit and motor information
-};
-extern struct dxJoint::Vtable __dslider_vtable;
-
-
-// contact
-
-struct dxJointContact : public dxJoint {
- int the_m; // number of rows computed by getInfo1
- dContact contact;
-};
-extern struct dxJoint::Vtable __dcontact_vtable;
-
-
-// hinge 2
-
-struct dxJointHinge2 : public dxJoint {
- dVector3 anchor1; // anchor w.r.t first body
- dVector3 anchor2; // anchor w.r.t second body
- dVector3 axis1; // axis 1 w.r.t first body
- dVector3 axis2; // axis 2 w.r.t second body
- dReal c0,s0; // cos,sin of desired angle between axis 1,2
- dVector3 v1,v2; // angle ref vectors embedded in first body
- dxJointLimitMotor limot1; // limit+motor info for axis 1
- dxJointLimitMotor limot2; // limit+motor info for axis 2
- dReal susp_erp,susp_cfm; // suspension parameters (erp,cfm)
-};
-extern struct dxJoint::Vtable __dhinge2_vtable;
-
-
-// angular motor
-
-struct dxJointAMotor : public dxJoint {
- int num; // number of axes (0..3)
- int mode; // a dAMotorXXX constant
- int rel[3]; // what the axes are relative to (global,b1,b2)
- dVector3 axis[3]; // three axes
- dxJointLimitMotor limot[3]; // limit+motor info for axes
- dReal angle[3]; // user-supplied angles for axes
- // these vectors are used for calculating euler angles
- dVector3 reference1; // original axis[2], relative to body 1
- dVector3 reference2; // original axis[0], relative to body 2
-};
-extern struct dxJoint::Vtable __damotor_vtable;
-
-
-// fixed
-
-struct dxJointFixed : public dxJoint {
- dVector3 offset; // relative offset between the bodies
-};
-extern struct dxJoint::Vtable __dfixed_vtable;
-
-
-// null joint, for testing only
-
-struct dxJointNull : public dxJoint {
-};
-extern struct dxJoint::Vtable __dnull_vtable;
-
-#endif
-
diff --git a/extern/ode/dist/ode/src/lcp.cpp b/extern/ode/dist/ode/src/lcp.cpp
deleted file mode 100644
index dba2d3b949b..00000000000
--- a/extern/ode/dist/ode/src/lcp.cpp
+++ /dev/null
@@ -1,1455 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/*
-
-
-THE ALGORITHM
--------------
-
-solve A*x = b+w, with x and w subject to certain LCP conditions.
-each x(i),w(i) must lie on one of the three line segments in the following
-diagram. each line segment corresponds to one index set :
-
- w(i)
- /|\ | :
- | | :
- | |i in N :
- w>0 | |state[i]=0 :
- | | :
- | | : i in C
- w=0 + +-----------------------+
- | : |
- | : |
- w<0 | : |i in N
- | : |state[i]=1
- | : |
- | : |
- +-------|-----------|-----------|----------> x(i)
- lo 0 hi
-
-the Dantzig algorithm proceeds as follows:
- for i=1:n
- * if (x(i),w(i)) is not on the line, push x(i) and w(i) positive or
- negative towards the line. as this is done, the other (x(j),w(j))
- for j<i are constrained to be on the line. if any (x,w) reaches the
- end of a line segment then it is switched between index sets.
- * i is added to the appropriate index set depending on what line segment
- it hits.
-
-we restrict lo(i) <= 0 and hi(i) >= 0. this makes the algorithm a bit
-simpler, because the starting point for x(i),w(i) is always on the dotted
-line x=0 and x will only ever increase in one direction, so it can only hit
-two out of the three line segments.
-
-
-NOTES
------
-
-this is an implementation of "lcp_dantzig2_ldlt.m" and "lcp_dantzig_lohi.m".
-the implementation is split into an LCP problem object (dLCP) and an LCP
-driver function. most optimization occurs in the dLCP object.
-
-a naive implementation of the algorithm requires either a lot of data motion
-or a lot of permutation-array lookup, because we are constantly re-ordering
-rows and columns. to avoid this and make a more optimized algorithm, a
-non-trivial data structure is used to represent the matrix A (this is
-implemented in the fast version of the dLCP object).
-
-during execution of this algorithm, some indexes in A are clamped (set C),
-some are non-clamped (set N), and some are "don't care" (where x=0).
-A,x,b,w (and other problem vectors) are permuted such that the clamped
-indexes are first, the unclamped indexes are next, and the don't-care
-indexes are last. this permutation is recorded in the array `p'.
-initially p = 0..n-1, and as the rows and columns of A,x,b,w are swapped,
-the corresponding elements of p are swapped.
-
-because the C and N elements are grouped together in the rows of A, we can do
-lots of work with a fast dot product function. if A,x,etc were not permuted
-and we only had a permutation array, then those dot products would be much
-slower as we would have a permutation array lookup in some inner loops.
-
-A is accessed through an array of row pointers, so that element (i,j) of the
-permuted matrix is A[i][j]. this makes row swapping fast. for column swapping
-we still have to actually move the data.
-
-during execution of this algorithm we maintain an L*D*L' factorization of
-the clamped submatrix of A (call it `AC') which is the top left nC*nC
-submatrix of A. there are two ways we could arrange the rows/columns in AC.
-
-(1) AC is always permuted such that L*D*L' = AC. this causes a problem
- when a row/column is removed from C, because then all the rows/columns of A
- between the deleted index and the end of C need to be rotated downward.
- this results in a lot of data motion and slows things down.
-(2) L*D*L' is actually a factorization of a *permutation* of AC (which is
- itself a permutation of the underlying A). this is what we do - the
- permutation is recorded in the vector C. call this permutation A[C,C].
- when a row/column is removed from C, all we have to do is swap two
- rows/columns and manipulate C.
-
-*/
-
-#include <ode/common.h>
-#include "lcp.h"
-#include <ode/matrix.h>
-#include <ode/misc.h>
-#include "mat.h" // for testing
-#include <ode/timer.h> // for testing
-
-//***************************************************************************
-// code generation parameters
-
-// LCP debugging (mosty for fast dLCP) - this slows things down a lot
-//#define DEBUG_LCP
-
-//#define dLCP_SLOW // use slow dLCP object
-#define dLCP_FAST // use fast dLCP object
-
-// option 1 : matrix row pointers (less data copying)
-#define ROWPTRS
-#define ATYPE dReal **
-#define AROW(i) (A[i])
-
-// option 2 : no matrix row pointers (slightly faster inner loops)
-//#define NOROWPTRS
-//#define ATYPE dReal *
-//#define AROW(i) (A+(i)*nskip)
-
-// misc defines
-#define ALLOCA dALLOCA16
-//#define dDot myDot
-#define NUB_OPTIMIZATIONS
-
-//***************************************************************************
-
-// an alternative inline dot product, for speed comparisons
-
-static inline dReal myDot (dReal *a, dReal *b, int n)
-{
- dReal sum=0;
- while (n > 0) {
- sum += (*a) * (*b);
- a++;
- b++;
- n--;
- }
- return sum;
-}
-
-
-// swap row/column i1 with i2 in the n*n matrix A. the leading dimension of
-// A is nskip. this only references and swaps the lower triangle.
-// if `do_fast_row_swaps' is nonzero and row pointers are being used, then
-// rows will be swapped by exchanging row pointers. otherwise the data will
-// be copied.
-
-static void swapRowsAndCols (ATYPE A, int n, int i1, int i2, int nskip,
- int do_fast_row_swaps)
-{
- int i;
- dIASSERT (A && n > 0 && i1 >= 0 && i2 >= 0 && i1 < n && i2 < n &&
- nskip >= n && i1 < i2);
-
-# ifdef ROWPTRS
- for (i=i1+1; i<i2; i++) A[i1][i] = A[i][i1];
- for (i=i1+1; i<i2; i++) A[i][i1] = A[i2][i];
- A[i1][i2] = A[i1][i1];
- A[i1][i1] = A[i2][i1];
- A[i2][i1] = A[i2][i2];
- // swap rows, by swapping row pointers
- if (do_fast_row_swaps) {
- dReal *tmpp;
- tmpp = A[i1];
- A[i1] = A[i2];
- A[i2] = tmpp;
- }
- else {
- dReal *tmprow = (dReal*) ALLOCA (n * sizeof(dReal));
- memcpy (tmprow,A[i1],n * sizeof(dReal));
- memcpy (A[i1],A[i2],n * sizeof(dReal));
- memcpy (A[i2],tmprow,n * sizeof(dReal));
- }
- // swap columns the hard way
- for (i=i2+1; i<n; i++) {
- dReal tmp = A[i][i1];
- A[i][i1] = A[i][i2];
- A[i][i2] = tmp;
- }
-# else
- dReal tmp,*tmprow = (dReal*) ALLOCA (n * sizeof(dReal));
- if (i1 > 0) {
- memcpy (tmprow,A+i1*nskip,i1*sizeof(dReal));
- memcpy (A+i1*nskip,A+i2*nskip,i1*sizeof(dReal));
- memcpy (A+i2*nskip,tmprow,i1*sizeof(dReal));
- }
- for (i=i1+1; i<i2; i++) {
- tmp = A[i2*nskip+i];
- A[i2*nskip+i] = A[i*nskip+i1];
- A[i*nskip+i1] = tmp;
- }
- tmp = A[i1*nskip+i1];
- A[i1*nskip+i1] = A[i2*nskip+i2];
- A[i2*nskip+i2] = tmp;
- for (i=i2+1; i<n; i++) {
- tmp = A[i*nskip+i1];
- A[i*nskip+i1] = A[i*nskip+i2];
- A[i*nskip+i2] = tmp;
- }
-# endif
-}
-
-
-// swap two indexes in the n*n LCP problem. i1 must be <= i2.
-
-static void swapProblem (ATYPE A, dReal *x, dReal *b, dReal *w, dReal *lo,
- dReal *hi, int *p, int *state, int *findex,
- int n, int i1, int i2, int nskip,
- int do_fast_row_swaps)
-{
- dReal tmp;
- int tmpi;
- dIASSERT (n>0 && i1 >=0 && i2 >= 0 && i1 < n && i2 < n && nskip >= n &&
- i1 <= i2);
- if (i1==i2) return;
- swapRowsAndCols (A,n,i1,i2,nskip,do_fast_row_swaps);
- tmp = x[i1];
- x[i1] = x[i2];
- x[i2] = tmp;
- tmp = b[i1];
- b[i1] = b[i2];
- b[i2] = tmp;
- tmp = w[i1];
- w[i1] = w[i2];
- w[i2] = tmp;
- tmp = lo[i1];
- lo[i1] = lo[i2];
- lo[i2] = tmp;
- tmp = hi[i1];
- hi[i1] = hi[i2];
- hi[i2] = tmp;
- tmpi = p[i1];
- p[i1] = p[i2];
- p[i2] = tmpi;
- tmpi = state[i1];
- state[i1] = state[i2];
- state[i2] = tmpi;
- if (findex) {
- tmpi = findex[i1];
- findex[i1] = findex[i2];
- findex[i2] = tmpi;
- }
-}
-
-
-// for debugging - check that L,d is the factorization of A[C,C].
-// A[C,C] has size nC*nC and leading dimension nskip.
-// L has size nC*nC and leading dimension nskip.
-// d has size nC.
-
-#ifdef DEBUG_LCP
-
-static void checkFactorization (ATYPE A, dReal *_L, dReal *_d,
- int nC, int *C, int nskip)
-{
- int i,j;
- if (nC==0) return;
-
- // get A1=A, copy the lower triangle to the upper triangle, get A2=A[C,C]
- dMatrix A1 (nC,nC);
- for (i=0; i<nC; i++) {
- for (j=0; j<=i; j++) A1(i,j) = A1(j,i) = AROW(i)[j];
- }
- dMatrix A2 = A1.select (nC,C,nC,C);
-
- // printf ("A1=\n"); A1.print(); printf ("\n");
- // printf ("A2=\n"); A2.print(); printf ("\n");
-
- // compute A3 = L*D*L'
- dMatrix L (nC,nC,_L,nskip,1);
- dMatrix D (nC,nC);
- for (i=0; i<nC; i++) D(i,i) = 1/_d[i];
- L.clearUpperTriangle();
- for (i=0; i<nC; i++) L(i,i) = 1;
- dMatrix A3 = L * D * L.transpose();
-
- // printf ("L=\n"); L.print(); printf ("\n");
- // printf ("D=\n"); D.print(); printf ("\n");
- // printf ("A3=\n"); A2.print(); printf ("\n");
-
- // compare A2 and A3
- dReal diff = A2.maxDifference (A3);
- if (diff > 1e-8)
- dDebug (0,"L*D*L' check, maximum difference = %.6e\n",diff);
-}
-
-#endif
-
-
-// for debugging
-
-#ifdef DEBUG_LCP
-
-static void checkPermutations (int i, int n, int nC, int nN, int *p, int *C)
-{
- int j,k;
- dIASSERT (nC>=0 && nN>=0 && (nC+nN)==i && i < n);
- for (k=0; k<i; k++) dIASSERT (p[k] >= 0 && p[k] < i);
- for (k=i; k<n; k++) dIASSERT (p[k] == k);
- for (j=0; j<nC; j++) {
- int C_is_bad = 1;
- for (k=0; k<nC; k++) if (C[k]==j) C_is_bad = 0;
- dIASSERT (C_is_bad==0);
- }
-}
-
-#endif
-
-//***************************************************************************
-// dLCP manipulator object. this represents an n*n LCP problem.
-//
-// two index sets C and N are kept. each set holds a subset of
-// the variable indexes 0..n-1. an index can only be in one set.
-// initially both sets are empty.
-//
-// the index set C is special: solutions to A(C,C)\A(C,i) can be generated.
-
-#ifdef dLCP_SLOW
-
-// simple but slow implementation of dLCP, for testing the LCP drivers.
-
-#include "array.h"
-
-struct dLCP {
- int n,nub,nskip;
- dReal *Adata,*x,*b,*w,*lo,*hi; // LCP problem data
- ATYPE A; // A rows
- dArray<int> C,N; // index sets
- int last_i_for_solve1; // last i value given to solve1
-
- dLCP (int _n, int _nub, dReal *_Adata, dReal *_x, dReal *_b, dReal *_w,
- dReal *_lo, dReal *_hi, dReal *_L, dReal *_d,
- dReal *_Dell, dReal *_ell, dReal *_tmp,
- int *_state, int *_findex, int *_p, int *_C, dReal **Arows);
- // the constructor is given an initial problem description (A,x,b,w) and
- // space for other working data (which the caller may allocate on the stack).
- // some of this data is specific to the fast dLCP implementation.
- // the matrices A and L have size n*n, vectors have size n*1.
- // A represents a symmetric matrix but only the lower triangle is valid.
- // `nub' is the number of unbounded indexes at the start. all the indexes
- // 0..nub-1 will be put into C.
-
- ~dLCP();
-
- int getNub() { return nub; }
- // return the value of `nub'. the constructor may want to change it,
- // so the caller should find out its new value.
-
- // transfer functions: transfer index i to the given set (C or N). indexes
- // less than `nub' can never be given. A,x,b,w,etc may be permuted by these
- // functions, the caller must be robust to this.
-
- void transfer_i_to_C (int i);
- // this assumes C and N span 1:i-1. this also assumes that solve1() has
- // been recently called for the same i without any other transfer
- // functions in between (thereby allowing some data reuse for the fast
- // implementation).
- void transfer_i_to_N (int i);
- // this assumes C and N span 1:i-1.
- void transfer_i_from_N_to_C (int i);
- void transfer_i_from_C_to_N (int i);
-
- int numC();
- int numN();
- // return the number of indexes in set C/N
-
- int indexC (int i);
- int indexN (int i);
- // return index i in set C/N.
-
- // accessor and arithmetic functions. Aij translates as A(i,j), etc.
- // make sure that only the lower triangle of A is ever referenced.
-
- dReal Aii (int i);
- dReal AiC_times_qC (int i, dReal *q);
- dReal AiN_times_qN (int i, dReal *q); // for all Nj
- void pN_equals_ANC_times_qC (dReal *p, dReal *q); // for all Nj
- void pN_plusequals_ANi (dReal *p, int i, int sign=1);
- // for all Nj. sign = +1,-1. assumes i > maximum index in N.
- void pC_plusequals_s_times_qC (dReal *p, dReal s, dReal *q);
- void pN_plusequals_s_times_qN (dReal *p, dReal s, dReal *q); // for all Nj
- void solve1 (dReal *a, int i, int dir=1, int only_transfer=0);
- // get a(C) = - dir * A(C,C) \ A(C,i). dir must be +/- 1.
- // the fast version of this function computes some data that is needed by
- // transfer_i_to_C(). if only_transfer is nonzero then this function
- // *only* computes that data, it does not set a(C).
-
- void unpermute();
- // call this at the end of the LCP function. if the x/w values have been
- // permuted then this will unscramble them.
-};
-
-
-dLCP::dLCP (int _n, int _nub, dReal *_Adata, dReal *_x, dReal *_b, dReal *_w,
- dReal *_lo, dReal *_hi, dReal *_L, dReal *_d,
- dReal *_Dell, dReal *_ell, dReal *_tmp,
- int *_state, int *_findex, int *_p, int *_C, dReal **Arows)
-{
- dUASSERT (_findex==0,"slow dLCP object does not support findex array");
-
- n = _n;
- nub = _nub;
- Adata = _Adata;
- A = 0;
- x = _x;
- b = _b;
- w = _w;
- lo = _lo;
- hi = _hi;
- nskip = dPAD(n);
- dSetZero (x,n);
- last_i_for_solve1 = -1;
-
- int i,j;
- C.setSize (n);
- N.setSize (n);
- for (int i=0; i<n; i++) {
- C[i] = 0;
- N[i] = 0;
- }
-
-# ifdef ROWPTRS
- // make matrix row pointers
- A = Arows;
- for (i=0; i<n; i++) A[i] = Adata + i*nskip;
-# else
- A = Adata;
-# endif
-
- // lets make A symmetric
- for (i=0; i<n; i++) {
- for (j=i+1; j<n; j++) AROW(i)[j] = AROW(j)[i];
- }
-
- // if nub>0, put all indexes 0..nub-1 into C and solve for x
- if (nub > 0) {
- for (i=0; i<nub; i++) memcpy (_L+i*nskip,AROW(i),(i+1)*sizeof(dReal));
- dFactorLDLT (_L,_d,nub,nskip);
- memcpy (x,b,nub*sizeof(dReal));
- dSolveLDLT (_L,_d,x,nub,nskip);
- dSetZero (_w,nub);
- for (i=0; i<nub; i++) C[i] = 1;
- }
-}
-
-
-dLCP::~dLCP()
-{
-}
-
-
-void dLCP::transfer_i_to_C (int i)
-{
- if (i < nub) dDebug (0,"bad i");
- if (C[i]) dDebug (0,"i already in C");
- if (N[i]) dDebug (0,"i already in N");
- for (int k=0; k<i; k++) {
- if (!(C[k] ^ N[k])) dDebug (0,"assumptions for C and N violated");
- }
- for (int k=i; k<n; k++)
- if (C[k] || N[k]) dDebug (0,"assumptions for C and N violated");
- if (i != last_i_for_solve1) dDebug (0,"assumptions for i violated");
- last_i_for_solve1 = -1;
- C[i] = 1;
-}
-
-
-void dLCP::transfer_i_to_N (int i)
-{
- if (i < nub) dDebug (0,"bad i");
- if (C[i]) dDebug (0,"i already in C");
- if (N[i]) dDebug (0,"i already in N");
- for (int k=0; k<i; k++)
- if (!C[k] && !N[k]) dDebug (0,"assumptions for C and N violated");
- for (int k=i; k<n; k++)
- if (C[k] || N[k]) dDebug (0,"assumptions for C and N violated");
- last_i_for_solve1 = -1;
- N[i] = 1;
-}
-
-
-void dLCP::transfer_i_from_N_to_C (int i)
-{
- if (i < nub) dDebug (0,"bad i");
- if (C[i]) dDebug (0,"i already in C");
- if (!N[i]) dDebug (0,"i not in N");
- last_i_for_solve1 = -1;
- N[i] = 0;
- C[i] = 1;
-}
-
-
-void dLCP::transfer_i_from_C_to_N (int i)
-{
- if (i < nub) dDebug (0,"bad i");
- if (N[i]) dDebug (0,"i already in N");
- if (!C[i]) dDebug (0,"i not in C");
- last_i_for_solve1 = -1;
- C[i] = 0;
- N[i] = 1;
-}
-
-
-int dLCP::numC()
-{
- int i,count=0;
- for (i=0; i<n; i++) if (C[i]) count++;
- return count;
-}
-
-
-int dLCP::numN()
-{
- int i,count=0;
- for (i=0; i<n; i++) if (N[i]) count++;
- return count;
-}
-
-
-int dLCP::indexC (int i)
-{
- int k,count=0;
- for (k=0; k<n; k++) {
- if (C[k]) {
- if (count==i) return k;
- count++;
- }
- }
- dDebug (0,"bad index C (%d)",i);
- return 0;
-}
-
-
-int dLCP::indexN (int i)
-{
- int k,count=0;
- for (k=0; k<n; k++) {
- if (N[k]) {
- if (count==i) return k;
- count++;
- }
- }
- dDebug (0,"bad index into N");
- return 0;
-}
-
-
-dReal dLCP::Aii (int i)
-{
- return AROW(i)[i];
-}
-
-
-dReal dLCP::AiC_times_qC (int i, dReal *q)
-{
- dReal sum = 0;
- for (int k=0; k<n; k++) if (C[k]) sum += AROW(i)[k] * q[k];
- return sum;
-}
-
-
-dReal dLCP::AiN_times_qN (int i, dReal *q)
-{
- dReal sum = 0;
- for (int k=0; k<n; k++) if (N[k]) sum += AROW(i)[k] * q[k];
- return sum;
-}
-
-
-void dLCP::pN_equals_ANC_times_qC (dReal *p, dReal *q)
-{
- dReal sum;
- for (int ii=0; ii<n; ii++) if (N[ii]) {
- sum = 0;
- for (int jj=0; jj<n; jj++) if (C[jj]) sum += AROW(ii)[jj] * q[jj];
- p[ii] = sum;
- }
-}
-
-
-void dLCP::pN_plusequals_ANi (dReal *p, int i, int sign)
-{
- int k;
- for (k=0; k<n; k++) if (N[k] && k >= i) dDebug (0,"N assumption violated");
- if (sign > 0) {
- for (k=0; k<n; k++) if (N[k]) p[k] += AROW(i)[k];
- }
- else {
- for (k=0; k<n; k++) if (N[k]) p[k] -= AROW(i)[k];
- }
-}
-
-
-void dLCP::pC_plusequals_s_times_qC (dReal *p, dReal s, dReal *q)
-{
- for (int k=0; k<n; k++) if (C[k]) p[k] += s*q[k];
-}
-
-
-void dLCP::pN_plusequals_s_times_qN (dReal *p, dReal s, dReal *q)
-{
- for (int k=0; k<n; k++) if (N[k]) p[k] += s*q[k];
-}
-
-
-void dLCP::solve1 (dReal *a, int i, int dir, int only_transfer)
-{
- dReal *AA = (dReal*) ALLOCA (n*nskip*sizeof(dReal));
- dReal *dd = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *bb = (dReal*) ALLOCA (n*sizeof(dReal));
- int ii,jj,AAi,AAj;
-
- last_i_for_solve1 = i;
- AAi = 0;
- for (ii=0; ii<n; ii++) if (C[ii]) {
- AAj = 0;
- for (jj=0; jj<n; jj++) if (C[jj]) {
- AA[AAi*nskip+AAj] = AROW(ii)[jj];
- AAj++;
- }
- bb[AAi] = AROW(i)[ii];
- AAi++;
- }
- if (AAi==0) return;
-
- dFactorLDLT (AA,dd,AAi,nskip);
- dSolveLDLT (AA,dd,bb,AAi,nskip);
-
- AAi=0;
- if (dir > 0) {
- for (ii=0; ii<n; ii++) if (C[ii]) a[ii] = -bb[AAi++];
- }
- else {
- for (ii=0; ii<n; ii++) if (C[ii]) a[ii] = bb[AAi++];
- }
-}
-
-
-void dLCP::unpermute()
-{
-}
-
-#endif // dLCP_SLOW
-
-//***************************************************************************
-// fast implementation of dLCP. see the above definition of dLCP for
-// interface comments.
-//
-// `p' records the permutation of A,x,b,w,etc. p is initially 1:n and is
-// permuted as the other vectors/matrices are permuted.
-//
-// A,x,b,w,lo,hi,state,findex,p,c are permuted such that sets C,N have
-// contiguous indexes. the don't-care indexes follow N.
-//
-// an L*D*L' factorization is maintained of A(C,C), and whenever indexes are
-// added or removed from the set C the factorization is updated.
-// thus L*D*L'=A[C,C], i.e. a permuted top left nC*nC submatrix of A.
-// the leading dimension of the matrix L is always `nskip'.
-//
-// at the start there may be other indexes that are unbounded but are not
-// included in `nub'. dLCP will permute the matrix so that absolutely all
-// unbounded vectors are at the start. thus there may be some initial
-// permutation.
-//
-// the algorithms here assume certain patterns, particularly with respect to
-// index transfer.
-
-#ifdef dLCP_FAST
-
-struct dLCP {
- int n,nskip,nub;
- ATYPE A; // A rows
- dReal *Adata,*x,*b,*w,*lo,*hi; // permuted LCP problem data
- dReal *L,*d; // L*D*L' factorization of set C
- dReal *Dell,*ell,*tmp;
- int *state,*findex,*p,*C;
- int nC,nN; // size of each index set
-
- dLCP (int _n, int _nub, dReal *_Adata, dReal *_x, dReal *_b, dReal *_w,
- dReal *_lo, dReal *_hi, dReal *_L, dReal *_d,
- dReal *_Dell, dReal *_ell, dReal *_tmp,
- int *_state, int *_findex, int *_p, int *_C, dReal **Arows);
- int getNub() { return nub; }
- void transfer_i_to_C (int i);
- void transfer_i_to_N (int i)
- { nN++; } // because we can assume C and N span 1:i-1
- void transfer_i_from_N_to_C (int i);
- void transfer_i_from_C_to_N (int i);
- int numC() { return nC; }
- int numN() { return nN; }
- int indexC (int i) { return i; }
- int indexN (int i) { return i+nC; }
- dReal Aii (int i) { return AROW(i)[i]; }
- dReal AiC_times_qC (int i, dReal *q) { return dDot (AROW(i),q,nC); }
- dReal AiN_times_qN (int i, dReal *q) { return dDot (AROW(i)+nC,q+nC,nN); }
- void pN_equals_ANC_times_qC (dReal *p, dReal *q);
- void pN_plusequals_ANi (dReal *p, int i, int sign=1);
- void pC_plusequals_s_times_qC (dReal *p, dReal s, dReal *q)
- { for (int i=0; i<nC; i++) p[i] += s*q[i]; }
- void pN_plusequals_s_times_qN (dReal *p, dReal s, dReal *q)
- { for (int i=0; i<nN; i++) p[i+nC] += s*q[i+nC]; }
- void solve1 (dReal *a, int i, int dir=1, int only_transfer=0);
- void unpermute();
-};
-
-
-dLCP::dLCP (int _n, int _nub, dReal *_Adata, dReal *_x, dReal *_b, dReal *_w,
- dReal *_lo, dReal *_hi, dReal *_L, dReal *_d,
- dReal *_Dell, dReal *_ell, dReal *_tmp,
- int *_state, int *_findex, int *_p, int *_C, dReal **Arows)
-{
- n = _n;
- nub = _nub;
- Adata = _Adata;
- A = 0;
- x = _x;
- b = _b;
- w = _w;
- lo = _lo;
- hi = _hi;
- L = _L;
- d = _d;
- Dell = _Dell;
- ell = _ell;
- tmp = _tmp;
- state = _state;
- findex = _findex;
- p = _p;
- C = _C;
- nskip = dPAD(n);
- dSetZero (x,n);
-
- int k;
-
-# ifdef ROWPTRS
- // make matrix row pointers
- A = Arows;
- for (k=0; k<n; k++) A[k] = Adata + k*nskip;
-# else
- A = Adata;
-# endif
-
- nC = 0;
- nN = 0;
- for (k=0; k<n; k++) p[k]=k; // initially unpermuted
-
- /*
- // for testing, we can do some random swaps in the area i > nub
- if (nub < n) {
- for (k=0; k<100; k++) {
- int i1,i2;
- do {
- i1 = dRandInt(n-nub)+nub;
- i2 = dRandInt(n-nub)+nub;
- }
- while (i1 > i2);
- //printf ("--> %d %d\n",i1,i2);
- swapProblem (A,x,b,w,lo,hi,p,state,findex,n,i1,i2,nskip,0);
- }
- }
- */
-
- // permute the problem so that *all* the unbounded variables are at the
- // start, i.e. look for unbounded variables not included in `nub'. we can
- // potentially push up `nub' this way and get a bigger initial factorization.
- // note that when we swap rows/cols here we must not just swap row pointers,
- // as the initial factorization relies on the data being all in one chunk.
- for (k=nub; k<n; k++) {
- if (lo[k]==-dInfinity && hi[k]==dInfinity) {
- swapProblem (A,x,b,w,lo,hi,p,state,findex,n,nub,k,nskip,0);
- nub++;
- }
- }
-
- // if there are unbounded variables at the start, factorize A up to that
- // point and solve for x. this puts all indexes 0..nub-1 into C.
- if (nub > 0) {
- for (k=0; k<nub; k++) memcpy (L+k*nskip,AROW(k),(k+1)*sizeof(dReal));
- dFactorLDLT (L,d,nub,nskip);
- memcpy (x,b,nub*sizeof(dReal));
- dSolveLDLT (L,d,x,nub,nskip);
- dSetZero (w,nub);
- for (k=0; k<nub; k++) C[k] = k;
- nC = nub;
- }
-
- // permute the indexes > nub such that all findex variables are at the end
- if (findex) {
- int num_at_end = 0;
- for (k=n-1; k >= nub; k--) {
- if (findex[k] >= 0) {
- swapProblem (A,x,b,w,lo,hi,p,state,findex,n,k,n-1-num_at_end,nskip,1);
- num_at_end++;
- }
- }
- }
-
- // print info about indexes
- /*
- for (k=0; k<n; k++) {
- if (k<nub) printf ("C");
- else if (lo[k]==-dInfinity && hi[k]==dInfinity) printf ("c");
- else printf (".");
- }
- printf ("\n");
- */
-}
-
-
-void dLCP::transfer_i_to_C (int i)
-{
- int j;
- if (nC > 0) {
- // ell,Dell were computed by solve1(). note, ell = D \ L1solve (L,A(i,C))
- for (j=0; j<nC; j++) L[nC*nskip+j] = ell[j];
- d[nC] = dRecip (AROW(i)[i] - dDot(ell,Dell,nC));
- }
- else {
- d[0] = dRecip (AROW(i)[i]);
- }
- swapProblem (A,x,b,w,lo,hi,p,state,findex,n,nC,i,nskip,1);
- C[nC] = nC;
- nC++;
-
-# ifdef DEBUG_LCP
- checkFactorization (A,L,d,nC,C,nskip);
- if (i < (n-1)) checkPermutations (i+1,n,nC,nN,p,C);
-# endif
-}
-
-
-void dLCP::transfer_i_from_N_to_C (int i)
-{
- int j;
- if (nC > 0) {
- dReal *aptr = AROW(i);
-# ifdef NUB_OPTIMIZATIONS
- // if nub>0, initial part of aptr unpermuted
- for (j=0; j<nub; j++) Dell[j] = aptr[j];
- for (j=nub; j<nC; j++) Dell[j] = aptr[C[j]];
-# else
- for (j=0; j<nC; j++) Dell[j] = aptr[C[j]];
-# endif
- dSolveL1 (L,Dell,nC,nskip);
- for (j=0; j<nC; j++) ell[j] = Dell[j] * d[j];
- for (j=0; j<nC; j++) L[nC*nskip+j] = ell[j];
- d[nC] = dRecip (AROW(i)[i] - dDot(ell,Dell,nC));
- }
- else {
- d[0] = dRecip (AROW(i)[i]);
- }
- swapProblem (A,x,b,w,lo,hi,p,state,findex,n,nC,i,nskip,1);
- C[nC] = nC;
- nN--;
- nC++;
-
- // @@@ TO DO LATER
- // if we just finish here then we'll go back and re-solve for
- // delta_x. but actually we can be more efficient and incrementally
- // update delta_x here. but if we do this, we wont have ell and Dell
- // to use in updating the factorization later.
-
-# ifdef DEBUG_LCP
- checkFactorization (A,L,d,nC,C,nskip);
-# endif
-}
-
-
-void dLCP::transfer_i_from_C_to_N (int i)
-{
- // remove a row/column from the factorization, and adjust the
- // indexes (black magic!)
- int j,k;
- for (j=0; j<nC; j++) if (C[j]==i) {
- dLDLTRemove (A,C,L,d,n,nC,j,nskip);
- for (k=0; k<nC; k++) if (C[k]==nC-1) {
- C[k] = C[j];
- if (j < (nC-1)) memmove (C+j,C+j+1,(nC-j-1)*sizeof(int));
- break;
- }
- dIASSERT (k < nC);
- break;
- }
- dIASSERT (j < nC);
- swapProblem (A,x,b,w,lo,hi,p,state,findex,n,i,nC-1,nskip,1);
- nC--;
- nN++;
-
-# ifdef DEBUG_LCP
- checkFactorization (A,L,d,nC,C,nskip);
-# endif
-}
-
-
-void dLCP::pN_equals_ANC_times_qC (dReal *p, dReal *q)
-{
- // we could try to make this matrix-vector multiplication faster using
- // outer product matrix tricks, e.g. with the dMultidotX() functions.
- // but i tried it and it actually made things slower on random 100x100
- // problems because of the overhead involved. so we'll stick with the
- // simple method for now.
- for (int i=0; i<nN; i++) p[i+nC] = dDot (AROW(i+nC),q,nC);
-}
-
-
-void dLCP::pN_plusequals_ANi (dReal *p, int i, int sign)
-{
- dReal *aptr = AROW(i)+nC;
- if (sign > 0) {
- for (int i=0; i<nN; i++) p[i+nC] += aptr[i];
- }
- else {
- for (int i=0; i<nN; i++) p[i+nC] -= aptr[i];
- }
-}
-
-
-void dLCP::solve1 (dReal *a, int i, int dir, int only_transfer)
-{
- // the `Dell' and `ell' that are computed here are saved. if index i is
- // later added to the factorization then they can be reused.
- //
- // @@@ question: do we need to solve for entire delta_x??? yes, but
- // only if an x goes below 0 during the step.
-
- int j;
- if (nC > 0) {
- dReal *aptr = AROW(i);
-# ifdef NUB_OPTIMIZATIONS
- // if nub>0, initial part of aptr[] is guaranteed unpermuted
- for (j=0; j<nub; j++) Dell[j] = aptr[j];
- for (j=nub; j<nC; j++) Dell[j] = aptr[C[j]];
-# else
- for (j=0; j<nC; j++) Dell[j] = aptr[C[j]];
-# endif
- dSolveL1 (L,Dell,nC,nskip);
- for (j=0; j<nC; j++) ell[j] = Dell[j] * d[j];
-
- if (!only_transfer) {
- for (j=0; j<nC; j++) tmp[j] = ell[j];
- dSolveL1T (L,tmp,nC,nskip);
- if (dir > 0) {
- for (j=0; j<nC; j++) a[C[j]] = -tmp[j];
- }
- else {
- for (j=0; j<nC; j++) a[C[j]] = tmp[j];
- }
- }
- }
-}
-
-
-void dLCP::unpermute()
-{
- // now we have to un-permute x and w
- int j;
- dReal *tmp = (dReal*) ALLOCA (n*sizeof(dReal));
- memcpy (tmp,x,n*sizeof(dReal));
- for (j=0; j<n; j++) x[p[j]] = tmp[j];
- memcpy (tmp,w,n*sizeof(dReal));
- for (j=0; j<n; j++) w[p[j]] = tmp[j];
-}
-
-#endif // dLCP_FAST
-
-//***************************************************************************
-// an unoptimized Dantzig LCP driver routine for the basic LCP problem.
-// must have lo=0, hi=dInfinity, and nub=0.
-
-void dSolveLCPBasic (int n, dReal *A, dReal *x, dReal *b,
- dReal *w, int nub, dReal *lo, dReal *hi)
-{
- dAASSERT (n>0 && A && x && b && w && nub == 0);
-
- int i,k;
- int nskip = dPAD(n);
- dReal *L = (dReal*) ALLOCA (n*nskip*sizeof(dReal));
- dReal *d = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *delta_x = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *delta_w = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *Dell = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *ell = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *tmp = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal **Arows = (dReal**) ALLOCA (n*sizeof(dReal*));
- int *p = (int*) ALLOCA (n*sizeof(int));
- int *C = (int*) ALLOCA (n*sizeof(int));
- int *dummy = (int*) ALLOCA (n*sizeof(int));
-
- dLCP lcp (n,0,A,x,b,w,tmp,tmp,L,d,Dell,ell,tmp,dummy,dummy,p,C,Arows);
- nub = lcp.getNub();
-
- for (i=0; i<n; i++) {
- w[i] = lcp.AiC_times_qC (i,x) - b[i];
- if (w[i] >= 0) {
- lcp.transfer_i_to_N (i);
- }
- else {
- for (;;) {
- // compute: delta_x(C) = -A(C,C)\A(C,i)
- dSetZero (delta_x,n);
- lcp.solve1 (delta_x,i);
- delta_x[i] = 1;
-
- // compute: delta_w = A*delta_x
- dSetZero (delta_w,n);
- lcp.pN_equals_ANC_times_qC (delta_w,delta_x);
- lcp.pN_plusequals_ANi (delta_w,i);
- delta_w[i] = lcp.AiC_times_qC (i,delta_x) + lcp.Aii(i);
-
- // find index to switch
- int si = i; // si = switch index
- int si_in_N = 0; // set to 1 if si in N
- dReal s = -w[i]/delta_w[i];
-
- if (s <= 0) {
- dMessage (d_ERR_LCP, "LCP internal error, s <= 0 (s=%.4e)",s);
- if (i < (n-1)) {
- dSetZero (x+i,n-i);
- dSetZero (w+i,n-i);
- }
- goto done;
- }
-
- for (k=0; k < lcp.numN(); k++) {
- if (delta_w[lcp.indexN(k)] < 0) {
- dReal s2 = -w[lcp.indexN(k)] / delta_w[lcp.indexN(k)];
- if (s2 < s) {
- s = s2;
- si = lcp.indexN(k);
- si_in_N = 1;
- }
- }
- }
- for (k=0; k < lcp.numC(); k++) {
- if (delta_x[lcp.indexC(k)] < 0) {
- dReal s2 = -x[lcp.indexC(k)] / delta_x[lcp.indexC(k)];
- if (s2 < s) {
- s = s2;
- si = lcp.indexC(k);
- si_in_N = 0;
- }
- }
- }
-
- // apply x = x + s * delta_x
- lcp.pC_plusequals_s_times_qC (x,s,delta_x);
- x[i] += s;
- lcp.pN_plusequals_s_times_qN (w,s,delta_w);
- w[i] += s * delta_w[i];
-
- // switch indexes between sets if necessary
- if (si==i) {
- w[i] = 0;
- lcp.transfer_i_to_C (i);
- break;
- }
- if (si_in_N) {
- w[si] = 0;
- lcp.transfer_i_from_N_to_C (si);
- }
- else {
- x[si] = 0;
- lcp.transfer_i_from_C_to_N (si);
- }
- }
- }
- }
-
- done:
- lcp.unpermute();
-}
-
-//***************************************************************************
-// an optimized Dantzig LCP driver routine for the lo-hi LCP problem.
-
-void dSolveLCP (int n, dReal *A, dReal *x, dReal *b,
- dReal *w, int nub, dReal *lo, dReal *hi, int *findex)
-{
- dAASSERT (n>0 && A && x && b && w && lo && hi && nub >= 0 && nub <= n);
- int i,k,hit_first_friction_index = 0;
- int nskip = dPAD(n);
-
- // if all the variables are unbounded then we can just factor, solve,
- // and return
- if (nub >= n) {
- dFactorLDLT (A,w,n,nskip); // use w for d
- dSolveLDLT (A,w,b,n,nskip);
- memcpy (x,b,n*sizeof(dReal));
- dSetZero (w,n);
- return;
- }
-
-# ifndef dNODEBUG
- // check restrictions on lo and hi
- for (k=0; k<n; k++) dIASSERT (lo[k] <= 0 && hi[k] >= 0);
-# endif
-
- dReal *L = (dReal*) ALLOCA (n*nskip*sizeof(dReal));
- dReal *d = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *delta_x = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *delta_w = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *Dell = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *ell = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal **Arows = (dReal**) ALLOCA (n*sizeof(dReal*));
- int *p = (int*) ALLOCA (n*sizeof(int));
- int *C = (int*) ALLOCA (n*sizeof(int));
- int dir;
- dReal dirf;
-
- // for i in N, state[i] is 0 if x(i)==lo(i) or 1 if x(i)==hi(i)
- int *state = (int*) ALLOCA (n*sizeof(int));
-
- // create LCP object. note that tmp is set to delta_w to save space, this
- // optimization relies on knowledge of how tmp is used, so be careful!
- dLCP lcp (n,nub,A,x,b,w,lo,hi,L,d,Dell,ell,delta_w,state,findex,p,C,Arows);
- nub = lcp.getNub();
-
- // loop over all indexes nub..n-1. for index i, if x(i),w(i) satisfy the
- // LCP conditions then i is added to the appropriate index set. otherwise
- // x(i),w(i) is driven either +ve or -ve to force it to the valid region.
- // as we drive x(i), x(C) is also adjusted to keep w(C) at zero.
- // while driving x(i) we maintain the LCP conditions on the other variables
- // 0..i-1. we do this by watching out for other x(i),w(i) values going
- // outside the valid region, and then switching them between index sets
- // when that happens.
-
- for (i=nub; i<n; i++) {
- // the index i is the driving index and indexes i+1..n-1 are "dont care",
- // i.e. when we make changes to the system those x's will be zero and we
- // don't care what happens to those w's. in other words, we only consider
- // an (i+1)*(i+1) sub-problem of A*x=b+w.
-
- // if we've hit the first friction index, we have to compute the lo and
- // hi values based on the values of x already computed. we have been
- // permuting the indexes, so the values stored in the findex vector are
- // no longer valid. thus we have to temporarily unpermute the x vector.
- if (hit_first_friction_index == 0 && findex && findex[i] >= 0) {
- // un-permute x into delta_w, which is not being used at the moment
- for (k=0; k<n; k++) delta_w[p[k]] = x[k];
- // set lo and hi values
- for (k=i; k<n; k++) {
- hi[k] = dFabs (hi[k] * delta_w[findex[k]]);
- lo[k] = -hi[k];
- }
- hit_first_friction_index = 1;
- }
-
- // thus far we have not even been computing the w values for indexes
- // greater than i, so compute w[i] now.
- w[i] = lcp.AiC_times_qC (i,x) + lcp.AiN_times_qN (i,x) - b[i];
-
- // if lo=hi=0 (which can happen for tangential friction when normals are
- // 0) then the index will be assigned to set N with some state. however,
- // set C's line has zero size, so the index will always remain in set N.
- // with the "normal" switching logic, if w changed sign then the index
- // would have to switch to set C and then back to set N with an inverted
- // state. this is pointless, and also computationally expensive. to
- // prevent this from happening, we use the rule that indexes with lo=hi=0
- // will never be checked for set changes. this means that the state for
- // these indexes may be incorrect, but that doesn't matter.
-
- // see if x(i),w(i) is in a valid region
- if (lo[i]==0 && w[i] >= 0) {
- lcp.transfer_i_to_N (i);
- state[i] = 0;
- }
- else if (hi[i]==0 && w[i] <= 0) {
- lcp.transfer_i_to_N (i);
- state[i] = 1;
- }
- else if (w[i]==0) {
- // this is a degenerate case. by the time we get to this test we know
- // that lo != 0, which means that lo < 0 as lo is not allowed to be +ve,
- // and similarly that hi > 0. this means that the line segment
- // corresponding to set C is at least finite in extent, and we are on it.
- // NOTE: we must call lcp.solve1() before lcp.transfer_i_to_C()
- lcp.solve1 (delta_x,i,0,1);
- lcp.transfer_i_to_C (i);
- }
- else {
- // we must push x(i) and w(i)
- for (;;) {
- // find direction to push on x(i)
- if (w[i] <= 0) {
- dir = 1;
- dirf = REAL(1.0);
- }
- else {
- dir = -1;
- dirf = REAL(-1.0);
- }
-
- // compute: delta_x(C) = -dir*A(C,C)\A(C,i)
- lcp.solve1 (delta_x,i,dir);
- // note that delta_x[i] = dirf, but we wont bother to set it
-
- // compute: delta_w = A*delta_x ... note we only care about
- // delta_w(N) and delta_w(i), the rest is ignored
- lcp.pN_equals_ANC_times_qC (delta_w,delta_x);
- lcp.pN_plusequals_ANi (delta_w,i,dir);
- delta_w[i] = lcp.AiC_times_qC (i,delta_x) + lcp.Aii(i)*dirf;
-
- // find largest step we can take (size=s), either to drive x(i),w(i)
- // to the valid LCP region or to drive an already-valid variable
- // outside the valid region.
-
- int cmd = 1; // index switching command
- int si = 0; // si = index to switch if cmd>3
- dReal s = -w[i]/delta_w[i];
- if (dir > 0) {
- if (hi[i] < dInfinity) {
- dReal s2 = (hi[i]-x[i])/dirf; // step to x(i)=hi(i)
- if (s2 < s) {
- s = s2;
- cmd = 3;
- }
- }
- }
- else {
- if (lo[i] > -dInfinity) {
- dReal s2 = (lo[i]-x[i])/dirf; // step to x(i)=lo(i)
- if (s2 < s) {
- s = s2;
- cmd = 2;
- }
- }
- }
-
- for (k=0; k < lcp.numN(); k++) {
- if ((state[lcp.indexN(k)]==0 && delta_w[lcp.indexN(k)] < 0) ||
- (state[lcp.indexN(k)]!=0 && delta_w[lcp.indexN(k)] > 0)) {
- // don't bother checking if lo=hi=0
- if (lo[lcp.indexN(k)] == 0 && hi[lcp.indexN(k)] == 0) continue;
- dReal s2 = -w[lcp.indexN(k)] / delta_w[lcp.indexN(k)];
- if (s2 < s) {
- s = s2;
- cmd = 4;
- si = lcp.indexN(k);
- }
- }
- }
-
- for (k=nub; k < lcp.numC(); k++) {
- if (delta_x[lcp.indexC(k)] < 0 && lo[lcp.indexC(k)] > -dInfinity) {
- dReal s2 = (lo[lcp.indexC(k)]-x[lcp.indexC(k)]) /
- delta_x[lcp.indexC(k)];
- if (s2 < s) {
- s = s2;
- cmd = 5;
- si = lcp.indexC(k);
- }
- }
- if (delta_x[lcp.indexC(k)] > 0 && hi[lcp.indexC(k)] < dInfinity) {
- dReal s2 = (hi[lcp.indexC(k)]-x[lcp.indexC(k)]) /
- delta_x[lcp.indexC(k)];
- if (s2 < s) {
- s = s2;
- cmd = 6;
- si = lcp.indexC(k);
- }
- }
- }
-
- //static char* cmdstring[8] = {0,"->C","->NL","->NH","N->C",
- // "C->NL","C->NH"};
- //printf ("cmd=%d (%s), si=%d\n",cmd,cmdstring[cmd],(cmd>3) ? si : i);
-
- // if s <= 0 then we've got a problem. if we just keep going then
- // we're going to get stuck in an infinite loop. instead, just cross
- // our fingers and exit with the current solution.
- if (s <= 0) {
- dMessage (d_ERR_LCP, "LCP internal error, s <= 0 (s=%.4e)",s);
- if (i < (n-1)) {
- dSetZero (x+i,n-i);
- dSetZero (w+i,n-i);
- }
- goto done;
- }
-
- // apply x = x + s * delta_x
- lcp.pC_plusequals_s_times_qC (x,s,delta_x);
- x[i] += s * dirf;
-
- // apply w = w + s * delta_w
- lcp.pN_plusequals_s_times_qN (w,s,delta_w);
- w[i] += s * delta_w[i];
-
- // switch indexes between sets if necessary
- switch (cmd) {
- case 1: // done
- w[i] = 0;
- lcp.transfer_i_to_C (i);
- break;
- case 2: // done
- x[i] = lo[i];
- state[i] = 0;
- lcp.transfer_i_to_N (i);
- break;
- case 3: // done
- x[i] = hi[i];
- state[i] = 1;
- lcp.transfer_i_to_N (i);
- break;
- case 4: // keep going
- w[si] = 0;
- lcp.transfer_i_from_N_to_C (si);
- break;
- case 5: // keep going
- x[si] = lo[si];
- state[si] = 0;
- lcp.transfer_i_from_C_to_N (si);
- break;
- case 6: // keep going
- x[si] = hi[si];
- state[si] = 1;
- lcp.transfer_i_from_C_to_N (si);
- break;
- }
-
- if (cmd <= 3) break;
- }
- }
- }
-
- done:
- lcp.unpermute();
-}
-
-//***************************************************************************
-// accuracy and timing test
-
-extern "C" void dTestSolveLCP()
-{
- int n = 100;
- int i,nskip = dPAD(n);
- const dReal tol = REAL(1e-9);
- printf ("dTestSolveLCP()\n");
-
- dReal *A = (dReal*) ALLOCA (n*nskip*sizeof(dReal));
- dReal *x = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *b = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *w = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *lo = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *hi = (dReal*) ALLOCA (n*sizeof(dReal));
-
- dReal *A2 = (dReal*) ALLOCA (n*nskip*sizeof(dReal));
- dReal *b2 = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *lo2 = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *hi2 = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *tmp1 = (dReal*) ALLOCA (n*sizeof(dReal));
- dReal *tmp2 = (dReal*) ALLOCA (n*sizeof(dReal));
-
- double total_time = 0;
- for (int count=0; count < 1000; count++) {
-
- // form (A,b) = a random positive definite LCP problem
- dMakeRandomMatrix (A2,n,n,1.0);
- dMultiply2 (A,A2,A2,n,n,n);
- dMakeRandomMatrix (x,n,1,1.0);
- dMultiply0 (b,A,x,n,n,1);
- for (i=0; i<n; i++) b[i] += (dRandReal()*REAL(0.2))-REAL(0.1);
-
- // choose `nub' in the range 0..n-1
- int nub = 50; //dRandInt (n);
-
- // make limits
- for (i=0; i<nub; i++) lo[i] = -dInfinity;
- for (i=0; i<nub; i++) hi[i] = dInfinity;
- //for (i=nub; i<n; i++) lo[i] = 0;
- //for (i=nub; i<n; i++) hi[i] = dInfinity;
- //for (i=nub; i<n; i++) lo[i] = -dInfinity;
- //for (i=nub; i<n; i++) hi[i] = 0;
- for (i=nub; i<n; i++) lo[i] = -(dRandReal()*REAL(1.0))-REAL(0.01);
- for (i=nub; i<n; i++) hi[i] = (dRandReal()*REAL(1.0))+REAL(0.01);
-
- // set a few limits to lo=hi=0
- /*
- for (i=0; i<10; i++) {
- int j = dRandInt (n-nub) + nub;
- lo[j] = 0;
- hi[j] = 0;
- }
- */
-
- // solve the LCP. we must make copy of A,b,lo,hi (A2,b2,lo2,hi2) for
- // SolveLCP() to permute. also, we'll clear the upper triangle of A2 to
- // ensure that it doesn't get referenced (if it does, the answer will be
- // wrong).
-
- memcpy (A2,A,n*nskip*sizeof(dReal));
- dClearUpperTriangle (A2,n);
- memcpy (b2,b,n*sizeof(dReal));
- memcpy (lo2,lo,n*sizeof(dReal));
- memcpy (hi2,hi,n*sizeof(dReal));
- dSetZero (x,n);
- dSetZero (w,n);
-
- dStopwatch sw;
- dStopwatchReset (&sw);
- dStopwatchStart (&sw);
-
- dSolveLCP (n,A2,x,b2,w,nub,lo2,hi2,0);
-
- dStopwatchStop (&sw);
- double time = dStopwatchTime(&sw);
- total_time += time;
- double average = total_time / double(count+1) * 1000.0;
-
- // check the solution
-
- dMultiply0 (tmp1,A,x,n,n,1);
- for (i=0; i<n; i++) tmp2[i] = b[i] + w[i];
- dReal diff = dMaxDifference (tmp1,tmp2,n,1);
- // printf ("\tA*x = b+w, maximum difference = %.6e - %s (1)\n",diff,
- // diff > tol ? "FAILED" : "passed");
- if (diff > tol) dDebug (0,"A*x = b+w, maximum difference = %.6e",diff);
- int n1=0,n2=0,n3=0;
- for (i=0; i<n; i++) {
- if (x[i]==lo[i] && w[i] >= 0) {
- n1++; // ok
- }
- else if (x[i]==hi[i] && w[i] <= 0) {
- n2++; // ok
- }
- else if (x[i] >= lo[i] && x[i] <= hi[i] && w[i] == 0) {
- n3++; // ok
- }
- else {
- dDebug (0,"FAILED: i=%d x=%.4e w=%.4e lo=%.4e hi=%.4e",i,
- x[i],w[i],lo[i],hi[i]);
- }
- }
-
- // pacifier
- printf ("passed: NL=%3d NH=%3d C=%3d ",n1,n2,n3);
- printf ("time=%10.3f ms avg=%10.4f\n",time * 1000.0,average);
- }
-}
diff --git a/extern/ode/dist/ode/src/lcp.h b/extern/ode/dist/ode/src/lcp.h
deleted file mode 100644
index 86cbd6319eb..00000000000
--- a/extern/ode/dist/ode/src/lcp.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/*
-
-given (A,b,lo,hi), solve the LCP problem: A*x = b+w, where each x(i),w(i)
-satisfies one of
- (1) x = lo, w >= 0
- (2) x = hi, w <= 0
- (3) lo < x < hi, w = 0
-A is a matrix of dimension n*n, everything else is a vector of size n*1.
-lo and hi can be +/- dInfinity as needed. the first `nub' variables are
-unbounded, i.e. hi and lo are assumed to be +/- dInfinity.
-
-we restrict lo(i) <= 0 and hi(i) >= 0.
-
-the original data (A,b) may be modified by this function.
-
-if the `findex' (friction index) parameter is nonzero, it points to an array
-of index values. in this case constraints that have findex[i] >= 0 are
-special. all non-special constraints are solved for, then the lo and hi values
-for the special constraints are set:
- hi[i] = abs( hi[i] * x[findex[i]] )
- lo[i] = -hi[i]
-and the solution continues. this mechanism allows a friction approximation
-to be implemented.
-
-*/
-
-
-#ifndef _ODE_LCP_H_
-#define _ODE_LCP_H_
-
-
-void dSolveLCP (int n, dReal *A, dReal *x, dReal *b, dReal *w,
- int nub, dReal *lo, dReal *hi, int *findex);
-
-
-#endif
-
diff --git a/extern/ode/dist/ode/src/mass.cpp b/extern/ode/dist/ode/src/mass.cpp
deleted file mode 100644
index 9c1aae2033f..00000000000
--- a/extern/ode/dist/ode/src/mass.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <ode/config.h>
-#include <ode/mass.h>
-#include <ode/odemath.h>
-#include <ode/matrix.h>
-
-
-#define _I(i,j) I[(i)*4+(j)]
-
-
-// return 1 if ok, 0 if bad
-
-static int checkMass (dMass *m)
-{
- if (m->mass <= 0) {
- dDEBUGMSG ("mass must be > 0");
- return 0;
- }
- if (!dIsPositiveDefinite (m->I,3)) {
- dDEBUGMSG ("inertia must be positive definite");
- return 0;
- }
-
- // verify that the center of mass position is consistent with the mass
- // and inertia matrix. this is done by checking that the inertia around
- // the center of mass is also positive definite. from the comment in
- // dMassTranslate(), if the body is translated so that its center of mass
- // is at the point of reference, then the new inertia is:
- // I + mass*crossmat(c)^2
- // note that requiring this to be positive definite is exactly equivalent
- // to requiring that the spatial inertia matrix
- // [ mass*eye(3,3) M*crossmat(c)^T ]
- // [ M*crossmat(c) I ]
- // is positive definite, given that I is PD and mass>0. see the theorem
- // about partitioned PD matrices for proof.
-
- dMatrix3 I2,chat;
- dSetZero (chat,12);
- dCROSSMAT (chat,m->c,4,+,-);
- dMULTIPLY0_333 (I2,chat,chat);
- for (int i=0; i<12; i++) I2[i] = m->I[i] + m->mass*I2[i];
- if (!dIsPositiveDefinite (I2,3)) {
- dDEBUGMSG ("center of mass inconsistent with mass parameters");
- return 0;
- }
- return 1;
-}
-
-
-void dMassSetZero (dMass *m)
-{
- dAASSERT (m);
- m->mass = REAL(0.0);
- dSetZero (m->c,sizeof(m->c) / sizeof(dReal));
- dSetZero (m->I,sizeof(m->I) / sizeof(dReal));
-}
-
-
-void dMassSetParameters (dMass *m, dReal themass,
- dReal cgx, dReal cgy, dReal cgz,
- dReal I11, dReal I22, dReal I33,
- dReal I12, dReal I13, dReal I23)
-{
- dAASSERT (m);
- dMassSetZero (m);
- m->mass = themass;
- m->c[0] = cgx;
- m->c[1] = cgy;
- m->c[2] = cgz;
- m->_I(0,0) = I11;
- m->_I(1,1) = I22;
- m->_I(2,2) = I33;
- m->_I(0,1) = I12;
- m->_I(0,2) = I13;
- m->_I(1,2) = I23;
- m->_I(1,0) = I12;
- m->_I(2,0) = I13;
- m->_I(2,1) = I23;
- checkMass (m);
-}
-
-
-void dMassSetSphere (dMass *m, dReal density, dReal radius)
-{
- dAASSERT (m);
- dMassSetZero (m);
- m->mass = (REAL(4.0)/REAL(3.0)) * M_PI * radius*radius*radius * density;
- dReal II = REAL(0.4) * m->mass * radius*radius;
- m->_I(0,0) = II;
- m->_I(1,1) = II;
- m->_I(2,2) = II;
-
-# ifndef dNODEBUG
- checkMass (m);
-# endif
-}
-
-
-void dMassSetCappedCylinder (dMass *m, dReal density, int direction,
- dReal a, dReal b)
-{
- dReal M1,M2,Ia,Ib;
- dAASSERT (m);
- dUASSERT (direction >= 1 && direction <= 3,"bad direction number");
- dMassSetZero (m);
- M1 = M_PI*a*a*b*density; // cylinder mass
- M2 = (REAL(4.0)/REAL(3.0))*M_PI*a*a*a*density; // total cap mass
- m->mass = M1+M2;
- Ia = M1*(REAL(0.25)*a*a + (REAL(1.0)/REAL(12.0))*b*b) +
- M2*(REAL(0.4)*a*a + REAL(0.5)*b*b);
- Ib = (M1*REAL(0.5) + M2*REAL(0.4))*a*a;
- m->_I(0,0) = Ia;
- m->_I(1,1) = Ia;
- m->_I(2,2) = Ia;
- m->_I(direction-1,direction-1) = Ib;
-
-# ifndef dNODEBUG
- checkMass (m);
-# endif
-}
-
-
-void dMassSetBox (dMass *m, dReal density,
- dReal lx, dReal ly, dReal lz)
-{
- dAASSERT (m);
- dMassSetZero (m);
- dReal M = lx*ly*lz*density;
- m->mass = M;
- m->_I(0,0) = M/REAL(12.0) * (ly*ly + lz*lz);
- m->_I(1,1) = M/REAL(12.0) * (lx*lx + lz*lz);
- m->_I(2,2) = M/REAL(12.0) * (lx*lx + ly*ly);
-
-# ifndef dNODEBUG
- checkMass (m);
-# endif
-}
-
-
-void dMassAdjust (dMass *m, dReal newmass)
-{
- dAASSERT (m);
- dReal scale = newmass / m->mass;
- m->mass = newmass;
- for (int i=0; i<3; i++) for (int j=0; j<3; j++) m->_I(i,j) *= scale;
-
-# ifndef dNODEBUG
- checkMass (m);
-# endif
-}
-
-
-void dMassTranslate (dMass *m, dReal x, dReal y, dReal z)
-{
- // if the body is translated by `a' relative to its point of reference,
- // the new inertia about the point of reference is:
- //
- // I + mass*(crossmat(c)^2 - crossmat(c+a)^2)
- //
- // where c is the existing center of mass and I is the old inertia.
-
- int i,j;
- dMatrix3 ahat,chat,t1,t2;
- dReal a[3];
-
- dAASSERT (m);
-
- // adjust inertia matrix
- dSetZero (chat,12);
- dCROSSMAT (chat,m->c,4,+,-);
- a[0] = x + m->c[0];
- a[1] = y + m->c[1];
- a[2] = z + m->c[2];
- dSetZero (ahat,12);
- dCROSSMAT (ahat,a,4,+,-);
- dMULTIPLY0_333 (t1,ahat,ahat);
- dMULTIPLY0_333 (t2,chat,chat);
- for (i=0; i<3; i++) for (j=0; j<3; j++)
- m->_I(i,j) += m->mass * (t2[i*4+j]-t1[i*4+j]);
-
- // ensure perfect symmetry
- m->_I(1,0) = m->_I(0,1);
- m->_I(2,0) = m->_I(0,2);
- m->_I(2,1) = m->_I(1,2);
-
- // adjust center of mass
- m->c[0] += x;
- m->c[1] += y;
- m->c[2] += z;
-
-# ifndef dNODEBUG
- checkMass (m);
-# endif
-}
-
-
-void dMassRotate (dMass *m, const dMatrix3 R)
-{
- // if the body is rotated by `R' relative to its point of reference,
- // the new inertia about the point of reference is:
- //
- // R * I * R'
- //
- // where I is the old inertia.
-
- dMatrix3 t1;
- dReal t2[3];
-
- dAASSERT (m);
-
- // rotate inertia matrix
- dMULTIPLY2_333 (t1,m->I,R);
- dMULTIPLY0_333 (m->I,R,t1);
-
- // ensure perfect symmetry
- m->_I(1,0) = m->_I(0,1);
- m->_I(2,0) = m->_I(0,2);
- m->_I(2,1) = m->_I(1,2);
-
- // rotate center of mass
- dMULTIPLY0_331 (t2,R,m->c);
- m->c[0] = t2[0];
- m->c[1] = t2[1];
- m->c[2] = t2[2];
-
-# ifndef dNODEBUG
- checkMass (m);
-# endif
-}
-
-
-void dMassAdd (dMass *a, const dMass *b)
-{
- int i;
- dAASSERT (a && b);
- dReal denom = dRecip (a->mass + b->mass);
- for (i=0; i<3; i++) a->c[i] = (a->c[i]*a->mass + b->c[i]*b->mass)*denom;
- a->mass += b->mass;
- for (i=0; i<12; i++) a->I[i] += b->I[i];
-}
diff --git a/extern/ode/dist/ode/src/mat.cpp b/extern/ode/dist/ode/src/mat.cpp
deleted file mode 100644
index 6e635dcc994..00000000000
--- a/extern/ode/dist/ode/src/mat.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <ode/config.h>
-#include <ode/misc.h>
-#include <ode/matrix.h>
-#include <ode/error.h>
-#include <ode/memory.h>
-#include "mat.h"
-
-
-dMatrix::dMatrix()
-{
- n = 0;
- m = 0;
- data = 0;
-}
-
-
-dMatrix::dMatrix (int rows, int cols)
-{
- if (rows < 1 || cols < 1) dDebug (0,"bad matrix size");
- n = rows;
- m = cols;
- data = (dReal*) dAlloc (n*m*sizeof(dReal));
- dSetZero (data,n*m);
-}
-
-
-dMatrix::dMatrix (const dMatrix &a)
-{
- n = a.n;
- m = a.m;
- data = (dReal*) dAlloc (n*m*sizeof(dReal));
- memcpy (data,a.data,n*m*sizeof(dReal));
-}
-
-
-dMatrix::dMatrix (int rows, int cols,
- dReal *_data, int rowskip, int colskip)
-{
- if (rows < 1 || cols < 1) dDebug (0,"bad matrix size");
- n = rows;
- m = cols;
- data = (dReal*) dAlloc (n*m*sizeof(dReal));
- for (int i=0; i<n; i++) {
- for (int j=0; j<m; j++) data[i*m+j] = _data[i*rowskip + j*colskip];
- }
-}
-
-
-dMatrix::~dMatrix()
-{
- if (data) dFree (data,n*m*sizeof(dReal));
-}
-
-
-dReal & dMatrix::operator () (int i, int j)
-{
- if (i < 0 || i >= n || j < 0 || j >= m) dDebug (0,"bad matrix (i,j)");
- return data [i*m+j];
-}
-
-
-void dMatrix::operator= (const dMatrix &a)
-{
- if (data) dFree (data,n*m*sizeof(dReal));
- n = a.n;
- m = a.m;
- if (n > 0 && m > 0) {
- data = (dReal*) dAlloc (n*m*sizeof(dReal));
- memcpy (data,a.data,n*m*sizeof(dReal));
- }
- else data = 0;
-}
-
-
-void dMatrix::operator= (dReal a)
-{
- for (int i=0; i<n*m; i++) data[i] = a;
-}
-
-
-dMatrix dMatrix::transpose()
-{
- dMatrix r (m,n);
- for (int i=0; i<n; i++) {
- for (int j=0; j<m; j++) r.data[j*n+i] = data[i*m+j];
- }
- return r;
-}
-
-
-dMatrix dMatrix::select (int np, int *p, int nq, int *q)
-{
- if (np < 1 || nq < 1) dDebug (0,"Matrix select, bad index array sizes");
- dMatrix r (np,nq);
- for (int i=0; i<np; i++) {
- for (int j=0; j<nq; j++) {
- if (p[i] < 0 || p[i] >= n || q[i] < 0 || q[i] >= m)
- dDebug (0,"Matrix select, bad index arrays");
- r.data[i*nq+j] = data[p[i]*m+q[j]];
- }
- }
- return r;
-}
-
-
-dMatrix dMatrix::operator + (const dMatrix &a)
-{
- if (n != a.n || m != a.m) dDebug (0,"matrix +, mismatched sizes");
- dMatrix r (n,m);
- for (int i=0; i<n*m; i++) r.data[i] = data[i] + a.data[i];
- return r;
-}
-
-
-dMatrix dMatrix::operator - (const dMatrix &a)
-{
- if (n != a.n || m != a.m) dDebug (0,"matrix -, mismatched sizes");
- dMatrix r (n,m);
- for (int i=0; i<n*m; i++) r.data[i] = data[i] - a.data[i];
- return r;
-}
-
-
-dMatrix dMatrix::operator - ()
-{
- dMatrix r (n,m);
- for (int i=0; i<n*m; i++) r.data[i] = -data[i];
- return r;
-}
-
-
-dMatrix dMatrix::operator * (const dMatrix &a)
-{
- if (m != a.n) dDebug (0,"matrix *, mismatched sizes");
- dMatrix r (n,a.m);
- for (int i=0; i<n; i++) {
- for (int j=0; j<a.m; j++) {
- dReal sum = 0;
- for (int k=0; k<m; k++) sum += data[i*m+k] * a.data[k*a.m+j];
- r.data [i*a.m+j] = sum;
- }
- }
- return r;
-}
-
-
-void dMatrix::operator += (const dMatrix &a)
-{
- if (n != a.n || m != a.m) dDebug (0,"matrix +=, mismatched sizes");
- for (int i=0; i<n*m; i++) data[i] += a.data[i];
-}
-
-
-void dMatrix::operator -= (const dMatrix &a)
-{
- if (n != a.n || m != a.m) dDebug (0,"matrix -=, mismatched sizes");
- for (int i=0; i<n*m; i++) data[i] -= a.data[i];
-}
-
-
-void dMatrix::clearUpperTriangle()
-{
- if (n != m) dDebug (0,"clearUpperTriangle() only works on square matrices");
- for (int i=0; i<n; i++) {
- for (int j=i+1; j<m; j++) data[i*m+j] = 0;
- }
-}
-
-
-void dMatrix::clearLowerTriangle()
-{
- if (n != m) dDebug (0,"clearLowerTriangle() only works on square matrices");
- for (int i=0; i<n; i++) {
- for (int j=0; j<i; j++) data[i*m+j] = 0;
- }
-}
-
-
-void dMatrix::makeRandom (dReal range)
-{
- for (int i=0; i<n; i++) {
- for (int j=0; j<m; j++)
- data[i*m+j] = (dRandReal()*REAL(2.0)-REAL(1.0))*range;
- }
-}
-
-
-void dMatrix::print (char *fmt, FILE *f)
-{
- for (int i=0; i<n; i++) {
- for (int j=0; j<m; j++) fprintf (f,fmt,data[i*m+j]);
- fprintf (f,"\n");
- }
-}
-
-
-dReal dMatrix::maxDifference (const dMatrix &a)
-{
- if (n != a.n || m != a.m) dDebug (0,"maxDifference(), mismatched sizes");
- dReal max = 0;
- for (int i=0; i<n; i++) {
- for (int j=0; j<m; j++) {
- dReal diff = dFabs(data[i*m+j] - a.data[i*m+j]);
- if (diff > max) max = diff;
- }
- }
- return max;
-}
diff --git a/extern/ode/dist/ode/src/mat.h b/extern/ode/dist/ode/src/mat.h
deleted file mode 100644
index 26f6bd1093a..00000000000
--- a/extern/ode/dist/ode/src/mat.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-// matrix class. this is mostly for convenience in the testing code, it is
-// not optimized at all. correctness is much more importance here.
-
-#ifndef _ODE_MAT_H_
-#define _ODE_MAT_H_
-
-#include <ode/common.h>
-
-
-class dMatrix {
- int n,m; // matrix dimension, n,m >= 0
- dReal *data; // if nonzero, n*m elements allocated on the heap
-
-public:
- // constructors, destructors
- dMatrix(); // make default 0x0 matrix
- dMatrix (int rows, int cols); // construct zero matrix of given size
- dMatrix (const dMatrix &); // construct copy of given matrix
- // create copy of given data - element (i,j) is data[i*rowskip+j*colskip]
- dMatrix (int rows, int cols, dReal *_data, int rowskip, int colskip);
- ~dMatrix(); // destructor
-
- // data movement
- dReal & operator () (int i, int j); // reference an element
- void operator= (const dMatrix &); // matrix = matrix
- void operator= (dReal); // matrix = scalar
- dMatrix transpose(); // return transposed matrix
- // return a permuted submatrix of this matrix, made up of the rows in p
- // and the columns in q. p has np elements, q has nq elements.
- dMatrix select (int np, int *p, int nq, int *q);
-
- // operators
- dMatrix operator + (const dMatrix &);
- dMatrix operator - (const dMatrix &);
- dMatrix operator - ();
- dMatrix operator * (const dMatrix &);
- void operator += (const dMatrix &);
- void operator -= (const dMatrix &);
-
- // utility
- void clearUpperTriangle();
- void clearLowerTriangle();
- void makeRandom (dReal range);
- void print (char *fmt = "%10.4f ", FILE *f=stdout);
- dReal maxDifference (const dMatrix &);
-};
-
-
-#endif
-
diff --git a/extern/ode/dist/ode/src/matrix.cpp b/extern/ode/dist/ode/src/matrix.cpp
deleted file mode 100644
index 16afe915dd6..00000000000
--- a/extern/ode/dist/ode/src/matrix.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <ode/common.h>
-#include <ode/matrix.h>
-
-// misc defines
-#define ALLOCA dALLOCA16
-
-
-void dSetZero (dReal *a, int n)
-{
- dAASSERT (a && n >= 0);
- while (n > 0) {
- *(a++) = 0;
- n--;
- }
-}
-
-
-void dSetValue (dReal *a, int n, dReal value)
-{
- dAASSERT (a && n >= 0);
- while (n > 0) {
- *(a++) = value;
- n--;
- }
-}
-
-
-void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p, int q, int r)
-{
- int i,j,k,qskip,rskip,rpad;
- dAASSERT (A && B && C && p>0 && q>0 && r>0);
- qskip = dPAD(q);
- rskip = dPAD(r);
- rpad = rskip - r;
- dReal sum;
- const dReal *b,*c,*bb;
- bb = B;
- for (i=p; i; i--) {
- for (j=0 ; j<r; j++) {
- c = C + j;
- b = bb;
- sum = 0;
- for (k=q; k; k--, c+=rskip) sum += (*(b++))*(*c);
- *(A++) = sum;
- }
- A += rpad;
- bb += qskip;
- }
-}
-
-
-void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p, int q, int r)
-{
- int i,j,k,pskip,rskip;
- dReal sum;
- dAASSERT (A && B && C && p>0 && q>0 && r>0);
- pskip = dPAD(p);
- rskip = dPAD(r);
- for (i=0; i<p; i++) {
- for (j=0; j<r; j++) {
- sum = 0;
- for (k=0; k<q; k++) sum += B[i+k*pskip] * C[j+k*rskip];
- A[i*rskip+j] = sum;
- }
- }
-}
-
-
-void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p, int q, int r)
-{
- int i,j,k,z,rpad,qskip;
- dReal sum;
- const dReal *bb,*cc;
- dAASSERT (A && B && C && p>0 && q>0 && r>0);
- rpad = dPAD(r) - r;
- qskip = dPAD(q);
- bb = B;
- for (i=p; i; i--) {
- cc = C;
- for (j=r; j; j--) {
- z = 0;
- sum = 0;
- for (k=q; k; k--,z++) sum += bb[z] * cc[z];
- *(A++) = sum;
- cc += qskip;
- }
- A += rpad;
- bb += qskip;
- }
-}
-
-
-int dFactorCholesky (dReal *A, int n)
-{
- int i,j,k,nskip;
- dReal sum,*a,*b,*aa,*bb,*cc,*recip;
- dAASSERT (n > 0 && A);
- nskip = dPAD (n);
- recip = (dReal*) ALLOCA (n * sizeof(dReal));
- aa = A;
- for (i=0; i<n; i++) {
- bb = A;
- cc = A + i*nskip;
- for (j=0; j<i; j++) {
- sum = *cc;
- a = aa;
- b = bb;
- for (k=j; k; k--) sum -= (*(a++))*(*(b++));
- *cc = sum * recip[j];
- bb += nskip;
- cc++;
- }
- sum = *cc;
- a = aa;
- for (k=i; k; k--, a++) sum -= (*a)*(*a);
- if (sum <= REAL(0.0)) return 0;
- *cc = dSqrt(sum);
- recip[i] = dRecip (*cc);
- aa += nskip;
- }
- return 1;
-}
-
-
-void dSolveCholesky (const dReal *L, dReal *b, int n)
-{
- int i,k,nskip;
- dReal sum,*y;
- dAASSERT (n > 0 && L && b);
- nskip = dPAD (n);
- y = (dReal*) ALLOCA (n*sizeof(dReal));
- for (i=0; i<n; i++) {
- sum = 0;
- for (k=0; k < i; k++) sum += L[i*nskip+k]*y[k];
- y[i] = (b[i]-sum)/L[i*nskip+i];
- }
- for (i=n-1; i >= 0; i--) {
- sum = 0;
- for (k=i+1; k < n; k++) sum += L[k*nskip+i]*b[k];
- b[i] = (y[i]-sum)/L[i*nskip+i];
- }
-}
-
-
-int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n)
-{
- int i,j,nskip;
- dReal *L,*x;
- dAASSERT (n > 0 && A && Ainv);
- nskip = dPAD (n);
- L = (dReal*) ALLOCA (nskip*n*sizeof(dReal));
- memcpy (L,A,nskip*n*sizeof(dReal));
- x = (dReal*) ALLOCA (n*sizeof(dReal));
- if (dFactorCholesky (L,n)==0) return 0;
- dSetZero (Ainv,n*nskip); // make sure all padding elements set to 0
- for (i=0; i<n; i++) {
- for (j=0; j<n; j++) x[j] = 0;
- x[i] = 1;
- dSolveCholesky (L,x,n);
- for (j=0; j<n; j++) Ainv[j*nskip+i] = x[j];
- }
- return 1;
-}
-
-
-int dIsPositiveDefinite (const dReal *A, int n)
-{
- dReal *Acopy;
- dAASSERT (n > 0 && A);
- int nskip = dPAD (n);
- Acopy = (dReal*) ALLOCA (nskip*n * sizeof(dReal));
- memcpy (Acopy,A,nskip*n * sizeof(dReal));
- return dFactorCholesky (Acopy,n);
-}
-
-
-/***** this has been replaced by a faster version
-void dSolveL1T (const dReal *L, dReal *b, int n, int nskip)
-{
- int i,j;
- dAASSERT (L && b && n >= 0 && nskip >= n);
- dReal sum;
- for (i=n-2; i>=0; i--) {
- sum = 0;
- for (j=i+1; j<n; j++) sum += L[j*nskip+i]*b[j];
- b[i] -= sum;
- }
-}
-*/
-
-
-void dVectorScale (dReal *a, const dReal *d, int n)
-{
- dAASSERT (a && d && n >= 0);
- for (int i=0; i<n; i++) a[i] *= d[i];
-}
-
-
-void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip)
-{
- dAASSERT (L && d && b && n > 0 && nskip >= n);
- dSolveL1 (L,b,n,nskip);
- dVectorScale (b,d,n);
- dSolveL1T (L,b,n,nskip);
-}
-
-
-void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip)
-{
- int j,p;
- dReal *W1,*W2,W11,W21,alpha1,alpha2,alphanew,gamma1,gamma2,k1,k2,Wp,ell,dee;
- dAASSERT (L && d && a && n > 0 && nskip >= n);
-
- if (n < 2) return;
- W1 = (dReal*) ALLOCA (n*sizeof(dReal));
- W2 = (dReal*) ALLOCA (n*sizeof(dReal));
-
- W1[0] = 0;
- W2[0] = 0;
- for (j=1; j<n; j++) W1[j] = W2[j] = a[j] * M_SQRT1_2;
- W11 = (REAL(0.5)*a[0]+1)*M_SQRT1_2;
- W21 = (REAL(0.5)*a[0]-1)*M_SQRT1_2;
-
- alpha1=1;
- alpha2=1;
-
- dee = d[0];
- alphanew = alpha1 + (W11*W11)*dee;
- dee /= alphanew;
- gamma1 = W11 * dee;
- dee *= alpha1;
- alpha1 = alphanew;
- alphanew = alpha2 - (W21*W21)*dee;
- dee /= alphanew;
- gamma2 = W21 * dee;
- alpha2 = alphanew;
- k1 = REAL(1.0) - W21*gamma1;
- k2 = W21*gamma1*W11 - W21;
- for (p=1; p<n; p++) {
- Wp = W1[p];
- ell = L[p*nskip];
- W1[p] = Wp - W11*ell;
- W2[p] = k1*Wp + k2*ell;
- }
-
- for (j=1; j<n; j++) {
- dee = d[j];
- alphanew = alpha1 + (W1[j]*W1[j])*dee;
- dee /= alphanew;
- gamma1 = W1[j] * dee;
- dee *= alpha1;
- alpha1 = alphanew;
- alphanew = alpha2 - (W2[j]*W2[j])*dee;
- dee /= alphanew;
- gamma2 = W2[j] * dee;
- dee *= alpha2;
- d[j] = dee;
- alpha2 = alphanew;
-
- k1 = W1[j];
- k2 = W2[j];
- for (p=j+1; p<n; p++) {
- ell = L[p*nskip+j];
- Wp = W1[p] - k1 * ell;
- ell += gamma1 * Wp;
- W1[p] = Wp;
- Wp = W2[p] - k2 * ell;
- ell -= gamma2 * Wp;
- W2[p] = Wp;
- L[p*nskip+j] = ell;
- }
- }
-}
-
-
-// macros for dLDLTRemove() for accessing A - either access the matrix
-// directly or access it via row pointers. we are only supposed to reference
-// the lower triangle of A (it is symmetric), but indexes i and j come from
-// permutation vectors so they are not predictable. so do a test on the
-// indexes - this should not slow things down too much, as we don't do this
-// in an inner loop.
-
-#define _GETA(i,j) (A[i][j])
-//#define _GETA(i,j) (A[(i)*nskip+(j)])
-#define GETA(i,j) ((i > j) ? _GETA(i,j) : _GETA(j,i))
-
-
-void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d,
- int n1, int n2, int r, int nskip)
-{
- int i;
- dAASSERT(A && p && L && d && n1 > 0 && n2 > 0 && r >= 0 && r < n2 &&
- n1 >= n2 && nskip >= n1);
- #ifndef dNODEBUG
- for (i=0; i<n2; i++) dIASSERT(p[i] >= 0 && p[i] < n1);
- #endif
-
- if (r==n2-1) {
- return; // deleting last row/col is easy
- }
- else if (r==0) {
- dReal *a = (dReal*) ALLOCA (n2 * sizeof(dReal));
- for (i=0; i<n2; i++) a[i] = -GETA(p[i],p[0]);
- a[0] += REAL(1.0);
- dLDLTAddTL (L,d,a,n2,nskip);
- }
- else {
- dReal *t = (dReal*) ALLOCA (r * sizeof(dReal));
- dReal *a = (dReal*) ALLOCA ((n2-r) * sizeof(dReal));
- for (i=0; i<r; i++) t[i] = L[r*nskip+i] / d[i];
- for (i=0; i<(n2-r); i++)
- a[i] = dDot(L+(r+i)*nskip,t,r) - GETA(p[r+i],p[r]);
- a[0] += REAL(1.0);
- dLDLTAddTL (L + r*nskip+r, d+r, a, n2-r, nskip);
- }
-
- // snip out row/column r from L and d
- dRemoveRowCol (L,n2,nskip,r);
- if (r < (n2-1)) memmove (d+r,d+r+1,(n2-r-1)*sizeof(dReal));
-}
-
-
-void dRemoveRowCol (dReal *A, int n, int nskip, int r)
-{
- int i;
- dAASSERT(A && n > 0 && nskip >= n && r >= 0 && r < n);
- if (r >= n-1) return;
- if (r > 0) {
- for (i=0; i<r; i++)
- memmove (A+i*nskip+r,A+i*nskip+r+1,(n-r-1)*sizeof(dReal));
- for (i=r; i<(n-1); i++)
- memcpy (A+i*nskip,A+i*nskip+nskip,r*sizeof(dReal));
- }
- for (i=r; i<(n-1); i++)
- memcpy (A+i*nskip+r,A+i*nskip+nskip+r+1,(n-r-1)*sizeof(dReal));
-}
diff --git a/extern/ode/dist/ode/src/memory.cpp b/extern/ode/dist/ode/src/memory.cpp
deleted file mode 100644
index df61f97375f..00000000000
--- a/extern/ode/dist/ode/src/memory.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-// if the dDEBUG_ALLOC macro is defined, the following tests are performed in
-// the default allocator:
-// - size > 0 for alloc and realloc
-// - realloc and free operate on uncorrupted blocks
-// - realloc and free with the correct sizes
-// - on exit, report of block allocation statistics
-// - on exit, report of unfreed blocks and if they are corrupted
-// the allocator will also call Debug() when it allocates a block with
-// sequence number `_d_seqstop' or pointer value `_d_ptrstop'. these variables
-// are global and can be set in the debugger.
-
-#include <ode/config.h>
-#include <ode/memory.h>
-#include <ode/error.h>
-
-#ifdef dDEBUG_ALLOC
-
-// when debugging, this is a header that it put at start of all blocks.
-// it contains `padding', which are PADSIZE elements of known value just
-// before the user memory starts. another PADSIZE padding elements are put
-// at the end of the user memory. the idea is that if the user accidentally
-// steps outside the allocated memory, it can hopefully be detected by
-// examining the padding elements.
-
-#define PADSIZE 10
-struct blockHeader {
- long pad1; // protective padding
- long seq; // sequence number
- long size; // data size
- long flags; // bit 0 = ignore this block in final report
- blockHeader *next,*prev; // next & previous blocks
- long pad[PADSIZE]; // protective padding
-};
-
-// compute the memory block size, including padding. the user memory block is
-// rounded up to a multiple of 4 bytes, to get alignment for the padding at
-// the end of the block.
-
-#define BSIZE(size) (((((size)-1) | 3)+1) + sizeof(blockHeader) + \
- PADSIZE * sizeof(long))
-
-static blockHeader dummyblock = {0,0,0,0,&dummyblock,&dummyblock,
- {0,0,0,0,0,0,0,0,0,0}};
-static blockHeader *firstblock = &dummyblock;
-static long num_blocks_alloced = 0;
-static long num_bytes_alloced = 0;
-static long total_num_blocks_alloced = 0;
-static long total_num_bytes_alloced = 0;
-static long max_blocks_alloced = 0;
-static long max_bytes_alloced = 0;
-
-long _d_seqstop = 0;
-void *_d_ptrstop = 0;
-
-static int checkBlockOk (void *ptr, int fatal)
-{
- if (ptr==0) dDebug (0,"0 passed to checkBlockOk()");
- blockHeader *b = ((blockHeader*) ptr) - 1;
- int i,ok = 1;
- if (b->pad1 != (long)0xdeadbeef || b->seq < 0 || b->size < 0) ok = 0;
- if (ok) {
- for (i=0; i<PADSIZE; i++) if (b->pad[i] != (long)0xdeadbeef) ok = 0;
- }
- if (ok) {
- long *endpad = (long*) (((char*)ptr) + (((b->size-1) | 3)+1));
- for (i=0; i<PADSIZE; i++) if (endpad[i] != (long)0xdeadbeef) ok = 0;
- }
- if (!ok && fatal)
- dDebug (0,"corrupted memory block found, ptr=%p, size=%d, "
- "seq=%ld", ptr,b->size,b->seq);
- return ok;
-}
-
-#endif
-
-
-static dAllocFunction *allocfn = 0;
-static dReallocFunction *reallocfn = 0;
-static dFreeFunction *freefn = 0;
-
-
-
-void dSetAllocHandler (dAllocFunction *fn)
-{
- allocfn = fn;
-}
-
-
-void dSetReallocHandler (dReallocFunction *fn)
-{
- reallocfn = fn;
-}
-
-
-void dSetFreeHandler (dFreeFunction *fn)
-{
- freefn = fn;
-}
-
-
-dAllocFunction *dGetAllocHandler()
-{
- return allocfn;
-}
-
-
-dReallocFunction *dGetReallocHandler()
-{
- return reallocfn;
-}
-
-
-dFreeFunction *dGetFreeHandler()
-{
- return freefn;
-}
-
-
-void * dAlloc (int size)
-{
-#ifdef dDEBUG_ALLOC
- if (size < 1) dDebug (0,"bad block size to Alloc()");
-
- num_blocks_alloced++;
- num_bytes_alloced += size;
- total_num_blocks_alloced++;
- total_num_bytes_alloced += size;
- if (num_blocks_alloced > max_blocks_alloced)
- max_blocks_alloced = num_blocks_alloced;
- if (num_bytes_alloced > max_bytes_alloced)
- max_bytes_alloced = num_bytes_alloced;
-
- if (total_num_blocks_alloced == _d_seqstop)
- dDebug (0,"ALLOCATOR TRAP ON SEQUENCE NUMBER %d",_d_seqstop);
- long size2 = BSIZE(size);
- blockHeader *b = (blockHeader*) malloc (size2);
- if (b+1 == _d_ptrstop)
- dDebug (0,"ALLOCATOR TRAP ON BLOCK POINTER %p",_d_ptrstop);
- for (unsigned int i=0; i < (size2/sizeof(long)); i++)
- ((long*)b)[i] = 0xdeadbeef;
- b->seq = total_num_blocks_alloced;
- b->size = size;
- b->flags = 0;
- b->next = firstblock->next;
- b->prev = firstblock;
- firstblock->next->prev = b;
- firstblock->next = b;
- return b + 1;
-#else
- if (allocfn) return allocfn (size); else return malloc (size);
-#endif
-}
-
-
-void * dRealloc (void *ptr, int oldsize, int newsize)
-{
-#ifdef dDEBUG_ALLOC
- if (ptr==0) dDebug (0,"Realloc() called with ptr==0");
- checkBlockOk (ptr,1);
- blockHeader *b = ((blockHeader*) ptr) - 1;
- if (b->size != oldsize)
- dDebug (0,"Realloc(%p,%d,%d) has bad old size, good size "
- "is %ld, seq=%ld",ptr,oldsize,newsize,b->size,b->seq);
- void *p = dAlloc (newsize);
- blockHeader *newb = ((blockHeader*) p) - 1;
- newb->flags = b->flags;
- if (oldsize>=1) memcpy (p,ptr,oldsize);
- dFree (ptr,oldsize);
- return p;
-#else
- if (reallocfn) return reallocfn (ptr,oldsize,newsize);
- else return realloc (ptr,newsize);
-#endif
-}
-
-
-void dFree (void *ptr, int size)
-{
- if (!ptr) return;
-#ifdef dDEBUG_ALLOC
- checkBlockOk (ptr,1);
- blockHeader *b = ((blockHeader*) ptr) - 1;
- if (b->size != size)
- dDebug (0,"Free(%p,%d) has bad size, good size "
- "is %ld, seq=%ld",ptr,size,b->size,b->seq);
- num_blocks_alloced--;
- num_bytes_alloced -= b->size;
- if (num_blocks_alloced < 0 || num_bytes_alloced < 0)
- dDebug (0,"Free called too many times");
-
- b->next->prev = b->prev;
- b->prev->next = b->next;
- memset (b,0,BSIZE(b->size));
-
- free (b);
-#else
- if (freefn) freefn (ptr,size); else free (ptr);
-#endif
-}
-
-
-void dAllocDontReport (void *ptr)
-{
-#ifdef dDEBUG_ALLOC
- checkBlockOk (ptr,1);
- blockHeader *b = ((blockHeader*) ptr) - 1;
- b->flags |= 1;
-#endif
-}
-
-
-#ifdef dDEBUG_ALLOC
-
-static void printReport()
-{
- // subtract the "dont report" blocks from the totals
- blockHeader *b = firstblock;
- do {
- if (b != &dummyblock && (b->flags & 1)) {
- num_blocks_alloced--;
- num_bytes_alloced -= b->size;
- if (!checkBlockOk (b+1,0))
- fprintf (stderr,"\tCORRUPTED: %p, size=%ld, seq=%ld\n",b+1,
- b->size,b->seq);
- }
- b = b->prev;
- }
- while (b != firstblock);
-
- fprintf (stderr,"\nALLOCATOR REPORT\n");
- fprintf (stderr,"\tblocks still allocated: %ld\n",num_blocks_alloced);
- fprintf (stderr,"\tbytes still allocated: %ld\n",num_bytes_alloced);
- fprintf (stderr,"\ttotal blocks allocated: %ld\n",total_num_blocks_alloced);
- fprintf (stderr,"\ttotal bytes allocated: %ld\n",total_num_bytes_alloced);
- fprintf (stderr,"\tmax blocks allocated: %ld\n",max_blocks_alloced);
- fprintf (stderr,"\tmax bytes allocated: %ld\n",max_bytes_alloced);
-
- b = firstblock;
- do {
- if (b != &dummyblock && (b->flags & 1)==0) {
- int ok = checkBlockOk (b+1,0);
- fprintf (stderr,"\tUNFREED: %p, size=%ld, seq=%ld (%s)\n",b+1,
- b->size,b->seq, ok ? "ok" : "CORUPTED");
- }
- b = b->prev;
- }
- while (b != firstblock);
- fprintf (stderr,"\n");
-}
-
-
-struct dMemoryReportPrinter {
- ~dMemoryReportPrinter() { printReport(); }
-} _dReportPrinter;
-
-#endif
diff --git a/extern/ode/dist/ode/src/misc.cpp b/extern/ode/dist/ode/src/misc.cpp
deleted file mode 100644
index bdc1579d5aa..00000000000
--- a/extern/ode/dist/ode/src/misc.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <ode/config.h>
-#include <ode/misc.h>
-#include <ode/matrix.h>
-
-//****************************************************************************
-// random numbers
-
-static unsigned long seed = 0;
-
-unsigned long dRand()
-{
- seed = (1664525L*seed + 1013904223L) & 0xffffffff;
- return seed;
-}
-
-
-unsigned long dRandGetSeed()
-{
- return seed;
-}
-
-
-void dRandSetSeed (unsigned long s)
-{
- seed = s;
-}
-
-
-int dTestRand()
-{
- unsigned long oldseed = seed;
- int ret = 1;
- seed = 0;
- if (dRand() != 0x3c6ef35f || dRand() != 0x47502932 ||
- dRand() != 0xd1ccf6e9 || dRand() != 0xaaf95334 ||
- dRand() != 0x6252e503) ret = 0;
- seed = oldseed;
- return ret;
-}
-
-
-int dRandInt (int n)
-{
- double a = double(n) / 4294967296.0;
- return (int) (double(dRand()) * a);
-}
-
-
-dReal dRandReal()
-{
- return ((dReal) dRand()) / ((dReal) 0xffffffff);
-}
-
-//****************************************************************************
-// matrix utility stuff
-
-void dPrintMatrix (dReal *A, int n, int m, char *fmt, FILE *f)
-{
- int i,j;
- int skip = dPAD(m);
- for (i=0; i<n; i++) {
- for (j=0; j<m; j++) fprintf (f,fmt,A[i*skip+j]);
- fprintf (f,"\n");
- }
-}
-
-
-void dMakeRandomVector (dReal *A, int n, dReal range)
-{
- int i;
- for (i=0; i<n; i++) A[i] = (dRandReal()*REAL(2.0)-REAL(1.0))*range;
-}
-
-
-void dMakeRandomMatrix (dReal *A, int n, int m, dReal range)
-{
- int i,j;
- int skip = dPAD(m);
- dSetZero (A,n*skip);
- for (i=0; i<n; i++) {
- for (j=0; j<m; j++) A[i*skip+j] = (dRandReal()*REAL(2.0)-REAL(1.0))*range;
- }
-}
-
-
-void dClearUpperTriangle (dReal *A, int n)
-{
- int i,j;
- int skip = dPAD(n);
- for (i=0; i<n; i++) {
- for (j=i+1; j<n; j++) A[i*skip+j] = 0;
- }
-}
-
-
-dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m)
-{
- int i,j;
- int skip = dPAD(m);
- dReal diff,max;
- max = 0;
- for (i=0; i<n; i++) {
- for (j=0; j<m; j++) {
- diff = dFabs(A[i*skip+j] - B[i*skip+j]);
- if (diff > max) max = diff;
- }
- }
- return max;
-}
-
-
-dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n)
-{
- int i,j;
- int skip = dPAD(n);
- dReal diff,max;
- max = 0;
- for (i=0; i<n; i++) {
- for (j=0; j<=i; j++) {
- diff = dFabs(A[i*skip+j] - B[i*skip+j]);
- if (diff > max) max = diff;
- }
- }
- return max;
-}
diff --git a/extern/ode/dist/ode/src/objects.h b/extern/ode/dist/ode/src/objects.h
deleted file mode 100644
index 4d2c4ca6af7..00000000000
--- a/extern/ode/dist/ode/src/objects.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-// object, body, and world structs.
-
-
-#ifndef _ODE_OBJECT_H_
-#define _ODE_OBJECT_H_
-
-#include <ode/common.h>
-#include <ode/memory.h>
-#include <ode/mass.h>
-#include "array.h"
-
-
-// some body flags
-
-enum {
- dxBodyFlagFiniteRotation = 1, // use finite rotations
- dxBodyFlagFiniteRotationAxis = 2, // use finite rotations only along axis
- dxBodyDisabled = 4, // body is disabled
- dxBodyNoGravity = 8 // body is not influenced by gravity
-};
-
-
-// base class that does correct object allocation / deallocation
-
-struct dBase {
- void *operator new (size_t size) { return dAlloc (size); }
- void operator delete (void *ptr, size_t size) { dFree (ptr,size); }
- void *operator new[] (size_t size) { return dAlloc (size); }
- void operator delete[] (void *ptr, size_t size) { dFree (ptr,size); }
-};
-
-
-// base class for bodies and joints
-
-struct dObject : public dBase {
- dxWorld *world; // world this object is in
- dObject *next; // next object of this type in list
- dObject **tome; // pointer to previous object's next ptr
- void *userdata; // user settable data
- int tag; // used by dynamics algorithms
-};
-
-
-struct dxBody : public dObject {
- dxJointNode *firstjoint; // list of attached joints
- int flags; // some dxBodyFlagXXX flags
- dMass mass; // mass parameters about POR
- dMatrix3 invI; // inverse of mass.I
- dReal invMass; // 1 / mass.mass
- dVector3 pos; // position of POR (point of reference)
- dQuaternion q; // orientation quaternion
- dMatrix3 R; // rotation matrix, always corresponds to q
- dVector3 lvel,avel; // linear and angular velocity of POR
- dVector3 facc,tacc; // force and torque accululators
- dVector3 finite_rot_axis; // finite rotation axis, unit length or 0=none
-};
-
-
-struct dxWorld : public dBase {
- dxBody *firstbody; // body linked list
- dxJoint *firstjoint; // joint linked list
- int nb,nj; // number of bodies and joints in lists
- dVector3 gravity; // gravity vector (m/s/s)
- dReal global_erp; // global error reduction parameter
- dReal global_cfm; // global costraint force mixing parameter
-};
-
-#endif
-
diff --git a/extern/ode/dist/ode/src/obstack.cpp b/extern/ode/dist/ode/src/obstack.cpp
deleted file mode 100644
index a6b9d36fbb4..00000000000
--- a/extern/ode/dist/ode/src/obstack.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <ode/common.h>
-#include <ode/error.h>
-#include <ode/memory.h>
-#include "obstack.h"
-
-//****************************************************************************
-// macros and constants
-
-#define ROUND_UP_OFFSET_TO_EFFICIENT_SIZE(arena,ofs) \
- ofs = (int) (dEFFICIENT_SIZE( ((intP)(arena)) + ofs ) - ((intP)(arena)) );
-
-#define MAX_ALLOC_SIZE \
- ((int)(dOBSTACK_ARENA_SIZE - sizeof (Arena) - EFFICIENT_ALIGNMENT + 1))
-
-//****************************************************************************
-// dObStack
-
-dObStack::dObStack()
-{
- first = 0;
- last = 0;
- current_arena = 0;
- current_ofs = 0;
-}
-
-
-dObStack::~dObStack()
-{
- // free all arenas
- Arena *a,*nexta;
- a = first;
- while (a) {
- nexta = a->next;
- dFree (a,dOBSTACK_ARENA_SIZE);
- a = nexta;
- }
-}
-
-
-void *dObStack::alloc (int num_bytes)
-{
- if (num_bytes > MAX_ALLOC_SIZE) dDebug (0,"num_bytes too large");
-
- // allocate or move to a new arena if necessary
- if (!first) {
- // allocate the first arena if necessary
- first = last = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE);
- first->next = 0;
- first->used = sizeof (Arena);
- ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used);
- }
- else {
- // we already have one or more arenas, see if a new arena must be used
- if ((last->used + num_bytes) > dOBSTACK_ARENA_SIZE) {
- if (!last->next) {
- last->next = (Arena *) dAlloc (dOBSTACK_ARENA_SIZE);
- last->next->next = 0;
- }
- last = last->next;
- last->used = sizeof (Arena);
- ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used);
- }
- }
-
- // allocate an area in the arena
- char *c = ((char*) last) + last->used;
- last->used += num_bytes;
- ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (last,last->used);
- return c;
-}
-
-
-void dObStack::freeAll()
-{
- last = first;
- if (first) {
- first->used = sizeof(Arena);
- ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (first,first->used);
- }
-}
-
-
-void *dObStack::rewind()
-{
- current_arena = first;
- current_ofs = sizeof (Arena);
- if (current_arena) {
- ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs)
- return ((char*) current_arena) + current_ofs;
- }
- else return 0;
-}
-
-
-void *dObStack::next (int num_bytes)
-{
- // this functions like alloc, except that no new storage is ever allocated
- if (!current_arena) return 0;
- current_ofs += num_bytes;
- ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs);
- if (current_ofs >= current_arena->used) {
- current_arena = current_arena->next;
- if (!current_arena) return 0;
- current_ofs = sizeof (Arena);
- ROUND_UP_OFFSET_TO_EFFICIENT_SIZE (current_arena,current_ofs);
- }
- return ((char*) current_arena) + current_ofs;
-}
diff --git a/extern/ode/dist/ode/src/obstack.h b/extern/ode/dist/ode/src/obstack.h
deleted file mode 100644
index fa7155dd966..00000000000
--- a/extern/ode/dist/ode/src/obstack.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_OBSTACK_H_
-#define _ODE_OBSTACK_H_
-
-#include "objects.h"
-
-// each obstack Arena pointer points to a block of this many bytes
-#define dOBSTACK_ARENA_SIZE 16384
-
-
-struct dObStack : public dBase {
- struct Arena {
- Arena *next; // next arena in linked list
- int used; // total number of bytes used in this arena, counting
- }; // this header
-
- Arena *first; // head of the arena linked list. 0 if no arenas yet
- Arena *last; // arena where blocks are currently being allocated
-
- // used for iterator
- Arena *current_arena;
- int current_ofs;
-
- dObStack();
- ~dObStack();
-
- void *alloc (int num_bytes);
- // allocate a block in the last arena, allocating a new arena if necessary.
- // it is a runtime error if num_bytes is larger than the arena size.
-
- void freeAll();
- // free all blocks in all arenas. this does not deallocate the arenas
- // themselves, so future alloc()s will reuse them.
-
- void *rewind();
- // rewind the obstack iterator, and return the address of the first
- // allocated block. return 0 if there are no allocated blocks.
-
- void *next (int num_bytes);
- // return the address of the next allocated block. 'num_bytes' is the size
- // of the previous block. this returns null if there are no more arenas.
- // the sequence of 'num_bytes' parameters passed to next() during a
- // traversal of the list must exactly match the parameters passed to alloc().
-};
-
-
-#endif
-
diff --git a/extern/ode/dist/ode/src/ode.cpp b/extern/ode/dist/ode/src/ode.cpp
deleted file mode 100644
index 1a14e3292a0..00000000000
--- a/extern/ode/dist/ode/src/ode.cpp
+++ /dev/null
@@ -1,1341 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-// this source file is mostly concerned with the data structures, not the
-// numerics.
-
-#include "objects.h"
-#include <ode/ode.h>
-#include "joint.h"
-#include <ode/odemath.h>
-#include <ode/matrix.h>
-#include "step.h"
-#include <ode/memory.h>
-#include <ode/error.h>
-
-// misc defines
-#define ALLOCA dALLOCA16
-
-//****************************************************************************
-// utility
-
-static inline void initObject (dObject *obj, dxWorld *w)
-{
- obj->world = w;
- obj->next = 0;
- obj->tome = 0;
- obj->userdata = 0;
- obj->tag = 0;
-}
-
-
-// add an object `obj' to the list who's head pointer is pointed to by `first'.
-
-static inline void addObjectToList (dObject *obj, dObject **first)
-{
- obj->next = *first;
- obj->tome = first;
- if (*first) (*first)->tome = &obj->next;
- (*first) = obj;
-}
-
-
-// remove the object from the linked list
-
-static inline void removeObjectFromList (dObject *obj)
-{
- if (obj->next) obj->next->tome = obj->tome;
- *(obj->tome) = obj->next;
- // safeguard
- obj->next = 0;
- obj->tome = 0;
-}
-
-
-// remove the joint from neighbour lists of all connected bodies
-
-static void removeJointReferencesFromAttachedBodies (dxJoint *j)
-{
- for (int i=0; i<2; i++) {
- dxBody *body = j->node[i].body;
- if (body) {
- dxJointNode *n = body->firstjoint;
- dxJointNode *last = 0;
- while (n) {
- if (n->joint == j) {
- if (last) last->next = n->next;
- else body->firstjoint = n->next;
- break;
- }
- last = n;
- n = n->next;
- }
- }
- }
- j->node[0].body = 0;
- j->node[0].next = 0;
- j->node[1].body = 0;
- j->node[1].next = 0;
-}
-
-//****************************************************************************
-// island processing
-
-// this groups all joints and bodies in a world into islands. all objects
-// in an island are reachable by going through connected bodies and joints.
-// each island can be simulated separately.
-// note that joints that are not attached to anything will not be included
-// in any island, an so they do not affect the simulation.
-//
-// this function starts new island from unvisited bodies. however, it will
-// never start a new islands from a disabled body. thus islands of disabled
-// bodies will not be included in the simulation. disabled bodies are
-// re-enabled if they are found to be part of an active island.
-
-static void processIslands (dxWorld *world, dReal stepsize)
-{
- dxBody *b,*bb,**body;
- dxJoint *j,**joint;
-
- // nothing to do if no bodies
- if (world->nb <= 0) return;
-
- // make arrays for body and joint lists (for a single island) to go into
- body = (dxBody**) ALLOCA (world->nb * sizeof(dxBody*));
- joint = (dxJoint**) ALLOCA (world->nj * sizeof(dxJoint*));
- int bcount = 0; // number of bodies in `body'
- int jcount = 0; // number of joints in `joint'
-
- // set all body/joint tags to 0
- for (b=world->firstbody; b; b=(dxBody*)b->next) b->tag = 0;
- for (j=world->firstjoint; j; j=(dxJoint*)j->next) j->tag = 0;
-
- // allocate a stack of unvisited bodies in the island. the maximum size of
- // the stack can be the lesser of the number of bodies or joints, because
- // new bodies are only ever added to the stack by going through untagged
- // joints. all the bodies in the stack must be tagged!
- int stackalloc = (world->nj < world->nb) ? world->nj : world->nb;
- dxBody **stack = (dxBody**) ALLOCA (stackalloc * sizeof(dxBody*));
-
- for (bb=world->firstbody; bb; bb=(dxBody*)bb->next) {
- // get bb = the next enabled, untagged body, and tag it
- if (bb->tag || (bb->flags & dxBodyDisabled)) continue;
- bb->tag = 1;
-
- // tag all bodies and joints starting from bb.
- int stacksize = 0;
- b = bb;
- body[0] = bb;
- bcount = 1;
- jcount = 0;
- goto quickstart;
- while (stacksize > 0) {
- b = stack[--stacksize]; // pop body off stack
- body[bcount++] = b; // put body on body list
- quickstart:
-
- // traverse and tag all body's joints, add untagged connected bodies
- // to stack
- for (dxJointNode *n=b->firstjoint; n; n=n->next) {
- if (!n->joint->tag) {
- n->joint->tag = 1;
- joint[jcount++] = n->joint;
- if (n->body && !n->body->tag) {
- n->body->tag = 1;
- stack[stacksize++] = n->body;
- }
- }
- }
- dIASSERT(stacksize <= world->nb);
- dIASSERT(stacksize <= world->nj);
- }
-
- // now do something with body and joint lists
- dInternalStepIsland (world,body,bcount,joint,jcount,stepsize);
-
- // what we've just done may have altered the body/joint tag values.
- // we must make sure that these tags are nonzero.
- // also make sure all bodies are in the enabled state.
- int i;
- for (i=0; i<bcount; i++) {
- body[i]->tag = 1;
- body[i]->flags &= ~dxBodyDisabled;
- }
- for (i=0; i<jcount; i++) joint[i]->tag = 1;
- }
-
- // if debugging, check that all objects (except for disabled bodies,
- // unconnected joints, and joints that are connected to disabled bodies)
- // were tagged.
-# ifndef dNODEBUG
- for (b=world->firstbody; b; b=(dxBody*)b->next) {
- if (b->flags & dxBodyDisabled) {
- if (b->tag) dDebug (0,"disabled body tagged");
- }
- else {
- if (!b->tag) dDebug (0,"enabled body not tagged");
- }
- }
- for (j=world->firstjoint; j; j=(dxJoint*)j->next) {
- if ((j->node[0].body && (j->node[0].body->flags & dxBodyDisabled)==0) ||
- (j->node[1].body && (j->node[1].body->flags & dxBodyDisabled)==0)) {
- if (!j->tag) dDebug (0,"attached enabled joint not tagged");
- }
- else {
- if (j->tag) dDebug (0,"unattached or disabled joint tagged");
- }
- }
-# endif
-}
-
-//****************************************************************************
-// debugging
-
-// see if an object list loops on itself (if so, it's bad).
-
-static int listHasLoops (dObject *first)
-{
- if (first==0 || first->next==0) return 0;
- dObject *a=first,*b=first->next;
- int skip=0;
- while (b) {
- if (a==b) return 1;
- b = b->next;
- if (skip) a = a->next;
- skip ^= 1;
- }
- return 0;
-}
-
-
-// check the validity of the world data structures
-
-static void checkWorld (dxWorld *w)
-{
- dxBody *b;
- dxJoint *j;
-
- // check there are no loops
- if (listHasLoops (w->firstbody)) dDebug (0,"body list has loops");
- if (listHasLoops (w->firstjoint)) dDebug (0,"joint list has loops");
-
- // check lists are well formed (check `tome' pointers)
- for (b=w->firstbody; b; b=(dxBody*)b->next) {
- if (b->next && b->next->tome != &b->next)
- dDebug (0,"bad tome pointer in body list");
- }
- for (j=w->firstjoint; j; j=(dxJoint*)j->next) {
- if (j->next && j->next->tome != &j->next)
- dDebug (0,"bad tome pointer in joint list");
- }
-
- // check counts
- int n = 0;
- for (b=w->firstbody; b; b=(dxBody*)b->next) n++;
- if (w->nb != n) dDebug (0,"body count incorrect");
- n = 0;
- for (j=w->firstjoint; j; j=(dxJoint*)j->next) n++;
- if (w->nj != n) dDebug (0,"joint count incorrect");
-
- // set all tag values to a known value
- static int count = 0;
- count++;
- for (b=w->firstbody; b; b=(dxBody*)b->next) b->tag = count;
- for (j=w->firstjoint; j; j=(dxJoint*)j->next) j->tag = count;
-
- // check all body/joint world pointers are ok
- for (b=w->firstbody; b; b=(dxBody*)b->next) if (b->world != w)
- dDebug (0,"bad world pointer in body list");
- for (j=w->firstjoint; j; j=(dxJoint*)j->next) if (j->world != w)
- dDebug (0,"bad world pointer in joint list");
-
- /*
- // check for half-connected joints - actually now these are valid
- for (j=w->firstjoint; j; j=(dxJoint*)j->next) {
- if (j->node[0].body || j->node[1].body) {
- if (!(j->node[0].body && j->node[1].body))
- dDebug (0,"half connected joint found");
- }
- }
- */
-
- // check that every joint node appears in the joint lists of both bodies it
- // attaches
- for (j=w->firstjoint; j; j=(dxJoint*)j->next) {
- for (int i=0; i<2; i++) {
- if (j->node[i].body) {
- int ok = 0;
- for (dxJointNode *n=j->node[i].body->firstjoint; n; n=n->next) {
- if (n->joint == j) ok = 1;
- }
- if (ok==0) dDebug (0,"joint not in joint list of attached body");
- }
- }
- }
-
- // check all body joint lists (correct body ptrs)
- for (b=w->firstbody; b; b=(dxBody*)b->next) {
- for (dxJointNode *n=b->firstjoint; n; n=n->next) {
- if (&n->joint->node[0] == n) {
- if (n->joint->node[1].body != b)
- dDebug (0,"bad body pointer in joint node of body list (1)");
- }
- else {
- if (n->joint->node[0].body != b)
- dDebug (0,"bad body pointer in joint node of body list (2)");
- }
- if (n->joint->tag != count) dDebug (0,"bad joint node pointer in body");
- }
- }
-
- // check all body pointers in joints, check they are distinct
- for (j=w->firstjoint; j; j=(dxJoint*)j->next) {
- if (j->node[0].body && (j->node[0].body == j->node[1].body))
- dDebug (0,"non-distinct body pointers in joint");
- if ((j->node[0].body && j->node[0].body->tag != count) ||
- (j->node[1].body && j->node[1].body->tag != count))
- dDebug (0,"bad body pointer in joint");
- }
-}
-
-
-void dWorldCheck (dxWorld *w)
-{
- checkWorld (w);
-}
-
-//****************************************************************************
-// body
-
-dxBody *dBodyCreate (dxWorld *w)
-{
- dAASSERT (w);
- dxBody *b = new dxBody;
- initObject (b,w);
- b->firstjoint = 0;
- b->flags = 0;
- dMassSetParameters (&b->mass,1,0,0,0,1,1,1,0,0,0);
- dSetZero (b->invI,4*3);
- b->invI[0] = 1;
- b->invI[5] = 1;
- b->invI[10] = 1;
- b->invMass = 1;
- dSetZero (b->pos,4);
- dSetZero (b->q,4);
- b->q[0] = 1;
- dRSetIdentity (b->R);
- dSetZero (b->lvel,4);
- dSetZero (b->avel,4);
- dSetZero (b->facc,4);
- dSetZero (b->tacc,4);
- dSetZero (b->finite_rot_axis,4);
- addObjectToList (b,(dObject **) &w->firstbody);
- w->nb++;
- return b;
-}
-
-
-void dBodyDestroy (dxBody *b)
-{
- dAASSERT (b);
-
- // detach all neighbouring joints, then delete this body.
- dxJointNode *n = b->firstjoint;
- while (n) {
- // sneaky trick to speed up removal of joint references (black magic)
- n->joint->node[(n == n->joint->node)].body = 0;
-
- dxJointNode *next = n->next;
- n->next = 0;
- removeJointReferencesFromAttachedBodies (n->joint);
- n = next;
- }
- removeObjectFromList (b);
- b->world->nb--;
- delete b;
-}
-
-
-void dBodySetData (dBodyID b, void *data)
-{
- dAASSERT (b);
- b->userdata = data;
-}
-
-
-void *dBodyGetData (dBodyID b)
-{
- dAASSERT (b);
- return b->userdata;
-}
-
-
-void dBodySetPosition (dBodyID b, dReal x, dReal y, dReal z)
-{
- dAASSERT (b);
- b->pos[0] = x;
- b->pos[1] = y;
- b->pos[2] = z;
-}
-
-
-void dBodySetRotation (dBodyID b, const dMatrix3 R)
-{
- dAASSERT (b && R);
- dQuaternion q;
- dRtoQ (R,q);
- dNormalize4 (q);
- b->q[0] = q[0];
- b->q[1] = q[1];
- b->q[2] = q[2];
- b->q[3] = q[3];
- dQtoR (b->q,b->R);
-}
-
-
-void dBodySetQuaternion (dBodyID b, const dQuaternion q)
-{
- dAASSERT (b && q);
- b->q[0] = q[0];
- b->q[1] = q[1];
- b->q[2] = q[2];
- b->q[3] = q[3];
- dNormalize4 (b->q);
- dQtoR (b->q,b->R);
-}
-
-
-void dBodySetLinearVel (dBodyID b, dReal x, dReal y, dReal z)
-{
- dAASSERT (b);
- b->lvel[0] = x;
- b->lvel[1] = y;
- b->lvel[2] = z;
-}
-
-
-void dBodySetAngularVel (dBodyID b, dReal x, dReal y, dReal z)
-{
- dAASSERT (b);
- b->avel[0] = x;
- b->avel[1] = y;
- b->avel[2] = z;
-}
-
-
-const dReal * dBodyGetPosition (dBodyID b)
-{
- dAASSERT (b);
- return b->pos;
-}
-
-
-const dReal * dBodyGetRotation (dBodyID b)
-{
- dAASSERT (b);
- return b->R;
-}
-
-
-const dReal * dBodyGetQuaternion (dBodyID b)
-{
- dAASSERT (b);
- return b->q;
-}
-
-
-const dReal * dBodyGetLinearVel (dBodyID b)
-{
- dAASSERT (b);
- return b->lvel;
-}
-
-
-const dReal * dBodyGetAngularVel (dBodyID b)
-{
- dAASSERT (b);
- return b->avel;
-}
-
-
-void dBodySetMass (dBodyID b, const dMass *mass)
-{
- dAASSERT (b && mass);
- memcpy (&b->mass,mass,sizeof(dMass));
- if (dInvertPDMatrix (b->mass.I,b->invI,3)==0) {
- dDEBUGMSG ("inertia must be positive definite");
- dRSetIdentity (b->invI);
- }
- b->invMass = dRecip(b->mass.mass);
-}
-
-
-void dBodyGetMass (dBodyID b, dMass *mass)
-{
- dAASSERT (b && mass);
- memcpy (mass,&b->mass,sizeof(dMass));
-}
-
-
-void dBodyAddForce (dBodyID b, dReal fx, dReal fy, dReal fz)
-{
- dAASSERT (b);
- b->facc[0] += fx;
- b->facc[1] += fy;
- b->facc[2] += fz;
-}
-
-
-void dBodyAddTorque (dBodyID b, dReal fx, dReal fy, dReal fz)
-{
- dAASSERT (b);
- b->tacc[0] += fx;
- b->tacc[1] += fy;
- b->tacc[2] += fz;
-}
-
-
-void dBodyAddRelForce (dBodyID b, dReal fx, dReal fy, dReal fz)
-{
- dAASSERT (b);
- dVector3 t1,t2;
- t1[0] = fx;
- t1[1] = fy;
- t1[2] = fz;
- t1[3] = 0;
- dMULTIPLY0_331 (t2,b->R,t1);
- b->facc[0] += t2[0];
- b->facc[1] += t2[1];
- b->facc[2] += t2[2];
-}
-
-
-void dBodyAddRelTorque (dBodyID b, dReal fx, dReal fy, dReal fz)
-{
- dAASSERT (b);
- dVector3 t1,t2;
- t1[0] = fx;
- t1[1] = fy;
- t1[2] = fz;
- t1[3] = 0;
- dMULTIPLY0_331 (t2,b->R,t1);
- b->tacc[0] += t2[0];
- b->tacc[1] += t2[1];
- b->tacc[2] += t2[2];
-}
-
-
-void dBodyAddForceAtPos (dBodyID b, dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
-{
- dAASSERT (b);
- b->facc[0] += fx;
- b->facc[1] += fy;
- b->facc[2] += fz;
- dVector3 f,q;
- f[0] = fx;
- f[1] = fy;
- f[2] = fz;
- q[0] = px - b->pos[0];
- q[1] = py - b->pos[1];
- q[2] = pz - b->pos[2];
- dCROSS (b->tacc,+=,q,f);
-}
-
-
-void dBodyAddForceAtRelPos (dBodyID b, dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
-{
- dAASSERT (b);
- dVector3 prel,f,p;
- f[0] = fx;
- f[1] = fy;
- f[2] = fz;
- f[3] = 0;
- prel[0] = px;
- prel[1] = py;
- prel[2] = pz;
- prel[3] = 0;
- dMULTIPLY0_331 (p,b->R,prel);
- b->facc[0] += f[0];
- b->facc[1] += f[1];
- b->facc[2] += f[2];
- dCROSS (b->tacc,+=,p,f);
-}
-
-
-void dBodyAddRelForceAtPos (dBodyID b, dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
-{
- dAASSERT (b);
- dVector3 frel,f;
- frel[0] = fx;
- frel[1] = fy;
- frel[2] = fz;
- frel[3] = 0;
- dMULTIPLY0_331 (f,b->R,frel);
- b->facc[0] += f[0];
- b->facc[1] += f[1];
- b->facc[2] += f[2];
- dVector3 q;
- q[0] = px - b->pos[0];
- q[1] = py - b->pos[1];
- q[2] = pz - b->pos[2];
- dCROSS (b->tacc,+=,q,f);
-}
-
-
-void dBodyAddRelForceAtRelPos (dBodyID b, dReal fx, dReal fy, dReal fz,
- dReal px, dReal py, dReal pz)
-{
- dAASSERT (b);
- dVector3 frel,prel,f,p;
- frel[0] = fx;
- frel[1] = fy;
- frel[2] = fz;
- frel[3] = 0;
- prel[0] = px;
- prel[1] = py;
- prel[2] = pz;
- prel[3] = 0;
- dMULTIPLY0_331 (f,b->R,frel);
- dMULTIPLY0_331 (p,b->R,prel);
- b->facc[0] += f[0];
- b->facc[1] += f[1];
- b->facc[2] += f[2];
- dCROSS (b->tacc,+=,p,f);
-}
-
-
-const dReal * dBodyGetForce (dBodyID b)
-{
- dAASSERT (b);
- return b->facc;
-}
-
-
-const dReal * dBodyGetTorque (dBodyID b)
-{
- dAASSERT (b);
- return b->tacc;
-}
-
-
-void dBodySetForce (dBodyID b, dReal x, dReal y, dReal z)
-{
- dAASSERT (b);
- b->facc[0] = x;
- b->facc[1] = y;
- b->facc[2] = z;
-}
-
-
-void dBodySetTorque (dBodyID b, dReal x, dReal y, dReal z)
-{
- dAASSERT (b);
- b->tacc[0] = x;
- b->tacc[1] = y;
- b->tacc[2] = z;
-}
-
-
-void dBodyGetRelPointPos (dBodyID b, dReal px, dReal py, dReal pz,
- dVector3 result)
-{
- dAASSERT (b);
- dVector3 prel,p;
- prel[0] = px;
- prel[1] = py;
- prel[2] = pz;
- prel[3] = 0;
- dMULTIPLY0_331 (p,b->R,prel);
- result[0] = p[0] + b->pos[0];
- result[1] = p[1] + b->pos[1];
- result[2] = p[2] + b->pos[2];
-}
-
-
-void dBodyGetRelPointVel (dBodyID b, dReal px, dReal py, dReal pz,
- dVector3 result)
-{
- dAASSERT (b);
- dVector3 prel,p;
- prel[0] = px;
- prel[1] = py;
- prel[2] = pz;
- prel[3] = 0;
- dMULTIPLY0_331 (p,b->R,prel);
- result[0] = b->lvel[0];
- result[1] = b->lvel[1];
- result[2] = b->lvel[2];
- dCROSS (result,+=,b->avel,p);
-}
-
-
-void dBodyGetPointVel (dBodyID b, dReal px, dReal py, dReal pz,
- dVector3 result)
-{
- dAASSERT (b);
- dVector3 p;
- p[0] = px - b->pos[0];
- p[1] = py - b->pos[1];
- p[2] = pz - b->pos[2];
- p[3] = 0;
- result[0] = b->lvel[0];
- result[1] = b->lvel[1];
- result[2] = b->lvel[2];
- dCROSS (result,+=,b->avel,p);
-}
-
-
-void dBodyGetPosRelPoint (dBodyID b, dReal px, dReal py, dReal pz,
- dVector3 result)
-{
- dAASSERT (b);
- dVector3 prel;
- prel[0] = px - b->pos[0];
- prel[1] = py - b->pos[1];
- prel[2] = pz - b->pos[2];
- prel[3] = 0;
- dMULTIPLY1_331 (result,b->R,prel);
-}
-
-
-void dBodyVectorToWorld (dBodyID b, dReal px, dReal py, dReal pz,
- dVector3 result)
-{
- dAASSERT (b);
- dVector3 p;
- p[0] = px;
- p[1] = py;
- p[2] = pz;
- p[3] = 0;
- dMULTIPLY0_331 (result,b->R,p);
-}
-
-
-void dBodyVectorFromWorld (dBodyID b, dReal px, dReal py, dReal pz,
- dVector3 result)
-{
- dAASSERT (b);
- dVector3 p;
- p[0] = px;
- p[1] = py;
- p[2] = pz;
- p[3] = 0;
- dMULTIPLY1_331 (result,b->R,p);
-}
-
-
-void dBodySetFiniteRotationMode (dBodyID b, int mode)
-{
- dAASSERT (b);
- b->flags &= ~(dxBodyFlagFiniteRotation | dxBodyFlagFiniteRotationAxis);
- if (mode) {
- b->flags |= dxBodyFlagFiniteRotation;
- if (b->finite_rot_axis[0] != 0 || b->finite_rot_axis[1] != 0 ||
- b->finite_rot_axis[2] != 0) {
- b->flags |= dxBodyFlagFiniteRotationAxis;
- }
- }
-}
-
-
-void dBodySetFiniteRotationAxis (dBodyID b, dReal x, dReal y, dReal z)
-{
- dAASSERT (b);
- b->finite_rot_axis[0] = x;
- b->finite_rot_axis[1] = y;
- b->finite_rot_axis[2] = z;
- if (x != 0 || y != 0 || z != 0) {
- dNormalize3 (b->finite_rot_axis);
- b->flags |= dxBodyFlagFiniteRotationAxis;
- }
- else {
- b->flags &= ~dxBodyFlagFiniteRotationAxis;
- }
-}
-
-
-int dBodyGetFiniteRotationMode (dBodyID b)
-{
- dAASSERT (b);
- return ((b->flags & dxBodyFlagFiniteRotation) != 0);
-}
-
-
-void dBodyGetFiniteRotationAxis (dBodyID b, dVector3 result)
-{
- dAASSERT (b);
- result[0] = b->finite_rot_axis[0];
- result[1] = b->finite_rot_axis[1];
- result[2] = b->finite_rot_axis[2];
-}
-
-
-int dBodyGetNumJoints (dBodyID b)
-{
- dAASSERT (b);
- int count=0;
- for (dxJointNode *n=b->firstjoint; n; n=n->next, count++);
- return count;
-}
-
-
-dJointID dBodyGetJoint (dBodyID b, int index)
-{
- dAASSERT (b);
- int i=0;
- for (dxJointNode *n=b->firstjoint; n; n=n->next, i++) {
- if (i == index) return n->joint;
- }
- return 0;
-}
-
-
-void dBodyEnable (dBodyID b)
-{
- dAASSERT (b);
- b->flags &= ~dxBodyDisabled;
-}
-
-
-void dBodyDisable (dBodyID b)
-{
- dAASSERT (b);
- b->flags |= dxBodyDisabled;
-}
-
-
-int dBodyIsEnabled (dBodyID b)
-{
- dAASSERT (b);
- return ((b->flags & dxBodyDisabled) == 0);
-}
-
-
-void dBodySetGravityMode (dBodyID b, int mode)
-{
- dAASSERT (b);
- if (mode) b->flags &= ~dxBodyNoGravity;
- else b->flags |= dxBodyNoGravity;
-}
-
-
-int dBodyGetGravityMode (dBodyID b)
-{
- dAASSERT (b);
- return ((b->flags & dxBodyNoGravity) == 0);
-}
-
-//****************************************************************************
-// joints
-
-static void dJointInit (dxWorld *w, dxJoint *j)
-{
- dIASSERT (w && j);
- initObject (j,w);
- j->vtable = 0;
- j->flags = 0;
- j->node[0].joint = j;
- j->node[0].body = 0;
- j->node[0].next = 0;
- j->node[1].joint = j;
- j->node[1].body = 0;
- j->node[1].next = 0;
- addObjectToList (j,(dObject **) &w->firstjoint);
- w->nj++;
-}
-
-
-static dxJoint *createJoint (dWorldID w, dJointGroupID group,
- dxJoint::Vtable *vtable)
-{
- dIASSERT (w && vtable);
- dxJoint *j;
- if (group) {
- j = (dxJoint*) group->stack.alloc (vtable->size);
- group->num++;
- }
- else j = (dxJoint*) dAlloc (vtable->size);
- dJointInit (w,j);
- j->vtable = vtable;
- if (group) j->flags |= dJOINT_INGROUP;
- if (vtable->init) vtable->init (j);
- j->feedback = 0;
- return j;
-}
-
-
-dxJoint * dJointCreateBall (dWorldID w, dJointGroupID group)
-{
- dAASSERT (w);
- return createJoint (w,group,&__dball_vtable);
-}
-
-
-dxJoint * dJointCreateHinge (dWorldID w, dJointGroupID group)
-{
- dAASSERT (w);
- return createJoint (w,group,&__dhinge_vtable);
-}
-
-
-dxJoint * dJointCreateSlider (dWorldID w, dJointGroupID group)
-{
- dAASSERT (w);
- return createJoint (w,group,&__dslider_vtable);
-}
-
-
-dxJoint * dJointCreateContact (dWorldID w, dJointGroupID group,
- const dContact *c)
-{
- dAASSERT (w && c);
- dxJointContact *j = (dxJointContact *)
- createJoint (w,group,&__dcontact_vtable);
- j->contact = *c;
- return j;
-}
-
-
-dxJoint * dJointCreateHinge2 (dWorldID w, dJointGroupID group)
-{
- dAASSERT (w);
- return createJoint (w,group,&__dhinge2_vtable);
-}
-
-
-dxJoint * dJointCreateUniversal (dWorldID w, dJointGroupID group)
-{
- dAASSERT (w);
- return createJoint (w,group,&__duniversal_vtable);
-}
-
-
-dxJoint * dJointCreateFixed (dWorldID w, dJointGroupID group)
-{
- dAASSERT (w);
- return createJoint (w,group,&__dfixed_vtable);
-}
-
-
-dxJoint * dJointCreateNull (dWorldID w, dJointGroupID group)
-{
- dAASSERT (w);
- return createJoint (w,group,&__dnull_vtable);
-}
-
-
-dxJoint * dJointCreateAMotor (dWorldID w, dJointGroupID group)
-{
- dAASSERT (w);
- return createJoint (w,group,&__damotor_vtable);
-}
-
-
-void dJointDestroy (dxJoint *j)
-{
- dAASSERT (j);
- if (j->flags & dJOINT_INGROUP) return;
- removeJointReferencesFromAttachedBodies (j);
- removeObjectFromList (j);
- j->world->nj--;
- dFree (j,j->vtable->size);
-}
-
-
-dJointGroupID dJointGroupCreate (int max_size)
-{
- // not any more ... dUASSERT (max_size > 0,"max size must be > 0");
- dxJointGroup *group = new dxJointGroup;
- group->num = 0;
- return group;
-}
-
-
-void dJointGroupDestroy (dJointGroupID group)
-{
- dAASSERT (group);
- dJointGroupEmpty (group);
- delete group;
-}
-
-
-void dJointGroupEmpty (dJointGroupID group)
-{
- // the joints in this group are detached starting from the most recently
- // added (at the top of the stack). this helps ensure that the various
- // linked lists are not traversed too much, as the joints will hopefully
- // be at the start of those lists.
- // if any group joints have their world pointer set to 0, their world was
- // previously destroyed. no special handling is required for these joints.
-
- dAASSERT (group);
- int i;
- dxJoint **jlist = (dxJoint**) ALLOCA (group->num * sizeof(dxJoint*));
- dxJoint *j = (dxJoint*) group->stack.rewind();
- for (i=0; i < group->num; i++) {
- jlist[i] = j;
- j = (dxJoint*) (group->stack.next (j->vtable->size));
- }
- for (i=group->num-1; i >= 0; i--) {
- if (jlist[i]->world) {
- removeJointReferencesFromAttachedBodies (jlist[i]);
- removeObjectFromList (jlist[i]);
- jlist[i]->world->nj--;
- }
- }
- group->num = 0;
- group->stack.freeAll();
-}
-
-
-void dJointAttach (dxJoint *joint, dxBody *body1, dxBody *body2)
-{
- // check arguments
- dUASSERT (joint,"bad joint argument");
- dUASSERT (body1 == 0 || body1 != body2,"can't have body1==body2");
- dxWorld *world = joint->world;
- dUASSERT ( (!body1 || body1->world == world) &&
- (!body2 || body2->world == world),
- "joint and bodies must be in same world");
-
- // check if the joint can not be attached to just one body
- dUASSERT (!((joint->flags & dJOINT_TWOBODIES) &&
- ((body1 != 0) ^ (body2 != 0))),
- "joint can not be attached to just one body");
-
- // remove any existing body attachments
- if (joint->node[0].body || joint->node[1].body) {
- removeJointReferencesFromAttachedBodies (joint);
- }
-
- // if a body is zero, make sure that it is body2, so 0 --> node[1].body
- if (body1==0) {
- body1 = body2;
- body2 = 0;
- joint->flags &= (~dJOINT_REVERSE);
- }
- else {
- joint->flags |= dJOINT_REVERSE;
- }
-
- // attach to new bodies
- joint->node[0].body = body1;
- joint->node[1].body = body2;
- if (body1) {
- joint->node[1].next = body1->firstjoint;
- body1->firstjoint = &joint->node[1];
- }
- else joint->node[1].next = 0;
- if (body2) {
- joint->node[0].next = body2->firstjoint;
- body2->firstjoint = &joint->node[0];
- }
- else {
- joint->node[0].next = 0;
- }
-}
-
-
-void dJointSetData (dxJoint *joint, void *data)
-{
- dAASSERT (joint);
- joint->userdata = data;
-}
-
-
-void *dJointGetData (dxJoint *joint)
-{
- dAASSERT (joint);
- return joint->userdata;
-}
-
-
-int dJointGetType (dxJoint *joint)
-{
- dAASSERT (joint);
- return joint->vtable->typenum;
-}
-
-
-dBodyID dJointGetBody (dxJoint *joint, int index)
-{
- dAASSERT (joint);
- if (index >= 0 && index < 2) return joint->node[index].body;
- else return 0;
-}
-
-
-void dJointSetFeedback (dxJoint *joint, dJointFeedback *f)
-{
- dAASSERT (joint);
- joint->feedback = f;
-}
-
-
-dJointFeedback *dJointGetFeedback (dxJoint *joint)
-{
- dAASSERT (joint);
- return joint->feedback;
-}
-
-
-int dAreConnected (dBodyID b1, dBodyID b2)
-{
- dAASSERT (b1 && b2);
- // look through b1's neighbour list for b2
- for (dxJointNode *n=b1->firstjoint; n; n=n->next) {
- if (n->body == b2) return 1;
- }
- return 0;
-}
-
-//****************************************************************************
-// world
-
-dxWorld * dWorldCreate()
-{
- dxWorld *w = new dxWorld;
- w->firstbody = 0;
- w->firstjoint = 0;
- w->nb = 0;
- w->nj = 0;
- dSetZero (w->gravity,4);
- w->global_erp = REAL(0.2);
-#if defined(dSINGLE)
- w->global_cfm = 1e-5f;
-#elif defined(dDOUBLE)
- w->global_cfm = 1e-10;
-#else
- #error dSINGLE or dDOUBLE must be defined
-#endif
- return w;
-}
-
-
-void dWorldDestroy (dxWorld *w)
-{
- // delete all bodies and joints
- dAASSERT (w);
- dxBody *nextb, *b = w->firstbody;
- while (b) {
- nextb = (dxBody*) b->next;
- delete b;
- b = nextb;
- }
- dxJoint *nextj, *j = w->firstjoint;
- while (j) {
- nextj = (dxJoint*)j->next;
- if (j->flags & dJOINT_INGROUP) {
- // the joint is part of a group, so "deactivate" it instead
- j->world = 0;
- j->node[0].body = 0;
- j->node[0].next = 0;
- j->node[1].body = 0;
- j->node[1].next = 0;
- dMessage (0,"warning: destroying world containing grouped joints");
- }
- else {
- dFree (j,j->vtable->size);
- }
- j = nextj;
- }
- delete w;
-}
-
-
-void dWorldSetGravity (dWorldID w, dReal x, dReal y, dReal z)
-{
- dAASSERT (w);
- w->gravity[0] = x;
- w->gravity[1] = y;
- w->gravity[2] = z;
-}
-
-
-void dWorldGetGravity (dWorldID w, dVector3 g)
-{
- dAASSERT (w);
- g[0] = w->gravity[0];
- g[1] = w->gravity[1];
- g[2] = w->gravity[2];
-}
-
-
-void dWorldSetERP (dWorldID w, dReal erp)
-{
- dAASSERT (w);
- w->global_erp = erp;
-}
-
-
-dReal dWorldGetERP (dWorldID w)
-{
- dAASSERT (w);
- return w->global_erp;
-}
-
-
-void dWorldSetCFM (dWorldID w, dReal cfm)
-{
- dAASSERT (w);
- w->global_cfm = cfm;
-}
-
-
-dReal dWorldGetCFM (dWorldID w)
-{
- dAASSERT (w);
- return w->global_cfm;
-}
-
-
-void dWorldStep (dWorldID w, dReal stepsize)
-{
- dUASSERT (w,"bad world argument");
- dUASSERT (stepsize > 0,"stepsize must be > 0");
- processIslands (w,stepsize);
-}
-
-
-void dWorldImpulseToForce (dWorldID w, dReal stepsize,
- dReal ix, dReal iy, dReal iz,
- dVector3 force)
-{
- dAASSERT (w);
- stepsize = dRecip(stepsize);
- force[0] = stepsize * ix;
- force[1] = stepsize * iy;
- force[2] = stepsize * iz;
- // @@@ force[3] = 0;
-}
-
-//****************************************************************************
-// testing
-
-#define NUM 100
-
-#define DO(x)
-
-
-extern "C" void dTestDataStructures()
-{
- int i;
- DO(printf ("testDynamicsStuff()\n"));
-
- dBodyID body [NUM];
- int nb = 0;
- dJointID joint [NUM];
- int nj = 0;
-
- for (i=0; i<NUM; i++) body[i] = 0;
- for (i=0; i<NUM; i++) joint[i] = 0;
-
- DO(printf ("creating world\n"));
- dWorldID w = dWorldCreate();
- checkWorld (w);
-
- for (;;) {
- if (nb < NUM && dRandReal() > 0.5) {
- DO(printf ("creating body\n"));
- body[nb] = dBodyCreate (w);
- DO(printf ("\t--> %p\n",body[nb]));
- nb++;
- checkWorld (w);
- DO(printf ("%d BODIES, %d JOINTS\n",nb,nj));
- }
- if (nj < NUM && nb > 2 && dRandReal() > 0.5) {
- dBodyID b1 = body [dRand() % nb];
- dBodyID b2 = body [dRand() % nb];
- if (b1 != b2) {
- DO(printf ("creating joint, attaching to %p,%p\n",b1,b2));
- joint[nj] = dJointCreateBall (w,0);
- DO(printf ("\t-->%p\n",joint[nj]));
- checkWorld (w);
- dJointAttach (joint[nj],b1,b2);
- nj++;
- checkWorld (w);
- DO(printf ("%d BODIES, %d JOINTS\n",nb,nj));
- }
- }
- if (nj > 0 && nb > 2 && dRandReal() > 0.5) {
- dBodyID b1 = body [dRand() % nb];
- dBodyID b2 = body [dRand() % nb];
- if (b1 != b2) {
- int k = dRand() % nj;
- DO(printf ("reattaching joint %p\n",joint[k]));
- dJointAttach (joint[k],b1,b2);
- checkWorld (w);
- DO(printf ("%d BODIES, %d JOINTS\n",nb,nj));
- }
- }
- if (nb > 0 && dRandReal() > 0.5) {
- int k = dRand() % nb;
- DO(printf ("destroying body %p\n",body[k]));
- dBodyDestroy (body[k]);
- checkWorld (w);
- for (; k < (NUM-1); k++) body[k] = body[k+1];
- nb--;
- DO(printf ("%d BODIES, %d JOINTS\n",nb,nj));
- }
- if (nj > 0 && dRandReal() > 0.5) {
- int k = dRand() % nj;
- DO(printf ("destroying joint %p\n",joint[k]));
- dJointDestroy (joint[k]);
- checkWorld (w);
- for (; k < (NUM-1); k++) joint[k] = joint[k+1];
- nj--;
- DO(printf ("%d BODIES, %d JOINTS\n",nb,nj));
- }
- }
-
- /*
- printf ("creating world\n");
- dWorldID w = dWorldCreate();
- checkWorld (w);
- printf ("creating body\n");
- dBodyID b1 = dBodyCreate (w);
- checkWorld (w);
- printf ("creating body\n");
- dBodyID b2 = dBodyCreate (w);
- checkWorld (w);
- printf ("creating joint\n");
- dJointID j = dJointCreateBall (w);
- checkWorld (w);
- printf ("attaching joint\n");
- dJointAttach (j,b1,b2);
- checkWorld (w);
- printf ("destroying joint\n");
- dJointDestroy (j);
- checkWorld (w);
- printf ("destroying body\n");
- dBodyDestroy (b1);
- checkWorld (w);
- printf ("destroying body\n");
- dBodyDestroy (b2);
- checkWorld (w);
- printf ("destroying world\n");
- dWorldDestroy (w);
- */
-}
diff --git a/extern/ode/dist/ode/src/odemath.cpp b/extern/ode/dist/ode/src/odemath.cpp
deleted file mode 100644
index cd6dbc855fe..00000000000
--- a/extern/ode/dist/ode/src/odemath.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#define SHARED_CONFIG_H_INCLUDED_FROM_DEFINING_FILE 1
-#include <ode/common.h>
-#include <ode/odemath.h>
-
-
-// get some math functions under windows
-#ifdef WIN32
-#include <float.h>
-#ifndef CYGWIN // added by andy for cygwin
-#define copysign(a,b) ((dReal)_copysign(a,b))
-#endif // added by andy for cygwin
-#endif
-
-
-// infinity declaration
-
-#ifdef DINFINITY_DECL
-DINFINITY_DECL
-#endif
-
-
-// this may be called for vectors `a' with extremely small magnitude, for
-// example the result of a cross product on two nearly perpendicular vectors.
-// we must be robust to these small vectors. to prevent numerical error,
-// first find the component a[i] with the largest magnitude and then scale
-// all the components by 1/a[i]. then we can compute the length of `a' and
-// scale the components by 1/l. this has been verified to work with vectors
-// containing the smallest representable numbers.
-
-void dNormalize3 (dVector3 a)
-{
- dReal a0,a1,a2,aa0,aa1,aa2,l;
- dAASSERT (a);
- a0 = a[0];
- a1 = a[1];
- a2 = a[2];
- aa0 = dFabs(a0);
- aa1 = dFabs(a1);
- aa2 = dFabs(a2);
- if (aa1 > aa0) {
- if (aa2 > aa1) {
- goto aa2_largest;
- }
- else { // aa1 is largest
- a0 /= aa1;
- a2 /= aa1;
- l = dRecipSqrt (a0*a0 + a2*a2 + 1);
- a[0] = a0*l;
- a[1] = copysign(l,a1);
- a[2] = a2*l;
- }
- }
- else {
- if (aa2 > aa0) {
- aa2_largest: // aa2 is largest
- a0 /= aa2;
- a1 /= aa2;
- l = dRecipSqrt (a0*a0 + a1*a1 + 1);
- a[0] = a0*l;
- a[1] = a1*l;
- a[2] = copysign(l,a2);
- }
- else { // aa0 is largest
- if (aa0 <= 0) {
- dDEBUGMSG ("vector has zero size");
- a[0] = 1; // if all a's are zero, this is where we'll end up.
- a[1] = 0; // return a default unit length vector.
- a[2] = 0;
- return;
- }
- a1 /= aa0;
- a2 /= aa0;
- l = dRecipSqrt (a1*a1 + a2*a2 + 1);
- a[0] = copysign(l,a0);
- a[1] = a1*l;
- a[2] = a2*l;
- }
- }
-}
-
-
-/* OLD VERSION */
-/*
-void dNormalize3 (dVector3 a)
-{
- dASSERT (a);
- dReal l = dDOT(a,a);
- if (l > 0) {
- l = dRecipSqrt(l);
- a[0] *= l;
- a[1] *= l;
- a[2] *= l;
- }
- else {
- a[0] = 1;
- a[1] = 0;
- a[2] = 0;
- }
-}
-*/
-
-
-void dNormalize4 (dVector4 a)
-{
- dAASSERT (a);
- dReal l = dDOT(a,a)+a[3]*a[3];
- if (l > 0) {
- l = dRecipSqrt(l);
- a[0] *= l;
- a[1] *= l;
- a[2] *= l;
- a[3] *= l;
- }
- else {
- dDEBUGMSG ("vector has zero size");
- a[0] = 1;
- a[1] = 0;
- a[2] = 0;
- a[3] = 0;
- }
-}
-
-
-void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q)
-{
- dAASSERT (n && p && q);
- if (dFabs(n[2]) > M_SQRT1_2) {
- // choose p in y-z plane
- dReal a = n[1]*n[1] + n[2]*n[2];
- dReal k = dRecipSqrt (a);
- p[0] = 0;
- p[1] = -n[2]*k;
- p[2] = n[1]*k;
- // set q = n x p
- q[0] = a*k;
- q[1] = -n[0]*p[2];
- q[2] = n[0]*p[1];
- }
- else {
- // choose p in x-y plane
- dReal a = n[0]*n[0] + n[1]*n[1];
- dReal k = dRecipSqrt (a);
- p[0] = -n[1]*k;
- p[1] = n[0]*k;
- p[2] = 0;
- // set q = n x p
- q[0] = -n[2]*p[1];
- q[1] = n[2]*p[0];
- q[2] = a*k;
- }
-}
diff --git a/extern/ode/dist/ode/src/rotation.cpp b/extern/ode/dist/ode/src/rotation.cpp
deleted file mode 100644
index 22b9fb13820..00000000000
--- a/extern/ode/dist/ode/src/rotation.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/*
-
-quaternions have the format: (s,vx,vy,vz) where (vx,vy,vz) is the
-"rotation axis" and s is the "rotation angle".
-
-*/
-
-#include <ode/rotation.h>
-
-
-#define _R(i,j) R[(i)*4+(j)]
-
-#define SET_3x3_IDENTITY \
- _R(0,0) = REAL(1.0); \
- _R(0,1) = REAL(0.0); \
- _R(0,2) = REAL(0.0); \
- _R(0,3) = REAL(0.0); \
- _R(1,0) = REAL(0.0); \
- _R(1,1) = REAL(1.0); \
- _R(1,2) = REAL(0.0); \
- _R(1,3) = REAL(0.0); \
- _R(2,0) = REAL(0.0); \
- _R(2,1) = REAL(0.0); \
- _R(2,2) = REAL(1.0); \
- _R(2,3) = REAL(0.0);
-
-
-void dRSetIdentity (dMatrix3 R)
-{
- dAASSERT (R);
- SET_3x3_IDENTITY;
-}
-
-
-void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,
- dReal angle)
-{
- dAASSERT (R);
- dQuaternion q;
- dQFromAxisAndAngle (q,ax,ay,az,angle);
- dQtoR (q,R);
-}
-
-
-void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi)
-{
- dReal sphi,cphi,stheta,ctheta,spsi,cpsi;
- dAASSERT (R);
- sphi = dSin(phi);
- cphi = dCos(phi);
- stheta = dSin(theta);
- ctheta = dCos(theta);
- spsi = dSin(psi);
- cpsi = dCos(psi);
- _R(0,0) = cpsi*ctheta;
- _R(0,1) = spsi*ctheta;
- _R(0,2) =-stheta;
- _R(1,0) = cpsi*stheta*sphi - spsi*cphi;
- _R(1,1) = spsi*stheta*sphi + cpsi*cphi;
- _R(1,2) = ctheta*sphi;
- _R(2,0) = cpsi*stheta*cphi + spsi*sphi;
- _R(2,1) = spsi*stheta*cphi - cpsi*sphi;
- _R(2,2) = ctheta*cphi;
-}
-
-
-void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az,
- dReal bx, dReal by, dReal bz)
-{
- dReal l,k;
- dAASSERT (R);
- l = dSqrt (ax*ax + ay*ay + az*az);
- if (l <= REAL(0.0)) {
- dDEBUGMSG ("zero length vector");
- return;
- }
- l = dRecip(l);
- ax *= l;
- ay *= l;
- az *= l;
- k = ax*bx + ay*by + az*bz;
- bx -= k*ax;
- by -= k*ay;
- bz -= k*az;
- l = dSqrt (bx*bx + by*by + bz*bz);
- if (l <= REAL(0.0)) {
- dDEBUGMSG ("zero length vector");
- return;
- }
- l = dRecip(l);
- bx *= l;
- by *= l;
- bz *= l;
- _R(0,0) = ax;
- _R(1,0) = ay;
- _R(2,0) = az;
- _R(0,1) = bx;
- _R(1,1) = by;
- _R(2,1) = bz;
- _R(0,2) = - by*az + ay*bz;
- _R(1,2) = - bz*ax + az*bx;
- _R(2,2) = - bx*ay + ax*by;
-}
-
-
-void dQSetIdentity (dQuaternion q)
-{
- dAASSERT (q);
- q[0] = 1;
- q[1] = 0;
- q[2] = 0;
- q[3] = 0;
-}
-
-
-void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az,
- dReal angle)
-{
- dAASSERT (q);
- dReal l = ax*ax + ay*ay + az*az;
- if (l > REAL(0.0)) {
- angle *= REAL(0.5);
- q[0] = dCos (angle);
- l = dSin(angle) * dRecipSqrt(l);
- q[1] = ax*l;
- q[2] = ay*l;
- q[3] = az*l;
- }
- else {
- q[0] = 1;
- q[1] = 0;
- q[2] = 0;
- q[3] = 0;
- }
-}
-
-
-void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc)
-{
- dAASSERT (qa && qb && qc);
- qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3];
- qa[1] = qb[0]*qc[1] + qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2];
- qa[2] = qb[0]*qc[2] + qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3];
- qa[3] = qb[0]*qc[3] + qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1];
-}
-
-
-void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc)
-{
- dAASSERT (qa && qb && qc);
- qa[0] = qb[0]*qc[0] + qb[1]*qc[1] + qb[2]*qc[2] + qb[3]*qc[3];
- qa[1] = qb[0]*qc[1] - qb[1]*qc[0] - qb[2]*qc[3] + qb[3]*qc[2];
- qa[2] = qb[0]*qc[2] - qb[2]*qc[0] - qb[3]*qc[1] + qb[1]*qc[3];
- qa[3] = qb[0]*qc[3] - qb[3]*qc[0] - qb[1]*qc[2] + qb[2]*qc[1];
-}
-
-
-void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc)
-{
- dAASSERT (qa && qb && qc);
- qa[0] = qb[0]*qc[0] + qb[1]*qc[1] + qb[2]*qc[2] + qb[3]*qc[3];
- qa[1] = -qb[0]*qc[1] + qb[1]*qc[0] - qb[2]*qc[3] + qb[3]*qc[2];
- qa[2] = -qb[0]*qc[2] + qb[2]*qc[0] - qb[3]*qc[1] + qb[1]*qc[3];
- qa[3] = -qb[0]*qc[3] + qb[3]*qc[0] - qb[1]*qc[2] + qb[2]*qc[1];
-}
-
-
-void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc)
-{
- dAASSERT (qa && qb && qc);
- qa[0] = qb[0]*qc[0] - qb[1]*qc[1] - qb[2]*qc[2] - qb[3]*qc[3];
- qa[1] = -qb[0]*qc[1] - qb[1]*qc[0] + qb[2]*qc[3] - qb[3]*qc[2];
- qa[2] = -qb[0]*qc[2] - qb[2]*qc[0] + qb[3]*qc[1] - qb[1]*qc[3];
- qa[3] = -qb[0]*qc[3] - qb[3]*qc[0] + qb[1]*qc[2] - qb[2]*qc[1];
-}
-
-
-// QtoR(), RtoQ() and WtoDQ() are derived from equations in "An Introduction
-// to Physically Based Modeling: Rigid Body Simulation - 1: Unconstrained
-// Rigid Body Dynamics" by David Baraff, Robotics Institute, Carnegie Mellon
-// University, 1997.
-
-void dQtoR (const dQuaternion q, dMatrix3 R)
-{
- dAASSERT (q && R);
- // q = (s,vx,vy,vz)
- dReal qq1 = 2*q[1]*q[1];
- dReal qq2 = 2*q[2]*q[2];
- dReal qq3 = 2*q[3]*q[3];
- _R(0,0) = 1 - qq2 - qq3;
- _R(0,1) = 2*(q[1]*q[2] - q[0]*q[3]);
- _R(0,2) = 2*(q[1]*q[3] + q[0]*q[2]);
- _R(1,0) = 2*(q[1]*q[2] + q[0]*q[3]);
- _R(1,1) = 1 - qq1 - qq3;
- _R(1,2) = 2*(q[2]*q[3] - q[0]*q[1]);
- _R(2,0) = 2*(q[1]*q[3] - q[0]*q[2]);
- _R(2,1) = 2*(q[2]*q[3] + q[0]*q[1]);
- _R(2,2) = 1 - qq1 - qq2;
-}
-
-
-void dRtoQ (const dMatrix3 R, dQuaternion q)
-{
- dAASSERT (q && R);
- dReal tr,s;
- tr = _R(0,0) + _R(1,1) + _R(2,2);
- if (tr >= 0) {
- s = dSqrt (tr + 1);
- q[0] = REAL(0.5) * s;
- s = REAL(0.5) * dRecip(s);
- q[1] = (_R(2,1) - _R(1,2)) * s;
- q[2] = (_R(0,2) - _R(2,0)) * s;
- q[3] = (_R(1,0) - _R(0,1)) * s;
- }
- else {
- // find the largest diagonal element and jump to the appropriate case
- if (_R(1,1) > _R(0,0)) {
- if (_R(2,2) > _R(1,1)) goto case_2;
- goto case_1;
- }
- if (_R(2,2) > _R(0,0)) goto case_2;
- goto case_0;
-
- case_0:
- s = dSqrt((_R(0,0) - (_R(1,1) + _R(2,2))) + 1);
- q[1] = REAL(0.5) * s;
- s = REAL(0.5) * dRecip(s);
- q[2] = (_R(0,1) + _R(1,0)) * s;
- q[3] = (_R(2,0) + _R(0,2)) * s;
- q[0] = (_R(2,1) - _R(1,2)) * s;
- return;
-
- case_1:
- s = dSqrt((_R(1,1) - (_R(2,2) + _R(0,0))) + 1);
- q[2] = REAL(0.5) * s;
- s = REAL(0.5) * dRecip(s);
- q[3] = (_R(1,2) + _R(2,1)) * s;
- q[1] = (_R(0,1) + _R(1,0)) * s;
- q[0] = (_R(0,2) - _R(2,0)) * s;
- return;
-
- case_2:
- s = dSqrt((_R(2,2) - (_R(0,0) + _R(1,1))) + 1);
- q[3] = REAL(0.5) * s;
- s = REAL(0.5) * dRecip(s);
- q[1] = (_R(2,0) + _R(0,2)) * s;
- q[2] = (_R(1,2) + _R(2,1)) * s;
- q[0] = (_R(1,0) - _R(0,1)) * s;
- return;
- }
-}
-
-
-void dWtoDQ (const dVector3 w, const dQuaternion q, dVector4 dq)
-{
- dAASSERT (w && q && dq);
- dq[0] = REAL(0.5)*(- w[0]*q[1] - w[1]*q[2] - w[2]*q[3]);
- dq[1] = REAL(0.5)*( w[0]*q[0] + w[1]*q[3] - w[2]*q[2]);
- dq[2] = REAL(0.5)*(- w[0]*q[3] + w[1]*q[0] + w[2]*q[1]);
- dq[3] = REAL(0.5)*( w[0]*q[2] - w[1]*q[1] + w[2]*q[0]);
-}
diff --git a/extern/ode/dist/ode/src/scrapbook.cpp b/extern/ode/dist/ode/src/scrapbook.cpp
deleted file mode 100644
index ca8c11f1f1b..00000000000
--- a/extern/ode/dist/ode/src/scrapbook.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-
-/*
-
-this is code that was once useful but has now been obseleted.
-
-this file should not be compiled as part of ODE!
-
-*/
-
-//***************************************************************************
-// intersect a line segment with a plane
-
-extern "C" int dClipLineToBox (const dVector3 p1, const dVector3 p2,
- const dVector3 p, const dMatrix3 R,
- const dVector3 side)
-{
- // compute the start and end of the line (p1 and p2) relative to the box.
- // we will do all subsequent computations in this box-relative coordinate
- // system. we have to do a translation and rotation for each point.
- dVector3 tmp,s,e;
- tmp[0] = p1[0] - p[0];
- tmp[1] = p1[1] - p[1];
- tmp[2] = p1[2] - p[2];
- dMULTIPLY1_331 (s,R,tmp);
- tmp[0] = p2[0] - p[0];
- tmp[1] = p2[1] - p[1];
- tmp[2] = p2[2] - p[2];
- dMULTIPLY1_331 (e,R,tmp);
-
- // compute the vector 'v' from the start point to the end point
- dVector3 v;
- v[0] = e[0] - s[0];
- v[1] = e[1] - s[1];
- v[2] = e[2] - s[2];
-
- // a point on the line is defined by the parameter 't'. t=0 corresponds
- // to the start of the line, t=1 corresponds to the end of the line.
- // we will clip the line to the box by finding the range of t where a
- // point on the line is inside the box. the currently known bounds for
- // t and tlo..thi.
- dReal tlo=0,thi=1;
-
- // clip in the X/Y/Z direction
- for (int i=0; i<3; i++) {
- // first adjust s,e for the current t range. this is redundant for the
- // first iteration, but never mind.
- e[i] = s[i] + thi*v[i];
- s[i] = s[i] + tlo*v[i];
- // compute where t intersects the positive and negative sides.
- dReal tp = ( side[i] - s[i])/v[i]; // @@@ handle case where denom=0
- dReal tm = (-side[i] - s[i])/v[i];
- // handle 9 intersection cases
- if (s[i] <= -side[i]) {
- tlo = tm;
- if (e[i] <= -side[i]) return 0;
- else if (e[i] >= side[i]) thi = tp;
- }
- else if (s[i] <= side[i]) {
- if (e[i] <= -side[i]) thi = tm;
- else if (e[i] >= side[i]) thi = tp;
- }
- else {
- tlo = tp;
- if (e[i] <= -side[i]) thi = tm;
- else if (e[i] >= side[i]) return 0;
- }
- }
-
- //... @@@ AT HERE @@@
-
- return 1;
-}
-
-
-//***************************************************************************
-// a nice try at C-B collision. unfortunately it doesn't work. the logic
-// for testing for line-box intersection is correct, but unfortunately the
-// closest-point distance estimates are often too large. as a result contact
-// points are placed incorrectly.
-
-
-int dCollideCB (const dxGeom *o1, const dxGeom *o2, int flags,
- dContactGeom *contact, int skip)
-{
- int i;
-
- dIASSERT (skip >= (int)sizeof(dContactGeom));
- dIASSERT (o1->_class->num == dCCylinderClass);
- dIASSERT (o2->_class->num == dBoxClass);
- contact->g1 = const_cast<dxGeom*> (o1);
- contact->g2 = const_cast<dxGeom*> (o2);
- dxCCylinder *cyl = (dxCCylinder*) CLASSDATA(o1);
- dxBox *box = (dxBox*) CLASSDATA(o2);
-
- // get p1,p2 = cylinder axis endpoints, get radius
- dVector3 p1,p2;
- dReal clen = cyl->lz * REAL(0.5);
- p1[0] = o1->pos[0] + clen * o1->R[2];
- p1[1] = o1->pos[1] + clen * o1->R[6];
- p1[2] = o1->pos[2] + clen * o1->R[10];
- p2[0] = o1->pos[0] - clen * o1->R[2];
- p2[1] = o1->pos[1] - clen * o1->R[6];
- p2[2] = o1->pos[2] - clen * o1->R[10];
- dReal radius = cyl->radius;
-
- // copy out box center, rotation matrix, and side array
- dReal *c = o2->pos;
- dReal *R = o2->R;
- dReal *side = box->side;
-
- // compute the start and end of the line (p1 and p2) relative to the box.
- // we will do all subsequent computations in this box-relative coordinate
- // system. we have to do a translation and rotation for each point.
- dVector3 tmp3,s,e;
- tmp3[0] = p1[0] - c[0];
- tmp3[1] = p1[1] - c[1];
- tmp3[2] = p1[2] - c[2];
- dMULTIPLY1_331 (s,R,tmp3);
- tmp3[0] = p2[0] - c[0];
- tmp3[1] = p2[1] - c[1];
- tmp3[2] = p2[2] - c[2];
- dMULTIPLY1_331 (e,R,tmp3);
-
- // compute the vector 'v' from the start point to the end point
- dVector3 v;
- v[0] = e[0] - s[0];
- v[1] = e[1] - s[1];
- v[2] = e[2] - s[2];
-
- // compute the half-sides of the box
- dReal S0 = side[0] * REAL(0.5);
- dReal S1 = side[1] * REAL(0.5);
- dReal S2 = side[2] * REAL(0.5);
-
- // compute the size of the bounding box around the line segment
- dReal B0 = dFabs (v[0]);
- dReal B1 = dFabs (v[1]);
- dReal B2 = dFabs (v[2]);
-
- // for all 6 separation axes, measure the penetration depth. if any depth is
- // less than 0 then the objects don't penetrate at all so we can just
- // return 0. find the axis with the smallest depth, and record its normal.
-
- // note: normalR is set to point to a column of R if that is the smallest
- // depth normal so far. otherwise normalR is 0 and normalC is set to a
- // vector relative to the box. invert_normal is 1 if the sign of the normal
- // should be flipped.
-
- dReal depth,trial_depth,tmp,length;
- const dReal *normalR=0;
- dVector3 normalC;
- int invert_normal = 0;
- int code = 0; // 0=no contact, 1-3=face contact, 4-6=edge contact
-
- depth = dInfinity;
-
- // look at face-normal axes
-
-#undef TEST
-#define TEST(center,depth_expr,norm,contact_code) \
- tmp = (center); \
- trial_depth = radius + REAL(0.5) * ((depth_expr) - dFabs(tmp)); \
- if (trial_depth < 0) return 0; \
- if (trial_depth < depth) { \
- depth = trial_depth; \
- normalR = (norm); \
- invert_normal = (tmp < 0); \
- code = contact_code; \
- }
-
- TEST (s[0]+e[0], side[0] + B0, R+0, 1);
- TEST (s[1]+e[1], side[1] + B1, R+1, 2);
- TEST (s[2]+e[2], side[2] + B2, R+2, 3);
-
- // look at v x box-edge axes
-
-#undef TEST
-#define TEST(box_radius,line_offset,nx,ny,nz,contact_code) \
- tmp = (line_offset); \
- trial_depth = (box_radius) - dFabs(tmp); \
- length = dSqrt ((nx)*(nx) + (ny)*(ny) + (nz)*(nz)); \
- if (length > 0) { \
- length = dRecip(length); \
- trial_depth = trial_depth * length + radius; \
- if (trial_depth < 0) return 0; \
- if (trial_depth < depth) { \
- depth = trial_depth; \
- normalR = 0; \
- normalC[0] = (nx)*length; \
- normalC[1] = (ny)*length; \
- normalC[2] = (nz)*length; \
- invert_normal = (tmp < 0); \
- code = contact_code; \
- } \
- }
-
- TEST (B2*S1+B1*S2,v[1]*s[2]-v[2]*s[1], 0,-v[2],v[1], 4);
- TEST (B2*S0+B0*S2,v[2]*s[0]-v[0]*s[2], v[2],0,-v[0], 5);
- TEST (B1*S0+B0*S1,v[0]*s[1]-v[1]*s[0], -v[1],v[0],0, 6);
-
-#undef TEST
-
- // if we get to this point, the box and ccylinder interpenetrate.
- // compute the normal in global coordinates.
- dReal *normal = contact[0].normal;
- if (normalR) {
- normal[0] = normalR[0];
- normal[1] = normalR[4];
- normal[2] = normalR[8];
- }
- else {
- dMULTIPLY0_331 (normal,R,normalC);
- }
- if (invert_normal) {
- normal[0] = -normal[0];
- normal[1] = -normal[1];
- normal[2] = -normal[2];
- }
-
- // set the depth
- contact[0].depth = depth;
-
- if (code == 0) {
- return 0; // should never get here
- }
- else if (code >= 4) {
- // handle edge contacts
- // find an endpoint q1 on the intersecting edge of the box
- dVector3 q1;
- dReal sign[3];
- for (i=0; i<3; i++) q1[i] = c[i];
- sign[0] = (dDOT14(normal,R+0) > 0) ? REAL(1.0) : REAL(-1.0);
- for (i=0; i<3; i++) q1[i] += sign[0] * S0 * R[i*4];
- sign[1] = (dDOT14(normal,R+1) > 0) ? REAL(1.0) : REAL(-1.0);
- for (i=0; i<3; i++) q1[i] += sign[1] * S1 * R[i*4+1];
- sign[2] = (dDOT14(normal,R+2) > 0) ? REAL(1.0) : REAL(-1.0);
- for (i=0; i<3; i++) q1[i] += sign[2] * S2 * R[i*4+2];
-
- // find the other endpoint q2 of the intersecting edge
- dVector3 q2;
- for (i=0; i<3; i++)
- q2[i] = q1[i] - R[code-4 + i*4] * (sign[code-4] * side[code-4]);
-
- // determine the closest point between the box edge and the line segment
- dVector3 cp1,cp2;
- dClosestLineSegmentPoints (q1,q2, p1,p2, cp1,cp2);
- for (i=0; i<3; i++) contact[0].pos[i] = cp1[i] - REAL(0.5)*normal[i]*depth;
- return 1;
- }
- else {
- // handle face contacts.
- // @@@ temporary: make deepest vertex on the line the contact point.
- // @@@ this kind of works, but we sometimes need two contact points for
- // @@@ stability.
-
- // compute 'v' in global coordinates
- dVector3 gv;
- for (i=0; i<3; i++) gv[i] = p2[i] - p1[i];
-
- if (dDOT (normal,gv) > 0) {
- for (i=0; i<3; i++)
- contact[0].pos[i] = p1[i] + (depth*REAL(0.5)-radius)*normal[i];
- }
- else {
- for (i=0; i<3; i++)
- contact[0].pos[i] = p2[i] + (depth*REAL(0.5)-radius)*normal[i];
- }
- return 1;
- }
-}
diff --git a/extern/ode/dist/ode/src/space.cpp b/extern/ode/dist/ode/src/space.cpp
deleted file mode 100644
index 0c656573918..00000000000
--- a/extern/ode/dist/ode/src/space.cpp
+++ /dev/null
@@ -1,621 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/*
-
-simple space
-------------
-
-reports all n^2 object intersections
-
-
-multi-resolution hash table
----------------------------
-
-the current implementation rebuilds a new hash table each time collide()
-is called. we don't keep any state between calls. this is wasteful if there
-are unmoving objects in the space.
-
-
-TODO
-----
-
-less memory wasting may to prevent multiple collision callbacks for the
-same pair?
-
-better virtual address function.
-
-the collision search can perhaps be optimized - as we search chains we can
-come across other candidate intersections at other levels, perhaps we should
-do the intersection check straight away? --> save on list searching time only,
-which is not too significant.
-
-*/
-
-//****************************************************************************
-
-#include <ode/common.h>
-#include <ode/space.h>
-#include <ode/geom.h>
-#include <ode/error.h>
-#include <ode/memory.h>
-#include "objects.h"
-#include "geom_internal.h"
-
-//****************************************************************************
-// space base class
-
-struct dxSpace : public dBase {
- int type; // don't want to use RTTI
- virtual void destroy()=0;
- virtual void add (dGeomID)=0;
- virtual void remove (dGeomID)=0;
- virtual void collide (void *data, dNearCallback *callback)=0;
- virtual int query (dGeomID)=0;
-};
-
-#define TYPE_SIMPLE 0xbad
-#define TYPE_HASH 0xbabe
-
-//****************************************************************************
-// stuff common to all spaces
-
-#define ALLOCA(x) dALLOCA16(x)
-
-
-// collide two AABBs together. for the hash table space, this is called if
-// the two AABBs inhabit the same hash table cells. this only calls the
-// callback function if the boxes actually intersect. if a geom has an
-// AABB test function, that is called to provide a further refinement of
-// the intersection.
-
-static inline void collideAABBs (dReal bounds1[6], dReal bounds2[6],
- dxGeom *g1, dxGeom *g2,
- void *data, dNearCallback *callback)
-{
- // no contacts if both geoms on the same body, and the body is not 0
- if (g1->body == g2->body && g1->body) return;
-
- if (bounds1[0] > bounds2[1] ||
- bounds1[1] < bounds2[0] ||
- bounds1[2] > bounds2[3] ||
- bounds1[3] < bounds2[2] ||
- bounds1[4] > bounds2[5] ||
- bounds1[5] < bounds2[4]) return;
- if (g1->_class->aabb_test) {
- if (g1->_class->aabb_test (g1,g2,bounds2) == 0) return;
- }
- if (g2->_class->aabb_test) {
- if (g2->_class->aabb_test (g2,g1,bounds1) == 0) return;
- }
- callback (data,g1,g2);
-}
-
-//****************************************************************************
-// simple space - reports all n^2 object intersections
-
-struct dxSimpleSpace : public dxSpace {
- dGeomID first;
- void destroy();
- void add (dGeomID);
- void remove (dGeomID);
- void collide (void *data, dNearCallback *callback);
- int query (dGeomID);
-};
-
-
-dSpaceID dSimpleSpaceCreate()
-{
- dxSimpleSpace *w = new dxSimpleSpace;
- w->type = TYPE_SIMPLE;
- w->first = 0;
- return w;
-}
-
-
-void dxSimpleSpace::destroy()
-{
- // destroying each geom will call remove(). this will be efficient if
- // we destroy geoms in list order.
- dAASSERT (this);
- dGeomID g,n;
- g = first;
- while (g) {
- n = g->space.next;
- dGeomDestroy (g);
- g = n;
- }
- delete this;
-}
-
-
-void dxSimpleSpace::add (dGeomID obj)
-{
- dAASSERT (this && obj);
- dUASSERT (obj->spaceid == 0 && obj->space.next == 0,
- "object is already in a space");
- obj->space.next = first;
- first = obj;
- obj->spaceid = this;
-}
-
-
-void dxSimpleSpace::remove (dGeomID geom_to_remove)
-{
- dAASSERT (this && geom_to_remove);
- dUASSERT (geom_to_remove->spaceid,"object is not in a space");
- dGeomID last=0,g=first;
- while (g) {
- if (g==geom_to_remove) {
- if (last) last->space.next = g->space.next;
- else first = g->space.next;
- geom_to_remove->space.next = 0;
- geom_to_remove->spaceid = 0;
- return;
- }
- last = g;
- g = g->space.next;
- }
-}
-
-
-void dxSimpleSpace::collide (void *data, dNearCallback *callback)
-{
- dAASSERT (this && callback);
- dxGeom *g1,*g2;
- int i,j,n;
-
- // count the number of objects
- n=0;
- for (g1=first; g1; g1=g1->space.next) n++;
-
- // allocate and fill bounds array
- dReal *bounds = (dReal*) ALLOCA (6 * n * sizeof(dReal));
- i=0;
- for (g1=first; g1; g1=g1->space.next) {
- g1->_class->aabb (g1,bounds + i);
- g1->space_aabb = bounds + i;
- i += 6;
- }
-
- // intersect all bounding boxes
- i=0;
- for (g1=first; g1; g1=g1->space.next) {
- j=i+6;
- for (g2=g1->space.next; g2; g2=g2->space.next) {
- collideAABBs (bounds+i,bounds+j,g1,g2,data,callback);
- j += 6;
- }
- i += 6;
- }
-
- // reset the aabb fields of the geoms back to 0
- for (g1=first; g1; g1=g1->space.next) g1->space_aabb = 0;
-}
-
-
-// @@@ NOT FLEXIBLE ENOUGH
-//
-//int dSpaceCollide (dSpaceID space, dContactGeom **contact_array)
-//{
-// int n = 0;
-// dContactGeom *base = (dContact*) dStackAlloc (sizeof(dContact));
-// dContactGeom *c = base;
-// for (dxGeom *g1=space->first; g1; g1=g1->space.next) {
-// for (dxGeom *g2=g1->space.next; g2; g2=g2->space.next) {
-// // generate at most 1 contact for this pair
-// c->o1 = g1;
-// c->o2 = g2;
-// if (dCollide (0,c)) {
-// c = (dContactGeom*) dStackAlloc (sizeof(dContactGeom));
-// n++;
-// }
-// }
-// }
-// *contact_array = base;
-// return n;
-//}
-
-
-int dxSimpleSpace::query (dGeomID obj)
-{
- dAASSERT (this && obj);
- if (obj->spaceid != this) return 0;
- dGeomID compare = first;
- while (compare) {
- if (compare == obj) return 1;
- compare = compare->space.next;
- }
- dDebug (0,"object is not in the space it thinks it is in");
- return 0;
-}
-
-//****************************************************************************
-// hash table space
-
-// kind of silly, but oh well...
-#define MAXINT ((int)((((unsigned int)(-1)) << 1) >> 1))
-
-
-// prime[i] is the largest prime smaller than 2^i
-#define NUM_PRIMES 31
-static long int prime[NUM_PRIMES] = {1L,2L,3L,7L,13L,31L,61L,127L,251L,509L,
- 1021L,2039L,4093L,8191L,16381L,32749L,65521L,131071L,262139L,
- 524287L,1048573L,2097143L,4194301L,8388593L,16777213L,33554393L,
- 67108859L,134217689L,268435399L,536870909L,1073741789L};
-
-
-// currently the space 'container' is just a list of the geoms in the space.
-
-struct dxHashSpace : public dxSpace {
- dxGeom *first;
- int global_minlevel; // smallest hash table level to put AABBs in
- int global_maxlevel; // objects that need a level larger than this will be
- // put in a "big objects" list instead of a hash table
- void destroy();
- void add (dGeomID);
- void remove (dGeomID);
- void collide (void *data, dNearCallback *callback);
- int query (dGeomID);
-};
-
-
-// an axis aligned bounding box
-struct dxAABB {
- dxAABB *next; // next in the list of all AABBs
- dReal bounds[6]; // minx, maxx, miny, maxy, minz, maxz
- int level; // the level this is stored in (cell size = 2^level)
- int dbounds[6]; // AABB bounds, discretized to cell size
- dxGeom *geom; // corresponding geometry object
- int index; // index of this AABB, starting from 0
-};
-
-
-// a hash table node that represents an AABB that intersects a particular cell
-// at a particular level
-struct Node {
- Node *next; // next node in hash table collision list, 0 if none
- int x,y,z; // cell position in space, discretized to cell size
- dxAABB *aabb; // axis aligned bounding box that intersects this cell
-};
-
-
-// return the `level' of an AABB. the AABB will be put into cells at this
-// level - the cell size will be 2^level. the level is chosen to be the
-// smallest value such that the AABB occupies no more than 8 cells, regardless
-// of its placement. this means that:
-// size/2 < q <= size
-// where q is the maximum AABB dimension.
-
-static int findLevel (dReal bounds[6])
-{
- // compute q
- dReal q,q2;
- q = bounds[1] - bounds[0]; // x bounds
- q2 = bounds[3] - bounds[2]; // y bounds
- if (q2 > q) q = q2;
- q2 = bounds[5] - bounds[4]; // z bounds
- if (q2 > q) q = q2;
-
- if (q == dInfinity) return MAXINT;
-
- // find level such that 0.5 * 2^level < q <= 2^level
- int level;
- frexp (q,&level); // q = (0.5 .. 1.0) * 2^level (definition of frexp)
- return level;
-}
-
-
-// find a virtual memory address for a cell at the given level and x,y,z
-// position.
-// @@@ currently this is not very sophisticated, e.g. the scaling
-// factors could be better designed to avoid collisions, and they should
-// probably depend on the hash table physical size.
-
-static unsigned long getVirtualAddress (int level, int x, int y, int z)
-{
- return level*1000 + x*100 + y*10 + z;
-}
-
-//****************************************************************************
-// hash space public functions
-
-dSpaceID dHashSpaceCreate()
-{
- dxHashSpace *w = new dxHashSpace;
- w->type = TYPE_HASH;
- w->first = 0;
- w->global_minlevel = -3;
- w->global_maxlevel = 10;
- return w;
-}
-
-
-void dxHashSpace::destroy()
-{
- // destroying each geom will call remove(). this will be efficient if
- // we destroy geoms in list order.
- dAASSERT (this);
- dGeomID g,n;
- g = first;
- while (g) {
- n = g->space.next;
- dGeomDestroy (g);
- g = n;
- }
- delete this;
-}
-
-
-void dHashSpaceSetLevels (dxSpace *space, int minlevel, int maxlevel)
-{
- dUASSERT (minlevel <= maxlevel,"must have minlevel <= maxlevel");
- dUASSERT (space->type == TYPE_HASH,"must be a hash space");
- dxHashSpace *hspace = (dxHashSpace*) space;
- hspace->global_minlevel = minlevel;
- hspace->global_maxlevel = maxlevel;
-}
-
-
-void dxHashSpace::add (dGeomID obj)
-{
- dAASSERT (this && obj);
- dUASSERT (obj->spaceid == 0 && obj->space.next == 0,
- "object is already in a space");
- obj->space.next = first;
- first = obj;
- obj->spaceid = this;
-}
-
-
-void dxHashSpace::remove (dGeomID geom_to_remove)
-{
- dAASSERT (this && geom_to_remove);
- dUASSERT (geom_to_remove->spaceid,"object is not in a space");
- dGeomID last=0,g=first;
- while (g) {
- if (g==geom_to_remove) {
- if (last) last->space.next = g->space.next;
- else first = g->space.next;
- geom_to_remove->space.next = 0;
- geom_to_remove->spaceid = 0;
- return;
- }
- last = g;
- g = g->space.next;
- }
-}
-
-
-void dxHashSpace::collide (void *data, dNearCallback *callback)
-{
- dAASSERT(this && callback);
- dxGeom *geom;
- dxAABB *aabb;
- int i,maxlevel;
-
- // create a list of axis aligned bounding boxes for all geoms. count the
- // number of AABBs as we go. set the level for all AABBs. put AABBs larger
- // than the space's global_maxlevel in the big_boxes list, check everything
- // else against that list at the end. for AABBs that are not too big,
- // record the maximum level that we need.
-
- int n = 0; // number of AABBs in main list
- int ntotal = 0; // total number of AABBs
- dxAABB *first_aabb = 0; // list of AABBs in hash table
- dxAABB *big_boxes = 0; // list of AABBs too big for hash table
- maxlevel = global_minlevel - 1;
- for (geom = first; geom; geom=geom->space.next) {
- ntotal++;
- dxAABB *aabb = (dxAABB*) ALLOCA (sizeof(dxAABB));
- geom->_class->aabb (geom,aabb->bounds);
- geom->space_aabb = aabb->bounds;
- aabb->geom = geom;
- // compute level, but prevent cells from getting too small
- int level = findLevel (aabb->bounds);
- if (level < global_minlevel) level = global_minlevel;
- if (level <= global_maxlevel) {
- // aabb goes in main list
- aabb->next = first_aabb;
- first_aabb = aabb;
- aabb->level = level;
- if (level > maxlevel) maxlevel = level;
- // cellsize = 2^level
- dReal cellsize = (dReal) ldexp (1.0,level);
- // discretize AABB position to cell size
- for (i=0; i < 6; i++) aabb->dbounds[i] = (int)
- floor (aabb->bounds[i]/cellsize);
- // set AABB index
- aabb->index = n;
- n++;
- }
- else {
- // aabb is too big, put it in the big_boxes list. we don't care about
- // setting level, dbounds, index, or the maxlevel
- aabb->next = big_boxes;
- big_boxes = aabb;
- }
- }
-
- // 0 or 1 boxes can't collide with anything
- if (ntotal < 2) return;
-
- // for `n' objects, an n*n array of bits is used to record if those objects
- // have been intersection-tested against each other yet. this array can
- // grow large with high n, but oh well...
- int tested_rowsize = (n+7) >> 3; // number of bytes needed for n bits
- unsigned char *tested = (unsigned char *) alloca (n * tested_rowsize);
- memset (tested,0,n * tested_rowsize);
-
- // create a hash table to store all AABBs. each AABB may take up to 8 cells.
- // we use chaining to resolve collisions, but we use a relatively large table
- // to reduce the chance of collisions.
-
- // compute hash table size sz to be a prime > 8*n
- for (i=0; i<NUM_PRIMES; i++) {
- if (prime[i] >= (8*n)) break;
- }
- if (i >= NUM_PRIMES) i = NUM_PRIMES-1; // probably pointless
- int sz = prime[i];
-
- // allocate and initialize hash table node pointers
- Node **table = (Node **) ALLOCA (sizeof(Node*) * sz);
- for (i=0; i<sz; i++) table[i] = 0;
-
- // add each AABB to the hash table (may need to add it to up to 8 cells)
- for (aabb=first_aabb; aabb; aabb=aabb->next) {
- int *dbounds = aabb->dbounds;
- for (int xi = dbounds[0]; xi <= dbounds[1]; xi++) {
- for (int yi = dbounds[2]; yi <= dbounds[3]; yi++) {
- for (int zi = dbounds[4]; zi <= dbounds[5]; zi++) {
- // get the hash index
- unsigned long hi = getVirtualAddress (aabb->level,xi,yi,zi) % sz;
- // add a new node to the hash table
- Node *node = (Node*) alloca (sizeof (Node));
- node->x = xi;
- node->y = yi;
- node->z = zi;
- node->aabb = aabb;
- node->next = table[hi];
- table[hi] = node;
- }
- }
- }
- }
-
- // now that all AABBs are loaded into the hash table, we do the actual
- // collision detection. for all AABBs, check for other AABBs in the
- // same cells for collisions, and then check for other AABBs in all
- // intersecting higher level cells.
-
- int db[6]; // discrete bounds at current level
- for (aabb=first_aabb; aabb; aabb=aabb->next) {
- // we are searching for collisions with aabb
- for (i=0; i<6; i++) db[i] = aabb->dbounds[i];
- for (int level = aabb->level; level <= maxlevel; level++) {
- for (int xi = db[0]; xi <= db[1]; xi++) {
- for (int yi = db[2]; yi <= db[3]; yi++) {
- for (int zi = db[4]; zi <= db[5]; zi++) {
- // get the hash index
- unsigned long hi = getVirtualAddress (level,xi,yi,zi) % sz;
- // search all nodes at this index
- Node *node;
- for (node = table[hi]; node; node=node->next) {
- // node points to an AABB that may intersect aabb
- if (node->aabb == aabb) continue;
- if (node->aabb->level == level &&
- node->x == xi && node->y == yi && node->z == zi) {
- // see if aabb and node->aabb have already been tested
- // against each other
- unsigned char mask;
- if (aabb->index <= node->aabb->index) {
- i = (aabb->index * tested_rowsize)+(node->aabb->index >> 3);
- mask = 1 << (node->aabb->index & 7);
- }
- else {
- i = (node->aabb->index * tested_rowsize)+(aabb->index >> 3);
- mask = 1 << (aabb->index & 7);
- }
- dIASSERT (i >= 0 && i < (tested_rowsize*n));
- if ((tested[i] & mask)==0) {
- collideAABBs (aabb->bounds,node->aabb->bounds,
- aabb->geom,node->aabb->geom,
- data,callback);
- }
- tested[i] |= mask;
- }
- }
- }
- }
- }
- // get the discrete bounds for the next level up
- for (i=0; i<6; i++) db[i] >>= 1;
- }
- }
-
- // every AABB in the normal list must now be intersected against every
- // AABB in the big_boxes list. so let's hope there are not too many objects
- // in the big_boxes list.
- for (aabb=first_aabb; aabb; aabb=aabb->next) {
- for (dxAABB *aabb2=big_boxes; aabb2; aabb2=aabb2->next) {
- collideAABBs (aabb->bounds,aabb2->bounds,aabb->geom,aabb2->geom,
- data,callback);
- }
- }
-
- // intersected all AABBs in the big_boxes list together
- for (aabb=big_boxes; aabb; aabb=aabb->next) {
- for (dxAABB *aabb2=aabb->next; aabb2; aabb2=aabb2->next) {
- collideAABBs (aabb->bounds,aabb2->bounds,aabb->geom,aabb2->geom,
- data,callback);
- }
- }
-
- // reset the aabb fields of the geoms back to 0
- for (geom=first; geom; geom=geom->space.next) geom->space_aabb = 0;
-}
-
-
-int dxHashSpace::query (dGeomID obj)
-{
- dAASSERT (this && obj);
- if (obj->spaceid != this) return 0;
- dGeomID compare = first;
- while (compare) {
- if (compare == obj) return 1;
- compare = compare->space.next;
- }
- dDebug (0,"object is not in the space it thinks it is in");
- return 0;
-}
-
-//****************************************************************************
-// space functions
-
-void dSpaceDestroy (dxSpace * space)
-{
- space->destroy();
-}
-
-
-void dSpaceAdd (dxSpace * space, dxGeom *g)
-{
- space->add (g);
-}
-
-
-void dSpaceRemove (dxSpace * space, dxGeom *g)
-{
- space->remove (g);
-}
-
-
-int dSpaceQuery (dxSpace * space, dxGeom *g)
-{
- return space->query (g);
-}
-
-
-void dSpaceCollide (dxSpace * space, void *data, dNearCallback *callback)
-{
- space->collide (data,callback);
-}
diff --git a/extern/ode/dist/ode/src/stack.cpp b/extern/ode/dist/ode/src/stack.cpp
deleted file mode 100644
index e062f92b54f..00000000000
--- a/extern/ode/dist/ode/src/stack.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-@@@ this file should not be compiled any more @@@
-
-#include <string.h>
-#include <errno.h>
-#include "stack.h"
-#include "ode/error.h"
-#include "ode/config.h"
-
-//****************************************************************************
-// unix version that uses mmap(). some systems have anonymous mmaps and some
-// need to mmap /dev/zero.
-
-#ifndef WIN32
-
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-
-void dStack::init (int max_size)
-{
- if (sizeof(long int) != sizeof(char*)) dDebug (0,"internal");
- if (max_size <= 0) dDebug (0,"Stack::init() given size <= 0");
-
-#ifndef MMAP_ANONYMOUS
- static int dev_zero_fd = -1; // cached file descriptor for /dev/zero
- if (dev_zero_fd < 0) dev_zero_fd = open ("/dev/zero", O_RDWR);
- if (dev_zero_fd < 0) dError (0,"can't open /dev/zero (%s)",strerror(errno));
- base = (char*) mmap (0,max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
- dev_zero_fd,0);
-#else
- base = (char*) mmap (0,max_size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON,0,0);
-#endif
-
- if (int(base) == -1) dError (0,"Stack::init(), mmap() failed, "
- "max_size=%d (%s)",max_size,strerror(errno));
- size = max_size;
- pointer = base;
- frame = 0;
-}
-
-
-void dStack::destroy()
-{
- munmap (base,size);
- base = 0;
- size = 0;
- pointer = 0;
- frame = 0;
-}
-
-#endif
-
-//****************************************************************************
-
-#ifdef WIN32
-
-#include "windows.h"
-
-
-void dStack::init (int max_size)
-{
- if (sizeof(LPVOID) != sizeof(char*)) dDebug (0,"internal");
- if (max_size <= 0) dDebug (0,"Stack::init() given size <= 0");
- base = (char*) VirtualAlloc (NULL,max_size,MEM_RESERVE,PAGE_READWRITE);
- if (base == 0) dError (0,"Stack::init(), VirtualAlloc() failed, "
- "max_size=%d",max_size);
- size = max_size;
- pointer = base;
- frame = 0;
- committed = 0;
-
- // get page size
- SYSTEM_INFO info;
- GetSystemInfo (&info);
- pagesize = info.dwPageSize;
-}
-
-
-void dStack::destroy()
-{
- VirtualFree (base,0,MEM_RELEASE);
- base = 0;
- size = 0;
- pointer = 0;
- frame = 0;
-}
-
-#endif
diff --git a/extern/ode/dist/ode/src/stack.h b/extern/ode/dist/ode/src/stack.h
deleted file mode 100644
index 3b98202b042..00000000000
--- a/extern/ode/dist/ode/src/stack.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/* this comes from the `reuse' library. copy any changes back to the source.
-
-these stack allocation functions are a replacement for alloca(), except that
-they allocate memory from a separate pool.
-
-advantages over alloca():
- - consecutive allocations are guaranteed to be contiguous with increasing
- address.
- - functions can allocate stack memory that is returned to the caller,
- in other words pushing and popping stack frames is optional.
-
-disadvantages compared to alloca():
- - less portable
- - slightly slower, although still orders of magnitude faster than malloc().
- - longjmp() and exceptions do not deallocate stack memory (but who cares?).
-
-just like alloca():
- - using too much stack memory does not fail gracefully, it fails with a
- segfault.
-
-*/
-
-
-#ifndef _ODE_STACK_H_
-#define _ODE_STACK_H_
-
-
-#ifdef WIN32
-#include "windows.h"
-#endif
-
-
-struct dStack {
- char *base; // bottom of the stack
- int size; // maximum size of the stack
- char *pointer; // current top of the stack
- char *frame; // linked list of stack frame ptrs
-# ifdef WIN32 // stuff for windows:
- int pagesize; // - page size - this is ASSUMED to be a power of 2
- int committed; // - bytes committed in allocated region
-#endif
-
- // initialize the stack. `max_size' is the maximum size that the stack can
- // reach. on unix and windows a `virtual' memory block of this size is
- // mapped into the address space but does not actually consume physical
- // memory until it is referenced - so it is safe to set this to a high value.
-
- void init (int max_size);
-
-
- // destroy the stack. this unmaps any virtual memory that was allocated.
-
- void destroy();
-
-
- // allocate `size' bytes from the stack and return a pointer to the allocated
- // memory. `size' must be >= 0. the returned pointer will be aligned to the
- // size of a long int.
-
- char * alloc (int size)
- {
- char *ret = pointer;
- pointer += ((size-1) | (sizeof(long int)-1) )+1;
-# ifdef WIN32
- // for windows we need to commit pages as they are required
- if ((pointer-base) > committed) {
- committed = ((pointer-base-1) | (pagesize-1))+1; // round up to pgsize
- VirtualAlloc (base,committed,MEM_COMMIT,PAGE_READWRITE);
- }
-# endif
- return ret;
- }
-
-
- // return the address that will be returned by the next call to alloc()
-
- char *nextAlloc()
- {
- return pointer;
- }
-
-
- // push and pop the current size of the stack. pushFrame() saves the current
- // frame pointer on the stack, and popFrame() retrieves it. a typical
- // stack-using function will bracket alloc() calls with pushFrame() and
- // popFrame(). both functions return the current stack pointer - this should
- // be the same value for the two bracketing calls. calling popFrame() too
- // many times will result in a segfault.
-
- char * pushFrame()
- {
- char *newframe = pointer;
- char **addr = (char**) alloc (sizeof(char*));
- *addr = frame;
- frame = newframe;
- return newframe;
-
- /* OLD CODE
- *((char**)pointer) = frame;
- frame = pointer;
- char *ret = pointer;
- pointer += sizeof(char*);
- return ret;
- */
- }
-
- char * popFrame()
- {
- pointer = frame;
- frame = *((char**)pointer);
- return pointer;
- }
-};
-
-
-#endif
-
diff --git a/extern/ode/dist/ode/src/step.cpp b/extern/ode/dist/ode/src/step.cpp
deleted file mode 100644
index 16f77112ad2..00000000000
--- a/extern/ode/dist/ode/src/step.cpp
+++ /dev/null
@@ -1,1085 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include "objects.h"
-#include "joint.h"
-#include <ode/config.h>
-#include <ode/odemath.h>
-#include <ode/rotation.h>
-#include <ode/timer.h>
-#include <ode/error.h>
-#include <ode/matrix.h>
-#include "lcp.h"
-
-//****************************************************************************
-// misc defines
-
-#define FAST_FACTOR
-//#define TIMING
-
-#define ALLOCA dALLOCA16
-
-//****************************************************************************
-// debugging - comparison of various vectors and matrices produced by the
-// slow and fast versions of the stepper.
-
-//#define COMPARE_METHODS
-
-#ifdef COMPARE_METHODS
-#include "testing.h"
-dMatrixComparison comparator;
-#endif
-
-//****************************************************************************
-// special matrix multipliers
-
-// this assumes the 4th and 8th rows of B and C are zero.
-
-static void Multiply2_p8r (dReal *A, dReal *B, dReal *C,
- int p, int r, int Askip)
-{
- int i,j;
- dReal sum,*bb,*cc;
- dIASSERT (p>0 && r>0 && A && B && C);
- bb = B;
- for (i=p; i; i--) {
- cc = C;
- for (j=r; j; j--) {
- sum = bb[0]*cc[0];
- sum += bb[1]*cc[1];
- sum += bb[2]*cc[2];
- sum += bb[4]*cc[4];
- sum += bb[5]*cc[5];
- sum += bb[6]*cc[6];
- *(A++) = sum;
- cc += 8;
- }
- A += Askip - r;
- bb += 8;
- }
-}
-
-
-// this assumes the 4th and 8th rows of B and C are zero.
-
-static void MultiplyAdd2_p8r (dReal *A, dReal *B, dReal *C,
- int p, int r, int Askip)
-{
- int i,j;
- dReal sum,*bb,*cc;
- dIASSERT (p>0 && r>0 && A && B && C);
- bb = B;
- for (i=p; i; i--) {
- cc = C;
- for (j=r; j; j--) {
- sum = bb[0]*cc[0];
- sum += bb[1]*cc[1];
- sum += bb[2]*cc[2];
- sum += bb[4]*cc[4];
- sum += bb[5]*cc[5];
- sum += bb[6]*cc[6];
- *(A++) += sum;
- cc += 8;
- }
- A += Askip - r;
- bb += 8;
- }
-}
-
-
-// this assumes the 4th and 8th rows of B are zero.
-
-static void Multiply0_p81 (dReal *A, dReal *B, dReal *C, int p)
-{
- int i;
- dIASSERT (p>0 && A && B && C);
- dReal sum;
- for (i=p; i; i--) {
- sum = B[0]*C[0];
- sum += B[1]*C[1];
- sum += B[2]*C[2];
- sum += B[4]*C[4];
- sum += B[5]*C[5];
- sum += B[6]*C[6];
- *(A++) = sum;
- B += 8;
- }
-}
-
-
-// this assumes the 4th and 8th rows of B are zero.
-
-static void MultiplyAdd0_p81 (dReal *A, dReal *B, dReal *C, int p)
-{
- int i;
- dIASSERT (p>0 && A && B && C);
- dReal sum;
- for (i=p; i; i--) {
- sum = B[0]*C[0];
- sum += B[1]*C[1];
- sum += B[2]*C[2];
- sum += B[4]*C[4];
- sum += B[5]*C[5];
- sum += B[6]*C[6];
- *(A++) += sum;
- B += 8;
- }
-}
-
-
-// this assumes the 4th and 8th rows of B are zero.
-
-static void MultiplyAdd1_8q1 (dReal *A, dReal *B, dReal *C, int q)
-{
- int k;
- dReal sum;
- dIASSERT (q>0 && A && B && C);
- sum = 0;
- for (k=0; k<q; k++) sum += B[k*8] * C[k];
- A[0] += sum;
- sum = 0;
- for (k=0; k<q; k++) sum += B[1+k*8] * C[k];
- A[1] += sum;
- sum = 0;
- for (k=0; k<q; k++) sum += B[2+k*8] * C[k];
- A[2] += sum;
- sum = 0;
- for (k=0; k<q; k++) sum += B[4+k*8] * C[k];
- A[4] += sum;
- sum = 0;
- for (k=0; k<q; k++) sum += B[5+k*8] * C[k];
- A[5] += sum;
- sum = 0;
- for (k=0; k<q; k++) sum += B[6+k*8] * C[k];
- A[6] += sum;
-}
-
-
-// this assumes the 4th and 8th rows of B are zero.
-
-static void Multiply1_8q1 (dReal *A, dReal *B, dReal *C, int q)
-{
- int k;
- dReal sum;
- dIASSERT (q>0 && A && B && C);
- sum = 0;
- for (k=0; k<q; k++) sum += B[k*8] * C[k];
- A[0] = sum;
- sum = 0;
- for (k=0; k<q; k++) sum += B[1+k*8] * C[k];
- A[1] = sum;
- sum = 0;
- for (k=0; k<q; k++) sum += B[2+k*8] * C[k];
- A[2] = sum;
- sum = 0;
- for (k=0; k<q; k++) sum += B[4+k*8] * C[k];
- A[4] = sum;
- sum = 0;
- for (k=0; k<q; k++) sum += B[5+k*8] * C[k];
- A[5] = sum;
- sum = 0;
- for (k=0; k<q; k++) sum += B[6+k*8] * C[k];
- A[6] = sum;
-}
-
-//****************************************************************************
-// body rotation
-
-// return sin(x)/x. this has a singularity at 0 so special handling is needed
-// for small arguments.
-
-static inline dReal sinc (dReal x)
-{
- // if |x| < 1e-4 then use a taylor series expansion. this two term expansion
- // is actually accurate to one LS bit within this range if double precision
- // is being used - so don't worry!
- if (dFabs(x) < 1.0e-4) return REAL(1.0) - x*x*REAL(0.166666666666666666667);
- else return dSin(x)/x;
-}
-
-
-// given a body b, apply its linear and angular rotation over the time
-// interval h, thereby adjusting its position and orientation.
-
-static inline void moveAndRotateBody (dxBody *b, dReal h)
-{
- int j;
-
- // handle linear velocity
- for (j=0; j<3; j++) b->pos[j] += h * b->lvel[j];
-
- if (b->flags & dxBodyFlagFiniteRotation) {
- dVector3 irv; // infitesimal rotation vector
- dQuaternion q; // quaternion for finite rotation
-
- if (b->flags & dxBodyFlagFiniteRotationAxis) {
- // split the angular velocity vector into a component along the finite
- // rotation axis, and a component orthogonal to it.
- dVector3 frv,irv; // finite rotation vector
- dReal k = dDOT (b->finite_rot_axis,b->avel);
- frv[0] = b->finite_rot_axis[0] * k;
- frv[1] = b->finite_rot_axis[1] * k;
- frv[2] = b->finite_rot_axis[2] * k;
- irv[0] = b->avel[0] - frv[0];
- irv[1] = b->avel[1] - frv[1];
- irv[2] = b->avel[2] - frv[2];
-
- // make a rotation quaternion q that corresponds to frv * h.
- // compare this with the full-finite-rotation case below.
- h *= REAL(0.5);
- dReal theta = k * h;
- q[0] = dCos(theta);
- dReal s = sinc(theta) * h;
- q[1] = frv[0] * s;
- q[2] = frv[1] * s;
- q[3] = frv[2] * s;
- }
- else {
- // make a rotation quaternion q that corresponds to w * h
- dReal wlen = dSqrt (b->avel[0]*b->avel[0] + b->avel[1]*b->avel[1] +
- b->avel[2]*b->avel[2]);
- h *= REAL(0.5);
- dReal theta = wlen * h;
- q[0] = dCos(theta);
- dReal s = sinc(theta) * h;
- q[1] = b->avel[0] * s;
- q[2] = b->avel[1] * s;
- q[3] = b->avel[2] * s;
- }
-
- // do the finite rotation
- dQuaternion q2;
- dQMultiply0 (q2,q,b->q);
- for (j=0; j<4; j++) b->q[j] = q2[j];
-
- // do the infitesimal rotation if required
- if (b->flags & dxBodyFlagFiniteRotationAxis) {
- dReal dq[4];
- dWtoDQ (irv,b->q,dq);
- for (j=0; j<4; j++) b->q[j] += h * dq[j];
- }
- }
- else {
- // the normal way - do an infitesimal rotation
- dReal dq[4];
- dWtoDQ (b->avel,b->q,dq);
- for (j=0; j<4; j++) b->q[j] += h * dq[j];
- }
-
- // normalize the quaternion and convert it to a rotation matrix
- dNormalize4 (b->q);
- dQtoR (b->q,b->R);
-}
-
-//****************************************************************************
-// the slow, but sure way
-// note that this does not do any joint feedback!
-
-// given lists of bodies and joints that form an island, perform a first
-// order timestep.
-//
-// `body' is the body array, `nb' is the size of the array.
-// `_joint' is the body array, `nj' is the size of the array.
-
-void dInternalStepIsland_x1 (dxWorld *world, dxBody * const *body, int nb,
- dxJoint * const *_joint, int nj, dReal stepsize)
-{
- int i,j,k;
- int n6 = 6*nb;
-
-# ifdef TIMING
- dTimerStart("preprocessing");
-# endif
-
- // number all bodies in the body list - set their tag values
- for (i=0; i<nb; i++) body[i]->tag = i;
-
- // make a local copy of the joint array, because we might want to modify it.
- // (the "dxJoint *const*" declaration says we're allowed to modify the joints
- // but not the joint array, because the caller might need it unchanged).
- dxJoint **joint = (dxJoint**) ALLOCA (nj * sizeof(dxJoint*));
- memcpy (joint,_joint,nj * sizeof(dxJoint*));
-
- // for all bodies, compute the inertia tensor and its inverse in the global
- // frame, and compute the rotational force and add it to the torque
- // accumulator.
- // @@@ check computation of rotational force.
- dReal *I = (dReal*) ALLOCA (3*nb*4 * sizeof(dReal));
- dReal *invI = (dReal*) ALLOCA (3*nb*4 * sizeof(dReal));
- dSetZero (I,3*nb*4);
- dSetZero (invI,3*nb*4);
- for (i=0; i<nb; i++) {
- dReal tmp[12];
- // compute inertia tensor in global frame
- dMULTIPLY2_333 (tmp,body[i]->mass.I,body[i]->R);
- dMULTIPLY0_333 (I+i*12,body[i]->R,tmp);
- // compute inverse inertia tensor in global frame
- dMULTIPLY2_333 (tmp,body[i]->invI,body[i]->R);
- dMULTIPLY0_333 (invI+i*12,body[i]->R,tmp);
- // compute rotational force
- dMULTIPLY0_331 (tmp,I+i*12,body[i]->avel);
- dCROSS (body[i]->tacc,-=,body[i]->avel,tmp);
- }
-
- // add the gravity force to all bodies
- for (i=0; i<nb; i++) {
- if ((body[i]->flags & dxBodyNoGravity)==0) {
- body[i]->facc[0] += body[i]->mass.mass * world->gravity[0];
- body[i]->facc[1] += body[i]->mass.mass * world->gravity[1];
- body[i]->facc[2] += body[i]->mass.mass * world->gravity[2];
- }
- }
-
- // get m = total constraint dimension, nub = number of unbounded variables.
- // create constraint offset array and number-of-rows array for all joints.
- // the constraints are re-ordered as follows: the purely unbounded
- // constraints, the mixed unbounded + LCP constraints, and last the purely
- // LCP constraints.
- //
- // joints with m=0 are inactive and are removed from the joints array
- // entirely, so that the code that follows does not consider them.
- int m = 0;
- dxJoint::Info1 *info = (dxJoint::Info1*) ALLOCA (nj*sizeof(dxJoint::Info1));
- int *ofs = (int*) ALLOCA (nj*sizeof(int));
- for (i=0, j=0; j<nj; j++) { // i=dest, j=src
- joint[j]->vtable->getInfo1 (joint[j],info+i);
- dIASSERT (info[i].m >= 0 && info[i].m <= 6 &&
- info[i].nub >= 0 && info[i].nub <= info[i].m);
- if (info[i].m > 0) {
- joint[i] = joint[j];
- i++;
- }
- }
- nj = i;
-
- // the purely unbounded constraints
- for (i=0; i<nj; i++) if (info[i].nub == info[i].m) {
- ofs[i] = m;
- m += info[i].m;
- }
- int nub = m;
- // the mixed unbounded + LCP constraints
- for (i=0; i<nj; i++) if (info[i].nub > 0 && info[i].nub < info[i].m) {
- ofs[i] = m;
- m += info[i].m;
- }
- // the purely LCP constraints
- for (i=0; i<nj; i++) if (info[i].nub == 0) {
- ofs[i] = m;
- m += info[i].m;
- }
-
- // create (6*nb,6*nb) inverse mass matrix `invM', and fill it with mass
- // parameters
-# ifdef TIMING
- dTimerNow ("create mass matrix");
-# endif
- int nskip = dPAD (n6);
- dReal *invM = (dReal*) ALLOCA (n6*nskip*sizeof(dReal));
- dSetZero (invM,n6*nskip);
- for (i=0; i<nb; i++) {
- dReal *MM = invM+(i*6)*nskip+(i*6);
- MM[0] = body[i]->invMass;
- MM[nskip+1] = body[i]->invMass;
- MM[2*nskip+2] = body[i]->invMass;
- MM += 3*nskip+3;
- for (j=0; j<3; j++) for (k=0; k<3; k++) {
- MM[j*nskip+k] = invI[i*12+j*4+k];
- }
- }
-
- // assemble some body vectors: fe = external forces, v = velocities
- dReal *fe = (dReal*) ALLOCA (n6 * sizeof(dReal));
- dReal *v = (dReal*) ALLOCA (n6 * sizeof(dReal));
- dSetZero (fe,n6);
- dSetZero (v,n6);
- for (i=0; i<nb; i++) {
- for (j=0; j<3; j++) fe[i*6+j] = body[i]->facc[j];
- for (j=0; j<3; j++) fe[i*6+3+j] = body[i]->tacc[j];
- for (j=0; j<3; j++) v[i*6+j] = body[i]->lvel[j];
- for (j=0; j<3; j++) v[i*6+3+j] = body[i]->avel[j];
- }
-
- // this will be set to the velocity update
- dReal *vnew = (dReal*) ALLOCA (n6 * sizeof(dReal));
- dSetZero (vnew,n6);
-
- // if there are constraints, compute cforce
- if (m > 0) {
- // create a constraint equation right hand side vector `c', a constraint
- // force mixing vector `cfm', and LCP low and high bound vectors, and an
- // 'findex' vector.
- dReal *c = (dReal*) ALLOCA (m*sizeof(dReal));
- dReal *cfm = (dReal*) ALLOCA (m*sizeof(dReal));
- dReal *lo = (dReal*) ALLOCA (m*sizeof(dReal));
- dReal *hi = (dReal*) ALLOCA (m*sizeof(dReal));
- int *findex = (int*) alloca (m*sizeof(int));
- dSetZero (c,m);
- dSetValue (cfm,m,world->global_cfm);
- dSetValue (lo,m,-dInfinity);
- dSetValue (hi,m, dInfinity);
- for (i=0; i<m; i++) findex[i] = -1;
-
- // create (m,6*nb) jacobian mass matrix `J', and fill it with constraint
- // data. also fill the c vector.
-# ifdef TIMING
- dTimerNow ("create J");
-# endif
- dReal *J = (dReal*) ALLOCA (m*nskip*sizeof(dReal));
- dSetZero (J,m*nskip);
- dxJoint::Info2 Jinfo;
- Jinfo.rowskip = nskip;
- Jinfo.fps = dRecip(stepsize);
- Jinfo.erp = world->global_erp;
- for (i=0; i<nj; i++) {
- Jinfo.J1l = J + nskip*ofs[i] + 6*joint[i]->node[0].body->tag;
- Jinfo.J1a = Jinfo.J1l + 3;
- if (joint[i]->node[1].body) {
- Jinfo.J2l = J + nskip*ofs[i] + 6*joint[i]->node[1].body->tag;
- Jinfo.J2a = Jinfo.J2l + 3;
- }
- else {
- Jinfo.J2l = 0;
- Jinfo.J2a = 0;
- }
- Jinfo.c = c + ofs[i];
- Jinfo.cfm = cfm + ofs[i];
- Jinfo.lo = lo + ofs[i];
- Jinfo.hi = hi + ofs[i];
- Jinfo.findex = findex + ofs[i];
- joint[i]->vtable->getInfo2 (joint[i],&Jinfo);
- // adjust returned findex values for global index numbering
- for (j=0; j<info[i].m; j++) {
- if (findex[ofs[i] + j] >= 0) findex[ofs[i] + j] += ofs[i];
- }
- }
-
- // compute A = J*invM*J'
-# ifdef TIMING
- dTimerNow ("compute A");
-# endif
- dReal *JinvM = (dReal*) ALLOCA (m*nskip*sizeof(dReal));
- dSetZero (JinvM,m*nskip);
- dMultiply0 (JinvM,J,invM,m,n6,n6);
- int mskip = dPAD(m);
- dReal *A = (dReal*) ALLOCA (m*mskip*sizeof(dReal));
- dSetZero (A,m*mskip);
- dMultiply2 (A,JinvM,J,m,n6,m);
-
- // add cfm to the diagonal of A
- for (i=0; i<m; i++) A[i*mskip+i] += cfm[i] * Jinfo.fps;
-
-# ifdef COMPARE_METHODS
- comparator.nextMatrix (A,m,m,1,"A");
-# endif
-
- // compute `rhs', the right hand side of the equation J*a=c
-# ifdef TIMING
- dTimerNow ("compute rhs");
-# endif
- dReal *tmp1 = (dReal*) ALLOCA (n6 * sizeof(dReal));
- dSetZero (tmp1,n6);
- dMultiply0 (tmp1,invM,fe,n6,n6,1);
- for (i=0; i<n6; i++) tmp1[i] += v[i]/stepsize;
- dReal *rhs = (dReal*) ALLOCA (m * sizeof(dReal));
- dSetZero (rhs,m);
- dMultiply0 (rhs,J,tmp1,m,n6,1);
- for (i=0; i<m; i++) rhs[i] = c[i]/stepsize - rhs[i];
-
-# ifdef COMPARE_METHODS
- comparator.nextMatrix (c,m,1,0,"c");
- comparator.nextMatrix (rhs,m,1,0,"rhs");
-# endif
-
- // solve the LCP problem and get lambda.
- // this will destroy A but that's okay
-# ifdef TIMING
- dTimerNow ("solving LCP problem");
-# endif
- dReal *lambda = (dReal*) ALLOCA (m * sizeof(dReal));
- dReal *residual = (dReal*) ALLOCA (m * sizeof(dReal));
- dSolveLCP (m,A,lambda,rhs,residual,nub,lo,hi,findex);
-
-// OLD WAY - direct factor and solve
-//
-// // factorize A (L*L'=A)
-//# ifdef TIMING
-// dTimerNow ("factorize A");
-//# endif
-// dReal *L = (dReal*) ALLOCA (m*mskip*sizeof(dReal));
-// memcpy (L,A,m*mskip*sizeof(dReal));
-// if (dFactorCholesky (L,m)==0) dDebug (0,"A is not positive definite");
-//
-// // compute lambda
-//# ifdef TIMING
-// dTimerNow ("compute lambda");
-//# endif
-// dReal *lambda = (dReal*) ALLOCA (m * sizeof(dReal));
-// memcpy (lambda,rhs,m * sizeof(dReal));
-// dSolveCholesky (L,lambda,m);
-
-# ifdef COMPARE_METHODS
- comparator.nextMatrix (lambda,m,1,0,"lambda");
-# endif
-
- // compute the velocity update `vnew'
-# ifdef TIMING
- dTimerNow ("compute velocity update");
-# endif
- dMultiply1 (tmp1,J,lambda,n6,m,1);
- for (i=0; i<n6; i++) tmp1[i] += fe[i];
- dMultiply0 (vnew,invM,tmp1,n6,n6,1);
- for (i=0; i<n6; i++) vnew[i] = v[i] + stepsize*vnew[i];
-
- // see if the constraint has worked: compute J*vnew and make sure it equals
- // `c' (to within a certain tolerance).
-# ifdef TIMING
- dTimerNow ("verify constraint equation");
-# endif
- dMultiply0 (tmp1,J,vnew,m,n6,1);
- dReal err = 0;
- for (i=0; i<m; i++) err += dFabs(tmp1[i]-c[i]);
- printf ("%.6e\n",err);
- }
- else {
- // no constraints
- dMultiply0 (vnew,invM,fe,n6,n6,1);
- for (i=0; i<n6; i++) vnew[i] = v[i] + stepsize*vnew[i];
- }
-
-# ifdef COMPARE_METHODS
- comparator.nextMatrix (vnew,n6,1,0,"vnew");
-# endif
-
- // apply the velocity update to the bodies
-# ifdef TIMING
- dTimerNow ("update velocity");
-# endif
- for (i=0; i<nb; i++) {
- for (j=0; j<3; j++) body[i]->lvel[j] = vnew[i*6+j];
- for (j=0; j<3; j++) body[i]->avel[j] = vnew[i*6+3+j];
- }
-
- // update the position and orientation from the new linear/angular velocity
- // (over the given timestep)
-# ifdef TIMING
- dTimerNow ("update position");
-# endif
- for (i=0; i<nb; i++) moveAndRotateBody (body[i],stepsize);
-
-# ifdef TIMING
- dTimerNow ("tidy up");
-# endif
-
- // zero all force accumulators
- for (i=0; i<nb; i++) {
- body[i]->facc[0] = 0;
- body[i]->facc[1] = 0;
- body[i]->facc[2] = 0;
- body[i]->facc[3] = 0;
- body[i]->tacc[0] = 0;
- body[i]->tacc[1] = 0;
- body[i]->tacc[2] = 0;
- body[i]->tacc[3] = 0;
- }
-
-# ifdef TIMING
- dTimerEnd();
- if (m > 0) dTimerReport (stdout,1);
-# endif
-}
-
-//****************************************************************************
-// an optimized version of dInternalStepIsland1()
-
-void dInternalStepIsland_x2 (dxWorld *world, dxBody * const *body, int nb,
- dxJoint * const *_joint, int nj, dReal stepsize)
-{
- int i,j,k;
-# ifdef TIMING
- dTimerStart("preprocessing");
-# endif
-
- dReal stepsize1 = dRecip(stepsize);
-
- // number all bodies in the body list - set their tag values
- for (i=0; i<nb; i++) body[i]->tag = i;
-
- // make a local copy of the joint array, because we might want to modify it.
- // (the "dxJoint *const*" declaration says we're allowed to modify the joints
- // but not the joint array, because the caller might need it unchanged).
- dxJoint **joint = (dxJoint**) ALLOCA (nj * sizeof(dxJoint*));
- memcpy (joint,_joint,nj * sizeof(dxJoint*));
-
- // for all bodies, compute the inertia tensor and its inverse in the global
- // frame, and compute the rotational force and add it to the torque
- // accumulator. I and invI are vertically stacked 3x4 matrices, one per body.
- // @@@ check computation of rotational force.
- dReal *I = (dReal*) ALLOCA (3*nb*4 * sizeof(dReal));
- dReal *invI = (dReal*) ALLOCA (3*nb*4 * sizeof(dReal));
- dSetZero (I,3*nb*4);
- dSetZero (invI,3*nb*4);
- for (i=0; i<nb; i++) {
- dReal tmp[12];
- // compute inertia tensor in global frame
- dMULTIPLY2_333 (tmp,body[i]->mass.I,body[i]->R);
- dMULTIPLY0_333 (I+i*12,body[i]->R,tmp);
- // compute inverse inertia tensor in global frame
- dMULTIPLY2_333 (tmp,body[i]->invI,body[i]->R);
- dMULTIPLY0_333 (invI+i*12,body[i]->R,tmp);
- // compute rotational force
- dMULTIPLY0_331 (tmp,I+i*12,body[i]->avel);
- dCROSS (body[i]->tacc,-=,body[i]->avel,tmp);
- }
-
- // add the gravity force to all bodies
- for (i=0; i<nb; i++) {
- if ((body[i]->flags & dxBodyNoGravity)==0) {
- body[i]->facc[0] += body[i]->mass.mass * world->gravity[0];
- body[i]->facc[1] += body[i]->mass.mass * world->gravity[1];
- body[i]->facc[2] += body[i]->mass.mass * world->gravity[2];
- }
- }
-
- // get m = total constraint dimension, nub = number of unbounded variables.
- // create constraint offset array and number-of-rows array for all joints.
- // the constraints are re-ordered as follows: the purely unbounded
- // constraints, the mixed unbounded + LCP constraints, and last the purely
- // LCP constraints. this assists the LCP solver to put all unbounded
- // variables at the start for a quick factorization.
- //
- // joints with m=0 are inactive and are removed from the joints array
- // entirely, so that the code that follows does not consider them.
- // also number all active joints in the joint list (set their tag values).
- // inactive joints receive a tag value of -1.
-
- int m = 0;
- dxJoint::Info1 *info = (dxJoint::Info1*) ALLOCA (nj*sizeof(dxJoint::Info1));
- int *ofs = (int*) ALLOCA (nj*sizeof(int));
- for (i=0, j=0; j<nj; j++) { // i=dest, j=src
- joint[j]->vtable->getInfo1 (joint[j],info+i);
- dIASSERT (info[i].m >= 0 && info[i].m <= 6 &&
- info[i].nub >= 0 && info[i].nub <= info[i].m);
- if (info[i].m > 0) {
- joint[i] = joint[j];
- joint[i]->tag = i;
- i++;
- }
- else {
- joint[j]->tag = -1;
- }
- }
- nj = i;
-
- // the purely unbounded constraints
- for (i=0; i<nj; i++) if (info[i].nub == info[i].m) {
- ofs[i] = m;
- m += info[i].m;
- }
- int nub = m;
- // the mixed unbounded + LCP constraints
- for (i=0; i<nj; i++) if (info[i].nub > 0 && info[i].nub < info[i].m) {
- ofs[i] = m;
- m += info[i].m;
- }
- // the purely LCP constraints
- for (i=0; i<nj; i++) if (info[i].nub == 0) {
- ofs[i] = m;
- m += info[i].m;
- }
-
- // this will be set to the force due to the constraints
- dReal *cforce = (dReal*) ALLOCA (nb*8 * sizeof(dReal));
- dSetZero (cforce,nb*8);
-
- // if there are constraints, compute cforce
- if (m > 0) {
- // create a constraint equation right hand side vector `c', a constraint
- // force mixing vector `cfm', and LCP low and high bound vectors, and an
- // 'findex' vector.
- dReal *c = (dReal*) ALLOCA (m*sizeof(dReal));
- dReal *cfm = (dReal*) ALLOCA (m*sizeof(dReal));
- dReal *lo = (dReal*) ALLOCA (m*sizeof(dReal));
- dReal *hi = (dReal*) ALLOCA (m*sizeof(dReal));
- int *findex = (int*) alloca (m*sizeof(int));
- dSetZero (c,m);
- dSetValue (cfm,m,world->global_cfm);
- dSetValue (lo,m,-dInfinity);
- dSetValue (hi,m, dInfinity);
- for (i=0; i<m; i++) findex[i] = -1;
-
- // get jacobian data from constraints. a (2*m)x8 matrix will be created
- // to store the two jacobian blocks from each constraint. it has this
- // format:
- //
- // l l l 0 a a a 0 \
- // l l l 0 a a a 0 }-- jacobian body 1 block for joint 0 (3 rows)
- // l l l 0 a a a 0 /
- // l l l 0 a a a 0 \
- // l l l 0 a a a 0 }-- jacobian body 2 block for joint 0 (3 rows)
- // l l l 0 a a a 0 /
- // l l l 0 a a a 0 }--- jacobian body 1 block for joint 1 (1 row)
- // l l l 0 a a a 0 }--- jacobian body 2 block for joint 1 (1 row)
- // etc...
- //
- // (lll) = linear jacobian data
- // (aaa) = angular jacobian data
- //
-# ifdef TIMING
- dTimerNow ("create J");
-# endif
- dReal *J = (dReal*) ALLOCA (2*m*8*sizeof(dReal));
- dSetZero (J,2*m*8);
- dxJoint::Info2 Jinfo;
- Jinfo.rowskip = 8;
- Jinfo.fps = stepsize1;
- Jinfo.erp = world->global_erp;
- for (i=0; i<nj; i++) {
- Jinfo.J1l = J + 2*8*ofs[i];
- Jinfo.J1a = Jinfo.J1l + 4;
- Jinfo.J2l = Jinfo.J1l + 8*info[i].m;
- Jinfo.J2a = Jinfo.J2l + 4;
- Jinfo.c = c + ofs[i];
- Jinfo.cfm = cfm + ofs[i];
- Jinfo.lo = lo + ofs[i];
- Jinfo.hi = hi + ofs[i];
- Jinfo.findex = findex + ofs[i];
- joint[i]->vtable->getInfo2 (joint[i],&Jinfo);
- // adjust returned findex values for global index numbering
- for (j=0; j<info[i].m; j++) {
- if (findex[ofs[i] + j] >= 0) findex[ofs[i] + j] += ofs[i];
- }
- }
-
- // compute A = J*invM*J'. first compute JinvM = J*invM. this has the same
- // format as J so we just go through the constraints in J multiplying by
- // the appropriate scalars and matrices.
-# ifdef TIMING
- dTimerNow ("compute A");
-# endif
- dReal *JinvM = (dReal*) ALLOCA (2*m*8*sizeof(dReal));
- dSetZero (JinvM,2*m*8);
- for (i=0; i<nj; i++) {
- int b = joint[i]->node[0].body->tag;
- dReal body_invMass = body[b]->invMass;
- dReal *body_invI = invI + b*12;
- dReal *Jsrc = J + 2*8*ofs[i];
- dReal *Jdst = JinvM + 2*8*ofs[i];
- for (j=info[i].m-1; j>=0; j--) {
- for (k=0; k<3; k++) Jdst[k] = Jsrc[k] * body_invMass;
- dMULTIPLY0_133 (Jdst+4,Jsrc+4,body_invI);
- Jsrc += 8;
- Jdst += 8;
- }
- if (joint[i]->node[1].body) {
- b = joint[i]->node[1].body->tag;
- body_invMass = body[b]->invMass;
- body_invI = invI + b*12;
- for (j=info[i].m-1; j>=0; j--) {
- for (k=0; k<3; k++) Jdst[k] = Jsrc[k] * body_invMass;
- dMULTIPLY0_133 (Jdst+4,Jsrc+4,body_invI);
- Jsrc += 8;
- Jdst += 8;
- }
- }
- }
-
- // now compute A = JinvM * J'. A's rows and columns are grouped by joint,
- // i.e. in the same way as the rows of J. block (i,j) of A is only nonzero
- // if joints i and j have at least one body in common. this fact suggests
- // the algorithm used to fill A:
- //
- // for b = all bodies
- // n = number of joints attached to body b
- // for i = 1..n
- // for j = i+1..n
- // ii = actual joint number for i
- // jj = actual joint number for j
- // // (ii,jj) will be set to all pairs of joints around body b
- // compute blockwise: A(ii,jj) += JinvM(ii) * J(jj)'
- //
- // this algorithm catches all pairs of joints that have at least one body
- // in common. it does not compute the diagonal blocks of A however -
- // another similar algorithm does that.
-
- int mskip = dPAD(m);
- dReal *A = (dReal*) ALLOCA (m*mskip*sizeof(dReal));
- dSetZero (A,m*mskip);
- for (i=0; i<nb; i++) {
- for (dxJointNode *n1=body[i]->firstjoint; n1; n1=n1->next) {
- for (dxJointNode *n2=n1->next; n2; n2=n2->next) {
- // get joint numbers and ensure ofs[j1] >= ofs[j2]
- int j1 = n1->joint->tag;
- int j2 = n2->joint->tag;
- if (ofs[j1] < ofs[j2]) {
- int tmp = j1;
- j1 = j2;
- j2 = tmp;
- }
-
- // if either joint was tagged as -1 then it is an inactive (m=0)
- // joint that should not be considered
- if (j1==-1 || j2==-1) continue;
-
- // determine if body i is the 1st or 2nd body of joints j1 and j2
- int jb1 = (joint[j1]->node[1].body == body[i]);
- int jb2 = (joint[j2]->node[1].body == body[i]);
- // jb1/jb2 must be 0 for joints with only one body
- dIASSERT(joint[j1]->node[1].body || jb1==0);
- dIASSERT(joint[j2]->node[1].body || jb2==0);
-
- // set block of A
- MultiplyAdd2_p8r (A + ofs[j1]*mskip + ofs[j2],
- JinvM + 2*8*ofs[j1] + jb1*8*info[j1].m,
- J + 2*8*ofs[j2] + jb2*8*info[j2].m,
- info[j1].m,info[j2].m, mskip);
- }
- }
- }
- // compute diagonal blocks of A
- for (i=0; i<nj; i++) {
- Multiply2_p8r (A + ofs[i]*(mskip+1),
- JinvM + 2*8*ofs[i],
- J + 2*8*ofs[i],
- info[i].m,info[i].m, mskip);
- if (joint[i]->node[1].body) {
- MultiplyAdd2_p8r (A + ofs[i]*(mskip+1),
- JinvM + 2*8*ofs[i] + 8*info[i].m,
- J + 2*8*ofs[i] + 8*info[i].m,
- info[i].m,info[i].m, mskip);
- }
- }
-
- // add cfm to the diagonal of A
- for (i=0; i<m; i++) A[i*mskip+i] += cfm[i] * stepsize1;
-
-# ifdef COMPARE_METHODS
- comparator.nextMatrix (A,m,m,1,"A");
-# endif
-
- // compute the right hand side `rhs'
-# ifdef TIMING
- dTimerNow ("compute rhs");
-# endif
- dReal *tmp1 = (dReal*) ALLOCA (nb*8 * sizeof(dReal));
- dSetZero (tmp1,nb*8);
- // put v/h + invM*fe into tmp1
- for (i=0; i<nb; i++) {
- dReal body_invMass = body[i]->invMass;
- dReal *body_invI = invI + i*12;
- for (j=0; j<3; j++) tmp1[i*8+j] = body[i]->facc[j] * body_invMass +
- body[i]->lvel[j] * stepsize1;
- dMULTIPLY0_331 (tmp1 + i*8 + 4,body_invI,body[i]->tacc);
- for (j=0; j<3; j++) tmp1[i*8+4+j] += body[i]->avel[j] * stepsize1;
- }
- // put J*tmp1 into rhs
- dReal *rhs = (dReal*) ALLOCA (m * sizeof(dReal));
- dSetZero (rhs,m);
- for (i=0; i<nj; i++) {
- dReal *JJ = J + 2*8*ofs[i];
- Multiply0_p81 (rhs+ofs[i],JJ,
- tmp1 + 8*joint[i]->node[0].body->tag, info[i].m);
- if (joint[i]->node[1].body) {
- MultiplyAdd0_p81 (rhs+ofs[i],JJ + 8*info[i].m,
- tmp1 + 8*joint[i]->node[1].body->tag, info[i].m);
- }
- }
- // complete rhs
- for (i=0; i<m; i++) rhs[i] = c[i]*stepsize1 - rhs[i];
-
-# ifdef COMPARE_METHODS
- comparator.nextMatrix (c,m,1,0,"c");
- comparator.nextMatrix (rhs,m,1,0,"rhs");
-# endif
-
- // solve the LCP problem and get lambda.
- // this will destroy A but that's okay
-# ifdef TIMING
- dTimerNow ("solving LCP problem");
-# endif
- dReal *lambda = (dReal*) ALLOCA (m * sizeof(dReal));
- dReal *residual = (dReal*) ALLOCA (m * sizeof(dReal));
- dSolveLCP (m,A,lambda,rhs,residual,nub,lo,hi,findex);
-
-// OLD WAY - direct factor and solve
-//
-// // factorize A (L*L'=A)
-//# ifdef TIMING
-// dTimerNow ("factorize A");
-//# endif
-// dReal *L = (dReal*) ALLOCA (m*mskip*sizeof(dReal));
-// memcpy (L,A,m*mskip*sizeof(dReal));
-//# ifdef FAST_FACTOR
-// dFastFactorCholesky (L,m); // does not report non positive definiteness
-//# else
-// if (dFactorCholesky (L,m)==0) dDebug (0,"A is not positive definite");
-//# endif
-//
-// // compute lambda
-//# ifdef TIMING
-// dTimerNow ("compute lambda");
-//# endif
-// dReal *lambda = (dReal*) ALLOCA (m * sizeof(dReal));
-// memcpy (lambda,rhs,m * sizeof(dReal));
-// dSolveCholesky (L,lambda,m);
-
-# ifdef COMPARE_METHODS
- comparator.nextMatrix (lambda,m,1,0,"lambda");
-# endif
-
- // compute the constraint force `cforce'
-# ifdef TIMING
- dTimerNow ("compute constraint force");
-# endif
- // compute cforce = J'*lambda
- for (i=0; i<nj; i++) {
- dReal *JJ = J + 2*8*ofs[i];
- dxBody* b1 = joint[i]->node[0].body;
- dxBody* b2 = joint[i]->node[1].body;
- dJointFeedback *fb = joint[i]->feedback;
-
- if (fb) {
- // the user has requested feedback on the amount of force that this
- // joint is applying to the bodies. we use a slightly slower
- // computation that splits out the force components and puts them
- // in the feedback structure.
- dReal data1[8],data2[8];
- Multiply1_8q1 (data1, JJ, lambda+ofs[i], info[i].m);
- dReal *cf1 = cforce + 8*b1->tag;
- cf1[0] += (fb->f1[0] = data1[0]);
- cf1[1] += (fb->f1[1] = data1[1]);
- cf1[2] += (fb->f1[2] = data1[2]);
- cf1[4] += (fb->t1[0] = data1[4]);
- cf1[5] += (fb->t1[1] = data1[5]);
- cf1[6] += (fb->t1[2] = data1[6]);
- if (b2){
- Multiply1_8q1 (data2, JJ + 8*info[i].m, lambda+ofs[i], info[i].m);
- dReal *cf2 = cforce + 8*b2->tag;
- cf2[0] += (fb->f2[0] = data2[0]);
- cf2[1] += (fb->f2[1] = data2[1]);
- cf2[2] += (fb->f2[2] = data2[2]);
- cf2[4] += (fb->t2[0] = data2[4]);
- cf2[5] += (fb->t2[1] = data2[5]);
- cf2[6] += (fb->t2[2] = data2[6]);
- }
- }
- else {
- // no feedback is required, let's compute cforce the faster way
- MultiplyAdd1_8q1 (cforce + 8*b1->tag,JJ, lambda+ofs[i], info[i].m);
- if (b2) {
- MultiplyAdd1_8q1 (cforce + 8*b2->tag,
- JJ + 8*info[i].m, lambda+ofs[i], info[i].m);
- }
- }
- }
- }
-
- // compute the velocity update
-# ifdef TIMING
- dTimerNow ("compute velocity update");
-# endif
-
- // add fe to cforce
- for (i=0; i<nb; i++) {
- for (j=0; j<3; j++) cforce[i*8+j] += body[i]->facc[j];
- for (j=0; j<3; j++) cforce[i*8+4+j] += body[i]->tacc[j];
- }
- // multiply cforce by stepsize
- for (i=0; i < nb*8; i++) cforce[i] *= stepsize;
- // add invM * cforce to the body velocity
- for (i=0; i<nb; i++) {
- dReal body_invMass = body[i]->invMass;
- dReal *body_invI = invI + i*12;
- for (j=0; j<3; j++) body[i]->lvel[j] += body_invMass * cforce[i*8+j];
- dMULTIPLYADD0_331 (body[i]->avel,body_invI,cforce+i*8+4);
- }
-
- // update the position and orientation from the new linear/angular velocity
- // (over the given timestep)
-# ifdef TIMING
- dTimerNow ("update position");
-# endif
- for (i=0; i<nb; i++) moveAndRotateBody (body[i],stepsize);
-
-# ifdef COMPARE_METHODS
- dReal *tmp_vnew = (dReal*) ALLOCA (nb*6*sizeof(dReal));
- for (i=0; i<nb; i++) {
- for (j=0; j<3; j++) tmp_vnew[i*6+j] = body[i]->lvel[j];
- for (j=0; j<3; j++) tmp_vnew[i*6+3+j] = body[i]->avel[j];
- }
- comparator.nextMatrix (tmp_vnew,nb*6,1,0,"vnew");
-# endif
-
-# ifdef TIMING
- dTimerNow ("tidy up");
-# endif
-
- // zero all force accumulators
- for (i=0; i<nb; i++) {
- body[i]->facc[0] = 0;
- body[i]->facc[1] = 0;
- body[i]->facc[2] = 0;
- body[i]->facc[3] = 0;
- body[i]->tacc[0] = 0;
- body[i]->tacc[1] = 0;
- body[i]->tacc[2] = 0;
- body[i]->tacc[3] = 0;
- }
-
-# ifdef TIMING
- dTimerEnd();
- if (m > 0) dTimerReport (stdout,1);
-# endif
-}
-
-//****************************************************************************
-
-void dInternalStepIsland (dxWorld *world, dxBody * const *body, int nb,
- dxJoint * const *joint, int nj, dReal stepsize)
-{
-# ifndef COMPARE_METHODS
- dInternalStepIsland_x2 (world,body,nb,joint,nj,stepsize);
-# endif
-
-# ifdef COMPARE_METHODS
- int i;
-
- // save body state
- dxBody *state = (dxBody*) ALLOCA (nb*sizeof(dxBody));
- for (i=0; i<nb; i++) memcpy (state+i,body[i],sizeof(dxBody));
-
- // take slow step
- comparator.reset();
- dInternalStepIsland_x1 (world,body,nb,joint,nj,stepsize);
- comparator.end();
-
- // restore state
- for (i=0; i<nb; i++) memcpy (body[i],state+i,sizeof(dxBody));
-
- // take fast step
- dInternalStepIsland_x2 (world,body,nb,joint,nj,stepsize);
- comparator.end();
-
- //comparator.dump();
- //_exit (1);
-# endif
-}
diff --git a/extern/ode/dist/ode/src/step.h b/extern/ode/dist/ode/src/step.h
deleted file mode 100644
index c825a11c1dc..00000000000
--- a/extern/ode/dist/ode/src/step.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#ifndef _ODE_STEP_H_
-#define _ODE_STEP_H_
-
-#include <ode/common.h>
-
-
-void dInternalStepIsland (dxWorld *world,
- dxBody * const *body, int nb,
- dxJoint * const *joint, int nj,
- dReal stepsize);
-
-
-
-#endif
-
diff --git a/extern/ode/dist/ode/src/testing.cpp b/extern/ode/dist/ode/src/testing.cpp
deleted file mode 100644
index d55afc25257..00000000000
--- a/extern/ode/dist/ode/src/testing.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-#include <ode/config.h>
-#include <ode/misc.h>
-#include <ode/memory.h>
-#include "testing.h"
-
-#ifdef dDOUBLE
-static const dReal tol = 1.0e-9;
-#else
-static const dReal tol = 1.0e-5f;
-#endif
-
-
-// matrix header on the stack
-
-struct dMatrixComparison::dMatInfo {
- int n,m; // size of matrix
- char name[128]; // name of the matrix
- dReal *data; // matrix data
- int size; // size of `data'
-};
-
-
-
-dMatrixComparison::dMatrixComparison()
-{
- afterfirst = 0;
- index = 0;
-}
-
-
-dMatrixComparison::~dMatrixComparison()
-{
- reset();
-}
-
-
-dReal dMatrixComparison::nextMatrix (dReal *A, int n, int m, int lower_tri,
- char *name, ...)
-{
- if (A==0 || n < 1 || m < 1 || name==0) dDebug (0,"bad args to nextMatrix");
- int num = n*dPAD(m);
-
- if (afterfirst==0) {
- dMatInfo *mi = (dMatInfo*) dAlloc (sizeof(dMatInfo));
- mi->n = n;
- mi->m = m;
- mi->size = num * sizeof(dReal);
- mi->data = (dReal*) dAlloc (mi->size);
- memcpy (mi->data,A,mi->size);
-
- va_list ap;
- va_start (ap,name);
- vsprintf (mi->name,name,ap);
- if (strlen(mi->name) >= sizeof (mi->name)) dDebug (0,"name too long");
-
- mat.push (mi);
- return 0;
- }
- else {
- if (lower_tri && n != m)
- dDebug (0,"dMatrixComparison, lower triangular matrix must be square");
- if (index >= mat.size()) dDebug (0,"dMatrixComparison, too many matrices");
- dMatInfo *mp = mat[index];
- index++;
-
- dMatInfo mi;
- va_list ap;
- va_start (ap,name);
- vsprintf (mi.name,name,ap);
- if (strlen(mi.name) >= sizeof (mi.name)) dDebug (0,"name too long");
-
- if (strcmp(mp->name,mi.name) != 0)
- dDebug (0,"dMatrixComparison, name mismatch (\"%s\" and \"%s\")",
- mp->name,mi.name);
- if (mp->n != n || mp->m != m)
- dDebug (0,"dMatrixComparison, size mismatch (%dx%d and %dx%d)",
- mp->n,mp->m,n,m);
-
- dReal maxdiff;
- if (lower_tri) {
- maxdiff = dMaxDifferenceLowerTriangle (A,mp->data,n);
- }
- else {
- maxdiff = dMaxDifference (A,mp->data,n,m);
- }
- if (maxdiff > tol)
- dDebug (0,"dMatrixComparison, matrix error (size=%dx%d, name=\"%s\", "
- "error=%.4e)",n,m,mi.name,maxdiff);
- return maxdiff;
- }
-}
-
-
-void dMatrixComparison::end()
-{
- if (mat.size() <= 0) dDebug (0,"no matrices in sequence");
- afterfirst = 1;
- index = 0;
-}
-
-
-void dMatrixComparison::reset()
-{
- for (int i=0; i<mat.size(); i++) {
- dFree (mat[i]->data,mat[i]->size);
- dFree (mat[i],sizeof(dMatInfo));
- }
- mat.setSize (0);
- afterfirst = 0;
- index = 0;
-}
-
-
-void dMatrixComparison::dump()
-{
- for (int i=0; i<mat.size(); i++)
- printf ("%d: %s (%dx%d)\n",i,mat[i]->name,mat[i]->n,mat[i]->m);
-}
-
-//****************************************************************************
-// unit test
-
-#include <setjmp.h>
-
-static jmp_buf jump_buffer;
-
-static void myDebug (int num, const char *msg, va_list ap)
-{
- // printf ("(Error %d: ",num);
- // vprintf (msg,ap);
- // printf (")\n");
- longjmp (jump_buffer,1);
-}
-
-
-extern "C" void dTestMatrixComparison()
-{
- volatile int i;
- printf ("dTestMatrixComparison()\n");
- dMessageFunction *orig_debug = dGetDebugHandler();
-
- dMatrixComparison mc;
- dReal A[50*50];
-
- // make first sequence
- unsigned long seed = dRandGetSeed();
- for (i=1; i<49; i++) {
- dMakeRandomMatrix (A,i,i+1,1.0);
- mc.nextMatrix (A,i,i+1,0,"A%d",i);
- }
- mc.end();
-
- //mc.dump();
-
- // test identical sequence
- dSetDebugHandler (&myDebug);
- dRandSetSeed (seed);
- if (setjmp (jump_buffer)) {
- printf ("\tFAILED (1)\n");
- }
- else {
- for (i=1; i<49; i++) {
- dMakeRandomMatrix (A,i,i+1,1.0);
- mc.nextMatrix (A,i,i+1,0,"A%d",i);
- }
- mc.end();
- printf ("\tpassed (1)\n");
- }
- dSetDebugHandler (orig_debug);
-
- // test broken sequences (with matrix error)
- dRandSetSeed (seed);
- volatile int passcount = 0;
- for (i=1; i<49; i++) {
- if (setjmp (jump_buffer)) {
- passcount++;
- }
- else {
- dSetDebugHandler (&myDebug);
- dMakeRandomMatrix (A,i,i+1,1.0);
- A[(i-1)*dPAD(i+1)+i] += REAL(0.01);
- mc.nextMatrix (A,i,i+1,0,"A%d",i);
- dSetDebugHandler (orig_debug);
- }
- }
- mc.end();
- printf ("\t%s (2)\n",(passcount == 48) ? "passed" : "FAILED");
-
- // test broken sequences (with name error)
- dRandSetSeed (seed);
- passcount = 0;
- for (i=1; i<49; i++) {
- if (setjmp (jump_buffer)) {
- passcount++;
- }
- else {
- dSetDebugHandler (&myDebug);
- dMakeRandomMatrix (A,i,i+1,1.0);
- mc.nextMatrix (A,i,i+1,0,"B%d",i);
- dSetDebugHandler (orig_debug);
- }
- }
- mc.end();
- printf ("\t%s (3)\n",(passcount == 48) ? "passed" : "FAILED");
-
- // test identical sequence again
- dSetDebugHandler (&myDebug);
- dRandSetSeed (seed);
- if (setjmp (jump_buffer)) {
- printf ("\tFAILED (4)\n");
- }
- else {
- for (i=1; i<49; i++) {
- dMakeRandomMatrix (A,i,i+1,1.0);
- mc.nextMatrix (A,i,i+1,0,"A%d",i);
- }
- mc.end();
- printf ("\tpassed (4)\n");
- }
- dSetDebugHandler (orig_debug);
-}
diff --git a/extern/ode/dist/ode/src/testing.h b/extern/ode/dist/ode/src/testing.h
deleted file mode 100644
index aa4acf119db..00000000000
--- a/extern/ode/dist/ode/src/testing.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/* stuff used for testing */
-
-#ifndef _ODE_TESTING_H_
-#define _ODE_TESTING_H_
-
-#include <ode/common.h>
-#include "array.h"
-
-
-// compare a sequence of named matrices/vectors, i.e. to make sure that two
-// different pieces of code are giving the same results.
-
-class dMatrixComparison {
- struct dMatInfo;
- dArray<dMatInfo*> mat;
- int afterfirst,index;
-
-public:
- dMatrixComparison();
- ~dMatrixComparison();
-
- dReal nextMatrix (dReal *A, int n, int m, int lower_tri, char *name, ...);
- // add a new n*m matrix A to the sequence. the name of the matrix is given
- // by the printf-style arguments (name,...). if this is the first sequence
- // then this object will simply record the matrices and return 0.
- // if this the second or subsequent sequence then this object will compare
- // the matrices with the first sequence, and report any differences.
- // the matrix error will be returned. if `lower_tri' is 1 then only the
- // lower triangle of the matrix (including the diagonal) will be compared
- // (the matrix must be square).
-
- void end();
- // end a sequence.
-
- void reset();
- // restarts the object, so the next sequence will be the first sequence.
-
- void dump();
- // print out info about all the matrices in the sequence
-};
-
-
-#endif
-
diff --git a/extern/ode/dist/ode/src/timer.cpp b/extern/ode/dist/ode/src/timer.cpp
deleted file mode 100644
index 87cb9f6f2fe..00000000000
--- a/extern/ode/dist/ode/src/timer.cpp
+++ /dev/null
@@ -1,397 +0,0 @@
-/*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: russ@q12.org Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library 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 files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
-
-/*
-
-TODO
-----
-
-* gettimeofday() and the pentium time stamp counter return the real time,
- not the process time. fix this somehow!
-
-*/
-
-#include <ode/common.h>
-#include <ode/timer.h>
-
-// misc defines
-#define ALLOCA dALLOCA16
-
-//****************************************************************************
-// implementation for windows based on the multimedia performance counter.
-
-#ifdef WIN32
-
-#include "windows.h"
-
-static inline void getClockCount (unsigned long cc[2])
-{
- LARGE_INTEGER a;
- QueryPerformanceCounter (&a);
- cc[0] = a.LowPart;
- cc[1] = a.HighPart;
-}
-
-
-static inline void serialize()
-{
-}
-
-
-static inline double loadClockCount (unsigned long cc[2])
-{
- LARGE_INTEGER a;
- a.LowPart = cc[0];
- a.HighPart = cc[1];
- return double(a.QuadPart);
-}
-
-
-double dTimerResolution()
-{
- return 1.0/dTimerTicksPerSecond();
-}
-
-
-double dTimerTicksPerSecond()
-{
- static int query=0;
- static double hz=0.0;
- if (!query) {
- LARGE_INTEGER a;
- QueryPerformanceFrequency (&a);
- hz = double(a.QuadPart);
- query = 1;
- }
- return hz;
-}
-
-#endif
-
-//****************************************************************************
-// implementation based on the pentium time stamp counter. the timer functions
-// can be serializing or non-serializing. serializing will ensure that all
-// instructions have executed and data has been written back before the cpu
-// time stamp counter is read. the CPUID instruction is used to serialize.
-
-#if defined(PENTIUM) && !defined(WIN32)
-
-// we need to know the clock rate so that the timing function can report
-// accurate times. this number only needs to be set accurately if we're
-// doing performance tests and care about real-world time numbers - otherwise,
-// just ignore this. i have not worked out how to determine this number
-// automatically yet.
-
-#define PENTIUM_HZ (500e6)
-
-
-static inline void getClockCount (unsigned long cc[2])
-{
- asm volatile ("\n\
- rdtsc\n\
- movl %%eax,(%%esi)\n\
- movl %%edx,4(%%esi)"
- : : "S" (cc) : "%eax","%edx","cc","memory");
-}
-
-
-static inline void serialize()
-{
- asm volatile ("\n\
- mov $0,%%eax\n\
- cpuid"
- : : : "%eax","%ebx","%ecx","%edx","cc","memory");
-}
-
-
-static inline double loadClockCount (unsigned long a[2])
-{
- double ret;
- asm volatile ("fildll %1; fstpl %0" : "=m" (ret) : "m" (a[0]) :
- "cc","memory");
- return ret;
-}
-
-
-double dTimerResolution()
-{
- return 1.0/PENTIUM_HZ;
-}
-
-
-double dTimerTicksPerSecond()
-{
- return PENTIUM_HZ;
-}
-
-#endif
-
-//****************************************************************************
-// otherwise, do the implementation based on gettimeofday().
-
-#if !defined(PENTIUM) && !defined(WIN32)
-
-#ifndef macintosh
-
-#include <sys/time.h>
-#include <unistd.h>
-
-
-static inline void getClockCount (unsigned long cc[2])
-{
- struct timeval tv;
- gettimeofday (&tv,0);
- cc[0] = tv.tv_usec;
- cc[1] = tv.tv_sec;
-}
-
-#else // macintosh
-
-#include <MacTypes.h>
-#include <Timer.h>
-
-static inline void getClockCount (unsigned long cc[2])
-{
- UnsignedWide ms;
- Microseconds (&ms);
- cc[1] = ms.lo / 1000000;
- cc[0] = ms.lo - ( cc[1] * 1000000 );
-}
-
-#endif
-
-
-static inline void serialize()
-{
-}
-
-
-static inline double loadClockCount (unsigned long a[2])
-{
- return a[1]*1.0e6 + a[0];
-}
-
-
-double dTimerResolution()
-{
- unsigned long cc1[2],cc2[2];
- getClockCount (cc1);
- do {
- getClockCount (cc2);
- }
- while (cc1[0]==cc2[0] && cc1[1]==cc2[1]);
- do {
- getClockCount (cc1);
- }
- while (cc1[0]==cc2[0] && cc1[1]==cc2[1]);
- double t1 = loadClockCount (cc1);
- double t2 = loadClockCount (cc2);
- return (t1-t2) / dTimerTicksPerSecond();
-}
-
-
-double dTimerTicksPerSecond()
-{
- return 1000000;
-}
-
-#endif
-
-//****************************************************************************
-// stop watches
-
-void dStopwatchReset (dStopwatch *s)
-{
- s->time = 0;
- s->cc[0] = 0;
- s->cc[1] = 0;
-}
-
-
-void dStopwatchStart (dStopwatch *s)
-{
- serialize();
- getClockCount (s->cc);
-}
-
-
-void dStopwatchStop (dStopwatch *s)
-{
- unsigned long cc[2];
- serialize();
- getClockCount (cc);
- double t1 = loadClockCount (s->cc);
- double t2 = loadClockCount (cc);
- s->time += t2-t1;
-}
-
-
-double dStopwatchTime (dStopwatch *s)
-{
- return s->time / dTimerTicksPerSecond();
-}
-
-//****************************************************************************
-// code timers
-
-// maximum number of events to record
-#define MAXNUM 100
-
-static int num = 0; // number of entries used in event array
-static struct {
- unsigned long cc[2]; // clock counts
- double total_t; // total clocks used in this slot.
- double total_p; // total percentage points used in this slot.
- int count; // number of times this slot has been updated.
- char *description; // pointer to static string
-} event[MAXNUM];
-
-
-// make sure all slot totals and counts reset to 0 at start
-
-static void initSlots()
-{
- static int initialized=0;
- if (!initialized) {
- for (int i=0; i<MAXNUM; i++) {
- event[i].count = 0;
- event[i].total_t = 0;
- event[i].total_p = 0;
- }
- initialized = 1;
- }
-}
-
-
-void dTimerStart (const char *description)
-{
- initSlots();
- event[0].description = const_cast<char*> (description);
- num = 1;
- serialize();
- getClockCount (event[0].cc);
-}
-
-
-void dTimerNow (const char *description)
-{
- if (num < MAXNUM) {
- // do not serialize
- getClockCount (event[num].cc);
- event[num].description = const_cast<char*> (description);
- num++;
- }
-}
-
-
-void dTimerEnd()
-{
- if (num < MAXNUM) {
- serialize();
- getClockCount (event[num].cc);
- event[num].description = "TOTAL";
- num++;
- }
-}
-
-//****************************************************************************
-// print report
-
-static void fprintDoubleWithPrefix (FILE *f, double a, char *fmt)
-{
- if (a >= 0.999999) {
- fprintf (f,fmt,a);
- return;
- }
- a *= 1000.0;
- if (a >= 0.999999) {
- fprintf (f,fmt,a);
- fprintf (f,"m");
- return;
- }
- a *= 1000.0;
- if (a >= 0.999999) {
- fprintf (f,fmt,a);
- fprintf (f,"u");
- return;
- }
- a *= 1000.0;
- fprintf (f,fmt,a);
- fprintf (f,"n");
-}
-
-
-void dTimerReport (FILE *fout, int average)
-{
- int i,maxl;
- double ccunit = 1.0/dTimerTicksPerSecond();
- fprintf (fout,"\nTimer Report (");
- fprintDoubleWithPrefix (fout,ccunit,"%.2f ");
- fprintf (fout,"s resolution)\n------------\n");
- if (num < 1) return;
-
- // get maximum description length
- maxl = 0;
- for (i=0; i<num; i++) {
- int l = strlen (event[i].description);
- if (l > maxl) maxl = l;
- }
-
- // calculate total time
- double t1 = loadClockCount (event[0].cc);
- double t2 = loadClockCount (event[num-1].cc);
- double total = t2 - t1;
- if (total <= 0) total = 1;
-
- // compute time difference for all slots except the last one. update totals
- double *times = (double*) ALLOCA (num * sizeof(double));
- for (i=0; i < (num-1); i++) {
- double t1 = loadClockCount (event[i].cc);
- double t2 = loadClockCount (event[i+1].cc);
- times[i] = t2 - t1;
- event[i].count++;
- event[i].total_t += times[i];
- event[i].total_p += times[i]/total * 100.0;
- }
-
- // print report (with optional averages)
- for (i=0; i<num; i++) {
- double t,p;
- if (i < (num-1)) {
- t = times[i];
- p = t/total * 100.0;
- }
- else {
- t = total;
- p = 100.0;
- }
- fprintf (fout,"%-*s %7.2fms %6.2f%%",maxl,event[i].description,
- t*ccunit * 1000.0, p);
- if (average && i < (num-1)) {
- fprintf (fout," (avg %7.2fms %6.2f%%)",
- (event[i].total_t / event[i].count)*ccunit * 1000.0,
- event[i].total_p / event[i].count);
- }
- fprintf (fout,"\n");
- }
- fprintf (fout,"\n");
-}
diff --git a/extern/ode/dist/tools/build4 b/extern/ode/dist/tools/build4
deleted file mode 100755
index 49831e2df35..00000000000
--- a/extern/ode/dist/tools/build4
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/sh
-#
-# build all four precision/release configurations and log the build messages
-# (used for debugging).
-
-PLATFORM=unix-gcc
-SETTINGS=config/user-settings
-
-if [ ! -f ode/src/ode.cpp ]; then
- echo "run this from the ODE root directory"
- exit 1
-fi
-
-function build() {
-echo -e "$PRECISION $MODE\n\n" >> BUILD_LOG
-cat <<END > $SETTINGS
-PLATFORM=$PLATFORM
-PRECISION=$PRECISION
-BUILD=$MODE
-END
-make clean
-make >> BUILD_LOG 2>&1
-echo -e "\n\n---------------------------------------------\n\n" >> BUILD_LOG
-}
-
-echo > BUILD_LOG
-
-PRECISION=SINGLE
-MODE=debug
-build
-PRECISION=SINGLE
-MODE=release
-build
-PRECISION=DOUBLE
-MODE=debug
-build
-PRECISION=DOUBLE
-MODE=release
-build
-
-make clean
-rm -f $SETTINGS
diff --git a/extern/ode/dist/tools/build4.bat b/extern/ode/dist/tools/build4.bat
deleted file mode 100755
index c87e9a9e2ba..00000000000
--- a/extern/ode/dist/tools/build4.bat
+++ /dev/null
@@ -1,43 +0,0 @@
-@echo off
-rem build all four precision/release configurations and log the build messages
-rem (used for debugging).
-
-setlocal
-
-set PLATFORM=cygwin
-set SETTINGS=config\user-settings
-
-echo SINGLE debug > BUILD_LOG
-echo PLATFORM=%PLATFORM%> %SETTINGS%
-echo PRECISION=SINGLE>> %SETTINGS%
-echo BUILD=debug>> %SETTINGS%
-make clean
-make >> BUILD_LOG
-echo --------------------------------------------- >> BUILD_LOG
-
-echo DOUBLE debug >> BUILD_LOG
-echo PLATFORM=%PLATFORM%> %SETTINGS%
-echo PRECISION=DOUBLE>> %SETTINGS%
-echo BUILD=debug>> %SETTINGS%
-make clean
-make >> BUILD_LOG
-echo --------------------------------------------- >> BUILD_LOG
-
-echo SINGLE release >> BUILD_LOG
-echo PLATFORM=%PLATFORM%> %SETTINGS%
-echo PRECISION=SINGLE>> %SETTINGS%
-echo BUILD=release>> %SETTINGS%
-make clean
-make >> BUILD_LOG
-echo --------------------------------------------- >> BUILD_LOG
-
-echo DOUBLE release >> BUILD_LOG
-echo PLATFORM=%PLATFORM%> %SETTINGS%
-echo PRECISION=DOUBLE>> %SETTINGS%
-echo BUILD=release>> %SETTINGS%
-make clean
-make >> BUILD_LOG
-echo --------------------------------------------- >> BUILD_LOG
-
-make clean
-del %SETTINGS%
diff --git a/extern/ode/dist/tools/make_distribution b/extern/ode/dist/tools/make_distribution
deleted file mode 100755
index ed6d52bcbfd..00000000000
--- a/extern/ode/dist/tools/make_distribution
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-
-VER=0.03
-# VER=`date +%y%m%d`
-
-if [ ! -f ode/src/ode.cpp ]; then
- echo "run this from the ODE root directory"
- exit 1
-fi
-
-ODE_DIR=`pwd`
-
-cd /tmp
-if [ -d /tmp/ode-$VER ]; then
- echo "remove /tmp/ode-$VER first"
- exit 1
-fi
-
-mkdir /tmp/ode-$VER
-cp -av $ODE_DIR/* /tmp/ode-$VER
-find /tmp/ode-$VER -type d -name CVS -exec rm -rf {} \; -print
-find /tmp/ode-$VER -type f -name *~ -exec rm -f {} \; -print
-rmdir /tmp/ode-$VER/build
-
-cd /tmp/ode-$VER
-make clean
-cp config/user-settings.example config/user-settings
-
-cd ode/doc
-./doccer ode.doc > ode.html
-
-cd /tmp/ode-$VER
-echo -e "\n\nMake any modifications you want, then exit the shell:"
-bash
-
-cd /tmp
-tar cfvz ode-$VER.tgz ode-$VER
-rm -rf /tmp/ode-$VER
-
-echo -e "\ntype <return> to exit or 'c' to copy to q12"
-read Q
-if [ $Q ]; then
- echo copying...
- scp1 ode-$VER.tgz q12.org:~/q12/ode/release/
-fi
diff --git a/extern/ode/dist/tools/process_deps b/extern/ode/dist/tools/process_deps
deleted file mode 100755
index 9b95ddac382..00000000000
--- a/extern/ode/dist/tools/process_deps
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/perl
-
-$a = join ('',<STDIN>);
-$a =~ s/\\\n/ /g; # join continued lines
-$a =~ s/(^\S+:)/$ARGV[0]$1/gm; # put prefix in front of rules
-$a =~ s/\s+\/\S+/ /g; # remove absolute path dependencies
-$a =~ s/\s+\n/\n/g; # remove whitespace at end of lines
-$a =~ s/[ \t]+/ /g; # clean up interior whitespace
-$a =~ s/ / \\\n /g; # put back line continuations
-
-print $a;
diff --git a/extern/ode/patchfile.FreeBSD b/extern/ode/patchfile.FreeBSD
deleted file mode 100644
index 1725a3acc45..00000000000
--- a/extern/ode/patchfile.FreeBSD
+++ /dev/null
@@ -1,22 +0,0 @@
---- dist/Makefile.org Sat Jan 11 23:55:46 2003
-+++ dist/Makefile Sat Jan 11 23:55:36 2003
-@@ -242,14 +242,16 @@
- clean:
- -$(DEL_CMD) $(ODE_OBJECTS) $(ODE_TEST_EXE) $(ODE_LIB) $(DRAWSTUFF_OBJECTS) $(DRAWSTUFF_TEST_EXE) $(DRAWSTUFF_LIB) ode/test/*$(OBJ) drawstuff/dstest/*$(OBJ) $(CONFIGURATOR_EXE) $(CONFIG_H)
-
-+# Patched for FreeBSD
-+
- %$(OBJ): %.c
-- $(CC) $(C_FLAGS) $(C_INC)$(INCPATH) $(DEFINES) $(C_OPT)1 $(C_OUT)$@ $<
-+ $(CC) $(C_FLAGS) $(C_INC)$(INCPATH) -I/usr/X11R6/include $(DEFINES) $(C_OPT)1 $(C_OUT)$@ $<
-
- %$(OBJ): %.cpp
-- $(CC) $(C_FLAGS) $(C_INC)$(INCPATH) $(DEFINES) $(C_OPT)$(OPT) $(C_OUT)$@ $<
-+ $(CC) $(C_FLAGS) $(C_INC)$(INCPATH) -I/usr/X11R6/include $(DEFINES) $(C_OPT)$(OPT) $(C_OUT)$@ $<
-
- %.exe: %$(OBJ)
-- $(CC) $(C_EXEOUT)$@ $< $(ODE_LIB) $(DRAWSTUFF_LIB) $(RESOURCE_FILE) $(LINK_OPENGL) $(LINK_MATH)
-+ $(CC) $(C_EXEOUT)$@ $< $(ODE_LIB) $(DRAWSTUFF_LIB) $(RESOURCE_FILE) $(LINK_OPENGL) $(LINK_MATH) -lXext
-
- # windows specific rules
-
diff --git a/extern/qhull/src/Makefile b/extern/qhull/src/Makefile
index 8201e44f01b..81c06758cbb 100644
--- a/extern/qhull/src/Makefile
+++ b/extern/qhull/src/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
#
@@ -40,16 +42,13 @@ CSRCS = user.c global.c stat.c io.c geom2.c poly2.c \
CCSRCS =
include nan_compile.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_QHULL) ] || mkdir -p $(NAN_QHULL)
@[ -d $(NAN_QHULL)/include/qhull ] || mkdir -p $(NAN_QHULL)/include/qhull
- @[ -d $(NAN_QHULL)/lib ] || mkdir -p $(NAN_QHULL)/lib
- @[ -d $(NAN_QHULL)/lib/debug ] || mkdir -p $(NAN_QHULL)/lib/debug
- @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/lib$(LIBNAME).a $(NAN_QHULL)/lib/
-# @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/debug/lib$(LIBNAME).a $(NAN_QHULL)/lib/debug/
+ @[ -d $(NAN_QHULL)/lib/$(DEBUG_DIR) ] || mkdir -p $(NAN_QHULL)/lib/$(DEBUG_DIR)
+ @$(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)lib$(LIBNAME).a $(NAN_QHULL)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_QHULL)/lib/lib$(LIBNAME).a
-# ranlib $(NAN_QHULL)/lib/debug/lib$(LIBNAME).a
+ ranlib $(NAN_QHULL)/lib/$(DEBUG_DIR)lib$(LIBNAME).a
endif
@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh ../include/qhull/*.h $(NAN_QHULL)/include/qhull
diff --git a/extern/solid/Makefile b/extern/solid/Makefile
index 3b333c5141d..206dc21c3fb 100644
--- a/extern/solid/Makefile
+++ b/extern/solid/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
#
@@ -37,18 +39,15 @@ DIRS = src
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_SOLID) ] || mkdir -p $(NAN_SOLID)
@[ -d $(NAN_SOLID)/include/SOLID ] || mkdir -p $(NAN_SOLID)/include/SOLID
@[ -d $(NAN_SOLID)/include/SOLID/MT ] || mkdir -p $(NAN_SOLID)/include/SOLID/MT
- @[ -d $(NAN_SOLID)/lib ] || mkdir -p $(NAN_SOLID)/lib
- @[ -d $(NAN_SOLID)/lib/debug ] || mkdir -p $(NAN_SOLID)/lib/debug
+ @[ -d $(NAN_SOLID)/lib/$(DEBUG_DIR) ] || mkdir -p $(NAN_SOLID)/lib/$(DEBUG_DIR)
@for i in $(LIBNAMES); do \
- $(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/$$i/lib$$i.a $(NAN_SOLID)/lib/ ; \
- $(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/$$i/debug/lib$$i.a $(NAN_SOLID)/lib/debug/ ; \
+ $(NANBLENDERHOME)/intern/tools/cpifdiff.sh $(DIR)/$$i/$(DEBUG_DIR)lib$$i.a $(NAN_SOLID)/lib/$(DEBUG_DIR) ; \
if [ $(OS) = darwin ] ; then \
- ranlib $(NAN_SOLID)/lib/lib$$i.a ; \
- ranlib $(NAN_SOLID)/lib/debug/lib$$i.a ; \
+ ranlib $(NAN_SOLID)/lib/$(DEBUG_DIR)lib$$i.a ; \
fi ; \
done
@$(NANBLENDERHOME)/intern/tools/cpifdiff.sh include/*.h $(NAN_SOLID)/include/SOLID
diff --git a/intern/SoundSystem/Makefile b/intern/SoundSystem/Makefile
index 051e2643a87..61785e44e68 100644
--- a/intern/SoundSystem/Makefile
+++ b/intern/SoundSystem/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
#
@@ -56,16 +58,13 @@ endif
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_SOUNDSYSTEM) ] || mkdir $(NAN_SOUNDSYSTEM)
@[ -d $(NAN_SOUNDSYSTEM)/include ] || mkdir $(NAN_SOUNDSYSTEM)/include
- @[ -d $(NAN_SOUNDSYSTEM)/lib ] || mkdir $(NAN_SOUNDSYSTEM)/lib
- @[ -d $(NAN_SOUNDSYSTEM)/lib/debug ] || mkdir $(NAN_SOUNDSYSTEM)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libSoundSystem.a $(NAN_SOUNDSYSTEM)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libSoundSystem.a $(NAN_SOUNDSYSTEM)/lib/debug/
+ @[ -d $(NAN_SOUNDSYSTEM)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_SOUNDSYSTEM)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libSoundSystem.a $(NAN_SOUNDSYSTEM)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_SOUNDSYSTEM)/lib/libSoundSystem.a
- ranlib $(NAN_SOUNDSYSTEM)/lib/debug/libSoundSystem.a
+ ranlib $(NAN_SOUNDSYSTEM)/lib/$(DEBUG_DIR)libSoundSystem.a
endif
@../tools/cpifdiff.sh *.h $(NAN_SOUNDSYSTEM)/include/
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/bmfont/Makefile b/intern/bmfont/Makefile
index bc42f52a1fb..de0fc715884 100644
--- a/intern/bmfont/Makefile
+++ b/intern/bmfont/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# bmfont main makefile.
@@ -38,16 +40,13 @@ DIRS = intern
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_BMFONT) ] || mkdir $(NAN_BMFONT)
@[ -d $(NAN_BMFONT)/include ] || mkdir $(NAN_BMFONT)/include
- @[ -d $(NAN_BMFONT)/lib ] || mkdir $(NAN_BMFONT)/lib
- @[ -d $(NAN_BMFONT)/lib/debug ] || mkdir $(NAN_BMFONT)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libbmfont.a $(NAN_BMFONT)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libbmfont.a $(NAN_BMFONT)/lib/debug/
+ @[ -d $(NAN_BMFONT)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_BMFONT)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libbmfont.a $(NAN_BMFONT)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_BMFONT)/lib/libbmfont.a
- ranlib $(NAN_BMFONT)/lib/debug/libbmfont.a
+ ranlib $(NAN_BMFONT)/lib/$(DEBUG_DIR)libbmfont.a
endif
@../tools/cpifdiff.sh *.h $(NAN_BMFONT)/include/
diff --git a/intern/boolop/Makefile b/intern/boolop/Makefile
index 4058c4ca7c1..a7a08f665c7 100644
--- a/intern/boolop/Makefile
+++ b/intern/boolop/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# bsp main makefile.
@@ -38,16 +40,13 @@ DIRS = intern
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_BOOLOP) ] || mkdir $(NAN_BOOLOP)
@[ -d $(NAN_BOOLOP)/include ] || mkdir $(NAN_BOOLOP)/include
- @[ -d $(NAN_BOOLOP)/lib ] || mkdir $(NAN_BOOLOP)/lib
- @[ -d $(NAN_BOOLOP)/lib/debug ] || mkdir $(NAN_BOOLOP)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libboolop.a $(NAN_BOOLOP)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libboolop.a $(NAN_BOOLOP)/lib/debug/
+ @[ -d $(NAN_BOOLOP)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_BOOLOP)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libboolop.a $(NAN_BOOLOP)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_BOOLOP)/lib/libboolop.a
- ranlib $(NAN_BOOLOP)/lib/debug/libboolop.a
+ ranlib $(NAN_BOOLOP)/lib/$(DEBUG_DIR)libboolop.a
endif
@../tools/cpifdiff.sh extern/*.h $(NAN_BOOLOP)/include/
diff --git a/intern/bsp/Makefile b/intern/bsp/Makefile
index fd106acab83..cd1653206a6 100644
--- a/intern/bsp/Makefile
+++ b/intern/bsp/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# bsp main makefile.
@@ -38,19 +40,14 @@ DIRS = intern
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_BSP) ] || mkdir $(NAN_BSP)
@[ -d $(NAN_BSP)/include ] || mkdir $(NAN_BSP)/include
- @[ -d $(NAN_BSP)/lib ] || mkdir $(NAN_BSP)/lib
- @[ -d $(NAN_BSP)/lib/debug ] || mkdir $(NAN_BSP)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libbsp.a $(NAN_BSP)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libbsp.a $(NAN_BSP)/lib/debug/
+ @[ -d $(NAN_BSP)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_BSP)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libbsp.a $(NAN_BSP)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_BSP)/lib/libbsp.a
- ranlib $(NAN_BSP)/lib/debug/libbsp.a
+ ranlib $(NAN_BSP)/lib/$(DEBUG_DIR)libbsp.a
endif
@../tools/cpifdiff.sh extern/*.h $(NAN_BSP)/include/
-
-
diff --git a/intern/container/Makefile b/intern/container/Makefile
index 76cba5b3ea1..8a9c038f0ee 100644
--- a/intern/container/Makefile
+++ b/intern/container/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# container main makefile.
@@ -38,12 +40,10 @@ DIRS = intern
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_CONTAINER) ] || mkdir $(NAN_CONTAINER)
@[ -d $(NAN_CONTAINER)/include ] || mkdir $(NAN_CONTAINER)/include
- @[ -d $(NAN_CONTAINER)/lib ] || mkdir $(NAN_CONTAINER)/lib
- @[ -d $(NAN_CONTAINER)/lib/debug ] || mkdir $(NAN_CONTAINER)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libcontainer.a $(NAN_CONTAINER)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libcontainer.a $(NAN_CONTAINER)/lib/debug
+ @[ -d $(NAN_CONTAINER)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_CONTAINER)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libcontainer.a $(NAN_CONTAINER)/lib/$(DEBUG_DIR)
@../tools/cpifdiff.sh *.h $(NAN_CONTAINER)/include/
diff --git a/intern/decimation/Makefile b/intern/decimation/Makefile
index 9241d87c3a3..7ff87fa018b 100644
--- a/intern/decimation/Makefile
+++ b/intern/decimation/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# decimation main makefile.
@@ -38,16 +40,13 @@ TESTDIRS = test
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_DECIMATION) ] || mkdir $(NAN_DECIMATION)
@[ -d $(NAN_DECIMATION)/include ] || mkdir $(NAN_DECIMATION)/include
- @[ -d $(NAN_DECIMATION)/lib ] || mkdir $(NAN_DECIMATION)/lib
- @[ -d $(NAN_DECIMATION)/lib/debug ] || mkdir $(NAN_DECIMATION)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libdecimation.a $(NAN_DECIMATION)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libdecimation.a $(NAN_DECIMATION)/lib/debug/
+ @[ -d $(NAN_DECIMATION)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_DECIMATION)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libdecimation.a $(NAN_DECIMATION)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_DECIMATION)/lib/libdecimation.a
- ranlib $(NAN_DECIMATION)/lib/debug/libdecimation.a
+ ranlib $(NAN_DECIMATION)/lib/$(DEBUG_DIR)libdecimation.a
endif
@../tools/cpifdiff.sh extern/*.h $(NAN_DECIMATION)/include/
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/elbeem/Makefile b/intern/elbeem/Makefile
index 9ea08d63374..e7e8a8baa64 100644
--- a/intern/elbeem/Makefile
+++ b/intern/elbeem/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# elbeem main makefile.
@@ -40,16 +42,13 @@ DIRS = intern
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_ELBEEM) ] || mkdir $(NAN_ELBEEM)
@[ -d $(NAN_ELBEEM)/include ] || mkdir $(NAN_ELBEEM)/include
- @[ -d $(NAN_ELBEEM)/lib ] || mkdir $(NAN_ELBEEM)/lib
- @[ -d $(NAN_ELBEEM)/lib/debug ] || mkdir $(NAN_ELBEEM)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libelbeem.a $(NAN_ELBEEM)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libelbeem.a $(NAN_ELBEEM)/lib/debug/
+ @[ -d $(NAN_ELBEEM)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_ELBEEM)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libelbeem.a $(NAN_ELBEEM)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_ELBEEM)/lib/libelbeem.a
- ranlib $(NAN_ELBEEM)/lib/debug/libelbeem.a
+ ranlib $(NAN_ELBEEM)/lib/$(DEBUG_DIR)libelbeem.a
endif
@../tools/cpifdiff.sh extern/*.h $(NAN_ELBEEM)/include/
diff --git a/intern/ghost/Makefile b/intern/ghost/Makefile
index c5a9c522655..e983c3a9cee 100644
--- a/intern/ghost/Makefile
+++ b/intern/ghost/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# ghost main makefile.
@@ -38,16 +40,13 @@ TESTDIRS = test
include nan_subdirs.mk
-install: all
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_GHOST) ] || mkdir $(NAN_GHOST)
@[ -d $(NAN_GHOST)/include ] || mkdir $(NAN_GHOST)/include
- @[ -d $(NAN_GHOST)/lib ] || mkdir $(NAN_GHOST)/lib
- @[ -d $(NAN_GHOST)/lib/debug ] || mkdir $(NAN_GHOST)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libghost.a $(NAN_GHOST)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libghost.a $(NAN_GHOST)/lib/debug/
+ @[ -d $(NAN_GHOST)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_GHOST)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libghost.a $(NAN_GHOST)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_GHOST)/lib/libghost.a
- ranlib $(NAN_GHOST)/lib/debug/libghost.a
+ ranlib $(NAN_GHOST)/lib/$(DEBUG_DIR)libghost.a
endif
@../tools/cpifdiff.sh *.h $(NAN_GHOST)/include/
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/ghost/intern/Makefile b/intern/ghost/intern/Makefile
index 467ec768720..5b95bbb3b68 100644
--- a/intern/ghost/intern/Makefile
+++ b/intern/ghost/intern/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
# ghost intern Makefile
@@ -38,8 +40,6 @@ CCSRCS += GHOST_Rect.cpp GHOST_DisplayManager.cpp GHOST_C-api.cpp
CCSRCS += GHOST_CallbackEventConsumer.cpp
CCSRCS += GHOST_NDOFManager.cpp
-include nan_definitions.mk
-
ifeq ($(OS),$(findstring $(OS), "darwin"))
CCSRCS += $(wildcard *Carbon.cpp)
endif
diff --git a/intern/guardedalloc/Makefile b/intern/guardedalloc/Makefile
index f0cef3d222c..55894d54c8e 100644
--- a/intern/guardedalloc/Makefile
+++ b/intern/guardedalloc/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# decimation main makefile.
@@ -38,16 +40,13 @@ TESTDIRS = test
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_GUARDEDALLOC) ] || mkdir $(NAN_GUARDEDALLOC)
@[ -d $(NAN_GUARDEDALLOC)/include ] || mkdir $(NAN_GUARDEDALLOC)/include
- @[ -d $(NAN_GUARDEDALLOC)/lib ] || mkdir $(NAN_GUARDEDALLOC)/lib
- @[ -d $(NAN_GUARDEDALLOC)/lib/debug ] || mkdir $(NAN_GUARDEDALLOC)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libguardedalloc.a $(NAN_GUARDEDALLOC)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libguardedalloc.a $(NAN_GUARDEDALLOC)/lib/debug/
+ @[ -d $(NAN_GUARDEDALLOC)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_GUARDEDALLOC)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libguardedalloc.a $(NAN_GUARDEDALLOC)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_GUARDEDALLOC)/lib/libguardedalloc.a
- ranlib $(NAN_GUARDEDALLOC)/lib/debug/libguardedalloc.a
+ ranlib $(NAN_GUARDEDALLOC)/lib/$(DEBUG_DIR)libguardedalloc.a
endif
@../tools/cpifdiff.sh *.h $(NAN_GUARDEDALLOC)/include/
diff --git a/intern/iksolver/Makefile b/intern/iksolver/Makefile
index a6cfa88eb30..09e6e3a1c2a 100644
--- a/intern/iksolver/Makefile
+++ b/intern/iksolver/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# iksolver main makefile.
@@ -38,16 +40,13 @@ TESTDIRS = test
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_IKSOLVER) ] || mkdir $(NAN_IKSOLVER)
@[ -d $(NAN_IKSOLVER)/include ] || mkdir $(NAN_IKSOLVER)/include
- @[ -d $(NAN_IKSOLVER)/lib ] || mkdir $(NAN_IKSOLVER)/lib
- @[ -d $(NAN_IKSOLVER)/lib/debug ] || mkdir $(NAN_IKSOLVER)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libiksolver.a $(NAN_IKSOLVER)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libiksolver.a $(NAN_IKSOLVER)/lib/debug/
+ @[ -d $(NAN_IKSOLVER)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_IKSOLVER)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libiksolver.a $(NAN_IKSOLVER)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_IKSOLVER)/lib/libiksolver.a
- ranlib $(NAN_IKSOLVER)/lib/debug/libiksolver.a
+ ranlib $(NAN_IKSOLVER)/lib/$(DEBUG_DIR)libiksolver.a
endif
@../tools/cpifdiff.sh extern/*.h $(NAN_IKSOLVER)/include/
diff --git a/intern/memutil/Makefile b/intern/memutil/Makefile
index 787ca4fd58f..50aa0528f31 100644
--- a/intern/memutil/Makefile
+++ b/intern/memutil/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# memutil main makefile.
@@ -38,16 +40,13 @@ DIRS = intern
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_MEMUTIL) ] || mkdir $(NAN_MEMUTIL)
@[ -d $(NAN_MEMUTIL)/include ] || mkdir $(NAN_MEMUTIL)/include
- @[ -d $(NAN_MEMUTIL)/lib ] || mkdir $(NAN_MEMUTIL)/lib
- @[ -d $(NAN_MEMUTIL)/lib/debug ] || mkdir $(NAN_MEMUTIL)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libmemutil.a $(NAN_MEMUTIL)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libmemutil.a $(NAN_MEMUTIL)/lib/debug
+ @[ -d $(NAN_MEMUTIL)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_MEMUTIL)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libmemutil.a $(NAN_MEMUTIL)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_MEMUTIL)/lib/libmemutil.a
- ranlib $(NAN_MEMUTIL)/lib/debug/libmemutil.a
+ ranlib $(NAN_MEMUTIL)/lib/$(DEBUG_DIR)libmemutil.a
endif
@../tools/cpifdiff.sh *.h $(NAN_MEMUTIL)/include/
diff --git a/intern/moto/Makefile b/intern/moto/Makefile
index 7bd7ea10abc..3ad4fde9c4e 100644
--- a/intern/moto/Makefile
+++ b/intern/moto/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# moto main makefile.
@@ -38,16 +40,13 @@ DIRS = intern
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_MOTO) ] || mkdir $(NAN_MOTO)
@[ -d $(NAN_MOTO)/include ] || mkdir $(NAN_MOTO)/include
- @[ -d $(NAN_MOTO)/lib ] || mkdir $(NAN_MOTO)/lib
- @[ -d $(NAN_MOTO)/lib/debug ] || mkdir $(NAN_MOTO)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libmoto.a $(NAN_MOTO)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libmoto.a $(NAN_MOTO)/lib/debug/
+ @[ -d $(NAN_MOTO)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_MOTO)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libmoto.a $(NAN_MOTO)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_MOTO)/lib/libmoto.a
- ranlib $(NAN_MOTO)/lib/debug/libmoto.a
+ ranlib $(NAN_MOTO)/lib/$(DEBUG_DIR)libmoto.a
endif
@../tools/cpifdiff.sh include/*.h $(NAN_MOTO)/include/
diff --git a/intern/opennl/Makefile b/intern/opennl/Makefile
index a84fd135d1d..023491792db 100644
--- a/intern/opennl/Makefile
+++ b/intern/opennl/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# opennl main makefile.
@@ -40,25 +42,19 @@ DIRS = intern superlu
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_OPENNL) ] || mkdir $(NAN_OPENNL)
@[ -d $(NAN_OPENNL)/include ] || mkdir $(NAN_OPENNL)/include
- @[ -d $(NAN_OPENNL)/lib ] || mkdir $(NAN_OPENNL)/lib
- @[ -d $(NAN_OPENNL)/lib/debug ] || mkdir $(NAN_OPENNL)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libopennl.a $(NAN_OPENNL)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libopennl.a $(NAN_OPENNL)/lib/debug/
+ @[ -d $(NAN_OPENNL)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_OPENNL)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libopennl.a $(NAN_OPENNL)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_OPENNL)/lib/libopennl.a
- ranlib $(NAN_OPENNL)/lib/debug/libopennl.a
+ ranlib $(NAN_OPENNL)/lib/$(DEBUG_DIR)libopennl.a
endif
@../tools/cpifdiff.sh extern/*.h $(NAN_OPENNL)/include/
@[ -d $(NAN_SUPERLU) ] || mkdir $(NAN_SUPERLU)
- @[ -d $(NAN_SUPERLU)/lib ] || mkdir $(NAN_SUPERLU)/lib
- @[ -d $(NAN_SUPERLU)/lib/debug ] || mkdir $(NAN_SUPERLU)/lib/debug
- @../tools/cpifdiff.sh $(DIR_SLU)/libsuperlu.a $(NAN_SUPERLU)/lib/
- @../tools/cpifdiff.sh $(DIR_SLU)/debug/libsuperlu.a $(NAN_SUPERLU)/lib/debug/
+ @[ -d $(NAN_SUPERLU)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_SUPERLU)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR_SLU)/$(DEBUG_DIR)libsuperlu.a $(NAN_SUPERLU)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_SUPERLU)/lib/libsuperlu.a
- ranlib $(NAN_SUPERLU)/lib/debug/libsuperlu.a
+ ranlib $(NAN_SUPERLU)/lib/$(DEBUG_DIR)libsuperlu.a
endif
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/intern/string/Makefile b/intern/string/Makefile
index e885b87babe..7972defd406 100644
--- a/intern/string/Makefile
+++ b/intern/string/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): Hans Lambermont
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
# string main makefile.
@@ -38,16 +40,13 @@ DIRS = intern
include nan_subdirs.mk
-install: all debug
+install: $(ALL_OR_DEBUG)
@[ -d $(NAN_STRING) ] || mkdir $(NAN_STRING)
@[ -d $(NAN_STRING)/include ] || mkdir $(NAN_STRING)/include
- @[ -d $(NAN_STRING)/lib ] || mkdir $(NAN_STRING)/lib
- @[ -d $(NAN_STRING)/lib/debug ] || mkdir $(NAN_STRING)/lib/debug
- @../tools/cpifdiff.sh $(DIR)/libstring.a $(NAN_STRING)/lib/
- @../tools/cpifdiff.sh $(DIR)/debug/libstring.a $(NAN_STRING)/lib/debug/
+ @[ -d $(NAN_STRING)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_STRING)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libstring.a $(NAN_STRING)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_STRING)/lib/libstring.a
- ranlib $(NAN_STRING)/lib/debug/libstring.a
+ ranlib $(NAN_STRING)/lib/$(DEBUG_DIR)libstring.a
endif
@../tools/cpifdiff.sh *.h $(NAN_STRING)/include/
diff --git a/po/Makefile b/po/Makefile
index 4bafba8a6e6..40b4684f5c0 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
# $Id$
#
# ***** BEGIN GPL LICENSE BLOCK *****
@@ -9,47 +11,48 @@
#
# 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
+# 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.
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# The Original Code is Copyright (C) 2002 by Stichting Blender Foundation,
# Amsterdam, the Netherlands.
# All rights reserved.
#
-# The Original Code is: revision 1.1
+# The Original Code is: revision 1.2
#
-# Contributor(s): Wouter van Heyst
+# Contributor(s): Wouter van Heyst, GSR
#
# ***** END GPL LICENSE BLOCK *****
#
-# po Makefile for blender. Compiles the translations and places them
+# po Makefile for blender. Compiles the translations in the place
# where release can pick them up.
+PO_FILES = $(wildcard *.po)
+
+LINGUAS = $(basename $(PO_FILES))
+
SOURCEDIR = blender/po
include nan_definitions.mk
-LINGUAS = ar bg ca cs de el es fi fr hr it ja ko nl pl pt_BR ro ru sr sr@Latn sv uk zh_CN
-
ifeq ($(OS), darwin)
-DIR = $(OCGDIR)/bin/blender.app/Contents/Resources/locale/$@/LC_MESSAGES/
+ DIR = $(OCGDIR)/bin/blender.app/Contents/Resources/locale/
else
-DIR = $(OCGDIR)/bin/.blender/locale/$@/LC_MESSAGES/
+ DIR = $(OCGDIR)/bin/.blender/locale/
endif
-all debug:: $(LINGUAS)
+LINGUAS_DEST= $(foreach LINGUA, $(LINGUAS),$(DIR)$(LINGUA)/LC_MESSAGES/blender.mo)
-clean::
-ifeq ($(OS), darwin)
- rm -rf $(OCGDIR)/bin/blender.app/Contents/Resources/locale/
-else
- rm -rf $(OCGDIR)/bin/.blender/locale/
-endif
+$(DIR)%/LC_MESSAGES/blender.mo: %.po
+ mkdir -p $(@D)
+ msgfmt -o $@ $<
-$(LINGUAS):
- mkdir -p $(DIR)
- msgfmt -o $(DIR)/blender.mo $@.po
+all debug:: $(LINGUAS_DEST)
+# Just trigger the deps
+
+clean::
+ rm -rf $(DIR)
diff --git a/projectfiles_vc9/blender/blender.vcproj b/projectfiles_vc9/blender/blender.vcproj
index 9206623cd0a..3111c322311 100644
--- a/projectfiles_vc9/blender/blender.vcproj
+++ b/projectfiles_vc9/blender/blender.vcproj
@@ -44,7 +44,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\source\blender;..\..\source\blender\imbuf;..\..\source\blender\misc;..\..\source\blender\blenlib;..\..\source\blender\editors\include;..\..\source\blender\python;..\..\source\blender\windowmanager;..\..\source\blender\renderui;..\..\source\blender\makesdna;..\..\source\blender\blenkernel;..\..\source\blender\blenloader;..\..\source\blender\renderconverter;..\..\source\blender\render\extern\include;..\..\source\blender\radiosity\extern\include;..\..\source\kernel\gen_system;..\..\source\kernel\gen_messaging;..\..\..\build\msvc_9\extern\glew\include;..\..\source\blender\gpu"
+ AdditionalIncludeDirectories="..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\source\blender;..\..\source\blender\imbuf;..\..\source\blender\misc;..\..\source\blender\blenlib;..\..\source\blender\editors\include;..\..\source\blender\python;..\..\source\blender\windowmanager;..\..\source\blender\renderui;..\..\source\blender\makesdna;..\..\source\blender\makesrna;..\..\source\blender\blenkernel;..\..\source\blender\blenloader;..\..\source\blender\renderconverter;..\..\source\blender\render\extern\include;..\..\source\blender\radiosity\extern\include;..\..\source\kernel\gen_system;..\..\source\kernel\gen_messaging;..\..\..\build\msvc_9\extern\glew\include;..\..\source\blender\gpu"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;WITH_QUICKTIME;GAMEBLENDER=1;USE_SUMO_SOLID;FTGL_LIBRARY_STATIC"
StringPooling="true"
RuntimeLibrary="0"
@@ -139,7 +139,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\source\blender;..\..\source\blender\imbuf;..\..\source\blender\misc;..\..\source\blender\blenlib;..\..\source\blender\editors\include;..\..\source\blender\python;..\..\source\blender\windowmanager;..\..\source\blender\renderui;..\..\source\blender\makesdna;..\..\source\blender\blenkernel;..\..\source\blender\blenloader;..\..\source\blender\renderconverter;..\..\source\blender\render\extern\include;..\..\source\blender\radiosity\extern\include;..\..\source\kernel\gen_system;..\..\source\kernel\gen_messaging;..\..\..\build\msvc_9\extern\glew\include;..\..\source\blender\gpu"
+ AdditionalIncludeDirectories="..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\source\blender;..\..\source\blender\imbuf;..\..\source\blender\misc;..\..\source\blender\blenlib;..\..\source\blender\editors\include;..\..\source\blender\python;..\..\source\blender\windowmanager;..\..\source\blender\renderui;..\..\source\blender\makesdna;..\..\source\blender\makesrna;..\..\source\blender\blenkernel;..\..\source\blender\blenloader;..\..\source\blender\renderconverter;..\..\source\blender\render\extern\include;..\..\source\blender\radiosity\extern\include;..\..\source\kernel\gen_system;..\..\source\kernel\gen_messaging;..\..\..\build\msvc_9\extern\glew\include;..\..\source\blender\gpu"
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;WITH_QUICKTIME"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
diff --git a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
index 9d011cfbc3a..1b3d071b05a 100644
--- a/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
+++ b/projectfiles_vc9/blender/blenkernel/BKE_blenkernel.vcproj
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="9,00"
+ Version="9.00"
Name="BKE_blenkernel"
ProjectGUID="{CAE37E91-6570-43AC-A4B4-7A37A4B0FC94}"
RootNamespace="BKE_blenkernel"
diff --git a/projectfiles_vc9/blender/editors/ED_editors.vcproj b/projectfiles_vc9/blender/editors/ED_editors.vcproj
index da6f8276230..768079b63fb 100644
--- a/projectfiles_vc9/blender/editors/ED_editors.vcproj
+++ b/projectfiles_vc9/blender/editors/ED_editors.vcproj
@@ -383,6 +383,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\interface\interface_layout.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\interface\interface_panel.c"
>
</File>
@@ -395,6 +399,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\interface\interface_widgets.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\interface\keyval.c"
>
</File>
@@ -699,6 +707,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\space_buttons\buttons_object.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\space_buttons\buttons_scene.c"
>
</File>
@@ -1123,10 +1135,30 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\armature\BIF_generate.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\editors\armature\BIF_retarget.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\armature\editarmature.c"
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\armature\editarmature_generate.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\editors\armature\editarmature_retarget.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\..\source\blender\editors\armature\editarmature_sketch.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\armature\meshlaplacian.c"
>
</File>
@@ -1143,6 +1175,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\editors\armature\reeb.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\editors\armature\reeb.h"
>
</File>
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/makesdna/DNA_makesdna.vcproj b/projectfiles_vc9/blender/makesdna/DNA_makesdna.vcproj
index 81449aa489d..96de0231363 100644
--- a/projectfiles_vc9/blender/makesdna/DNA_makesdna.vcproj
+++ b/projectfiles_vc9/blender/makesdna/DNA_makesdna.vcproj
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="9,00"
+ Version="9.00"
Name="DNA_makesdna"
ProjectGUID="{E013786A-9575-4F34-81B2-33290357EE87}"
RootNamespace="DNA_makesdna"
@@ -702,6 +702,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\makesdna\DNA_meshdata_types.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\makesdna\DNA_meta_types.h"
>
</File>
diff --git a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
index e215bf2eaba..92dd343ab8f 100644
--- a/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
+++ b/projectfiles_vc9/blender/makesrna/RNA_makesrna.vcproj
@@ -629,6 +629,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\makesrna\intern\rna_context.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\makesrna\intern\rna_controller.c"
>
</File>
diff --git a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
index a0e4a87c630..dd63bc8e70b 100644
--- a/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
+++ b/projectfiles_vc9/blender/makesrna/RNA_rna.vcproj
@@ -203,6 +203,10 @@
>
</File>
<File
+ RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_context_gen.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\source\blender\makesrna\intern\rna.crna_controller_gen.c"
>
</File>
@@ -358,10 +362,6 @@
RelativePath="..\..\..\source\blender\makesrna\intern\rna_access.c"
>
</File>
- <File
- RelativePath="..\..\..\source\blender\makesrna\intern\rna_dependency.c"
- >
- </File>
</Filter>
<Filter
Name="Header Files"
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/datafiles/blenderbuttons b/release/datafiles/blenderbuttons
index 664c82ab2c0..aa71ab4cfae 100644
--- a/release/datafiles/blenderbuttons
+++ b/release/datafiles/blenderbuttons
Binary files differ
diff --git a/release/datafiles/prvicons b/release/datafiles/prvicons
index de3980f9676..5863afefbdc 100644
--- a/release/datafiles/prvicons
+++ b/release/datafiles/prvicons
Binary files differ
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..b81f0c4e5ed 100644
--- a/source/Makefile
+++ b/source/Makefile
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
#
@@ -53,7 +55,7 @@ ifdef NAN_BUILDINFO
BUILDINFO_C = $(SRCHOME)/creator/buildinfo.c
BUILD_DATE := $(shell date "+%Y-%m-%d")
BUILD_TIME := $(shell date "+%H:%M:%S")
- BUILD_REV := $(shell svnversion)
+ BUILD_REV := $(shell svnversion)
endif
############# set pyplayerlib ##################
@@ -89,7 +91,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
@@ -98,15 +99,13 @@ COMLIB += $(OCGDIR)/blender/nodes_tex/$(DEBUG_DIR)libnodes_tex.a
COMLIB += $(OCGDIR)/blender/nodes/$(DEBUG_DIR)libnodes.a
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 += $(NAN_IKSOLVER)/lib/$(DEBUG_DIR)libiksolver.a
+COMLIB += $(NAN_MOTO)/lib/$(DEBUG_DIR)libmoto.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 += $(NAN_GLEW)/lib/$(DEBUG_DIR)libglew.a
COMLIB += $(OCGDIR)/blender/blenfont/$(DEBUG_DIR)libblenfont.a
ifneq ($(NAN_NO_KETSJI),true)
@@ -117,7 +116,7 @@ ifneq ($(NAN_NO_KETSJI),true)
COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
COMLIB += $(OCGDIR)/gameengine/blconverter/$(DEBUG_DIR)libblconverter.a
COMLIB += $(NAN_SOLID)/lib/libsolid.a
- COMLIB += $(NAN_SOLID)/lib/libsolid_broad.a
+ COMLIB += $(NAN_SOLID)/lib/libsolid_broad.a
COMLIB += $(NAN_SOLID)/lib/libsolid_complex.a
COMLIB += $(NAN_SOLID)/lib/libsolid_convex.a
COMLIB += $(OCGDIR)/gameengine/blphys/sumo/$(DEBUG_DIR)libsumo.a
@@ -171,6 +170,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)
@@ -192,7 +195,7 @@ ifeq ($(WITH_FREETYPE2), true)
COMLIB += $(NAN_FREETYPE)/lib/freetype2ST.lib
endif
else
- COMLIB += $(NAN_FTGL)/lib/libftgl.a
+ COMLIB += $(NAN_FTGL)/lib/$(DEBUG_DIR)libftgl.a
ifeq ($(OS), irix)
COMLIB += $(NAN_FREETYPE)/lib/libfreetype.a
else
@@ -220,45 +223,48 @@ endif
# note: space_api.a in begin of editors, screen.a in end
PULIB = $(NAN_MOTO)/lib/libmoto.a
+PULIB += $(NAN_DECIMATION)/lib/$(DEBUG_DIR)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
-PULIB += $(OCGDIR)/blender/ed_action/libed_action.a
-PULIB += $(OCGDIR)/blender/ed_nla/libed_nla.a
-PULIB += $(OCGDIR)/blender/ed_script/libed_script.a
-PULIB += $(OCGDIR)/blender/ed_text/libed_text.a
-PULIB += $(OCGDIR)/blender/ed_sequencer/libed_sequencer.a
-PULIB += $(OCGDIR)/blender/ed_file/libed_file.a
-PULIB += $(OCGDIR)/blender/ed_info/libed_info.a
-PULIB += $(OCGDIR)/blender/ed_buttons/libed_buttons.a
-PULIB += $(OCGDIR)/blender/ed_node/libed_node.a
-PULIB += $(OCGDIR)/blender/ed_graph/libed_graph.a
-PULIB += $(OCGDIR)/blender/ed_outliner/libed_outliner.a
-PULIB += $(OCGDIR)/blender/ed_time/libed_time.a
-PULIB += $(OCGDIR)/blender/ed_preview/libed_preview.a
-PULIB += $(OCGDIR)/blender/ed_view3d/libed_view3d.a
-PULIB += $(OCGDIR)/blender/ed_interface/libed_interface.a
-PULIB += $(OCGDIR)/blender/ed_object/libed_object.a
-PULIB += $(OCGDIR)/blender/ed_curve/libed_curve.a
-PULIB += $(OCGDIR)/blender/ed_armature/libed_armature.a
-PULIB += $(OCGDIR)/blender/ed_mesh/libed_mesh.a
-PULIB += $(OCGDIR)/blender/ed_sculpt_paint/libed_sculpt_paint.a
-PULIB += $(OCGDIR)/blender/ed_physics/libed_physics.a
-PULIB += $(OCGDIR)/blender/ed_animation/libed_animation.a
-PULIB += $(OCGDIR)/blender/ed_transform/libed_transform.a
-PULIB += $(OCGDIR)/blender/ed_util/libed_util.a
-PULIB += $(OCGDIR)/blender/ed_datafiles/libed_datafiles.a
-PULIB += $(OCGDIR)/blender/ed_image/libed_image.a
-PULIB += $(OCGDIR)/blender/ed_uvedit/libed_uvedit.a
-PULIB += $(OCGDIR)/blender/ed_screen/libed_screen.a
-PULIB += $(OCGDIR)/blender/windowmanager/libwindowmanager.a
+PULIB += $(OCGDIR)/blender/ed_space/$(DEBUG_DIR)libed_space.a
+PULIB += $(OCGDIR)/blender/ed_sound/$(DEBUG_DIR)libed_sound.a
+PULIB += $(OCGDIR)/blender/ed_action/$(DEBUG_DIR)libed_action.a
+PULIB += $(OCGDIR)/blender/ed_nla/$(DEBUG_DIR)libed_nla.a
+PULIB += $(OCGDIR)/blender/ed_script/$(DEBUG_DIR)libed_script.a
+PULIB += $(OCGDIR)/blender/ed_text/$(DEBUG_DIR)libed_text.a
+PULIB += $(OCGDIR)/blender/ed_sequencer/$(DEBUG_DIR)libed_sequencer.a
+PULIB += $(OCGDIR)/blender/ed_file/$(DEBUG_DIR)libed_file.a
+PULIB += $(OCGDIR)/blender/ed_info/$(DEBUG_DIR)libed_info.a
+PULIB += $(OCGDIR)/blender/ed_buttons/$(DEBUG_DIR)libed_buttons.a
+PULIB += $(OCGDIR)/blender/ed_node/$(DEBUG_DIR)libed_node.a
+PULIB += $(OCGDIR)/blender/ed_graph/$(DEBUG_DIR)libed_graph.a
+PULIB += $(OCGDIR)/blender/ed_outliner/$(DEBUG_DIR)libed_outliner.a
+PULIB += $(OCGDIR)/blender/ed_time/$(DEBUG_DIR)libed_time.a
+PULIB += $(OCGDIR)/blender/ed_preview/$(DEBUG_DIR)libed_preview.a
+PULIB += $(OCGDIR)/blender/ed_view3d/$(DEBUG_DIR)libed_view3d.a
+PULIB += $(OCGDIR)/blender/ed_interface/$(DEBUG_DIR)libed_interface.a
+PULIB += $(OCGDIR)/blender/ed_object/$(DEBUG_DIR)libed_object.a
+PULIB += $(OCGDIR)/blender/ed_curve/$(DEBUG_DIR)libed_curve.a
+PULIB += $(OCGDIR)/blender/ed_armature/$(DEBUG_DIR)libed_armature.a
+PULIB += $(OCGDIR)/blender/ed_mesh/$(DEBUG_DIR)libed_mesh.a
+PULIB += $(OCGDIR)/blender/ed_sculpt_paint/$(DEBUG_DIR)libed_sculpt_paint.a
+PULIB += $(OCGDIR)/blender/ed_physics/$(DEBUG_DIR)libed_physics.a
+PULIB += $(OCGDIR)/blender/ed_animation/$(DEBUG_DIR)libed_animation.a
+PULIB += $(OCGDIR)/blender/ed_transform/$(DEBUG_DIR)libed_transform.a
+PULIB += $(OCGDIR)/blender/ed_util/$(DEBUG_DIR)libed_util.a
+PULIB += $(OCGDIR)/blender/ed_datafiles/$(DEBUG_DIR)libed_datafiles.a
+PULIB += $(OCGDIR)/blender/ed_image/$(DEBUG_DIR)libed_image.a
+PULIB += $(OCGDIR)/blender/ed_uvedit/$(DEBUG_DIR)libed_uvedit.a
+PULIB += $(OCGDIR)/blender/ed_screen/$(DEBUG_DIR)libed_screen.a
+PULIB += $(OCGDIR)/blender/windowmanager/$(DEBUG_DIR)libwindowmanager.a
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
+ PULIB += $(NAN_MOTO)/lib/$(DEBUG_DIR)libmoto.a
PULIB += $(OCGDIR)/kernel/gen_system/$(DEBUG_DIR)libgen_system.a
PULIB += $(OCGDIR)/kernel/gen_messaging/$(DEBUG_DIR)libgen_messaging.a
COMLIB += $(NAN_SND_LIBS)
@@ -313,7 +319,7 @@ PLUGAPPLIB += $(OCGDIR)/gameengine/GamePlayer/common/$(DEBUG_DIR)libcommon.a
ifeq ($(OS),$(findstring $(OS), "linux"))
ifeq ($(CPU),i386)
- PLUGAPPLIB_XPLINK = $(OCGDIR)/gameengine/GamePlayer/netscape/src/$(DEBUG_DIR)_Blender3DPlugin_implementation_.o
+ PLUGAPPLIB_XPLINK = $(OCGDIR)/gameengine/GamePlayer/netscape/src/$(DEBUG_DIR)_Blender3DPlugin_implementation_.o
endif
endif
@@ -377,7 +383,7 @@ else
NAN_SND_LIBS += $(OPENALSOUND)
NAN_SND_LIBS += $(SDLSOUND)
NAN_SND_LIBS += $(NAN_OPENAL)/lib/libopenal.a
- ALUT = $(wildcard $(NAN_OPENAL)/lib/libalut.a)
+ ALUT = $(wildcard $(NAN_OPENAL)/lib/libalut.a)
NAN_SND_LIBS += $(ALUT)
NAN_SND_LIBS += $(SOUNDSYSTEM)
else
@@ -387,7 +393,7 @@ else
NAN_SND_LIBS += $(OPENALSOUND)
NAN_SND_LIBS += $(SDLSOUND)
NAN_SND_LIBS += $(NAN_OPENAL)/lib/openal_static.lib
- ALUT = $(wildcard $(NAN_OPENAL)/lib/alut_static.lib)
+ ALUT = $(wildcard $(NAN_OPENAL)/lib/alut_static.lib)
NAN_SND_LIBS += $(ALUT)
NAN_SND_LIBS += $(SOUNDSYSTEM)
else
@@ -546,7 +552,7 @@ ifeq ($(OS), darwin)
@$(MAKE) -C darwin/ APPLICATION=blenderstatic
endif
-$(DIR)/$(DEBUG_DIR)bin/blender$(EXT): $(OBJS) $(GRPLIB) $(PULIB) $(COMLIB)
+$(DIR)/$(DEBUG_DIR)bin/blender$(EXT): $(OBJS) $(GRPLIB) $(PULIB) $(COMLIB)
@echo "****> Link $@"
ifdef NAN_BUILDINFO
$(CCC) $(REL_CFLAGS) -DBUILD_DATE='"$(BUILD_DATE)"' -DBUILD_TIME='"$(BUILD_TIME)"' -DBUILD_REV='"$(BUILD_REV)"' -DBUILD_PLATFORM='"$(CONFIG_GUESS)"' -DBUILD_TYPE='"dynamic"' $(BUILDINFO_C) -c -o $(BUILDINFO_O) -DNAN_BUILDINFO
@@ -636,4 +642,3 @@ endif
ifdef NAN_BUILDINFO
/bin/rm $(BUILDINFO_O)
endif
-
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/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 0e96bf8ceb1..71554df57ab 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -52,6 +52,9 @@ void BLF_clipping(float xmin, float ymin, float xmax, float ymax);
void BLF_enable(int option);
void BLF_disable(int option);
+/* return the id of the current font. */
+int BLF_get(void);
+
/* Read the .Blanguages file, return 1 on success or 0 if fails. */
int BLF_lang_init(void);
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 43c85b78977..8e3b27bb425 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -165,7 +165,7 @@ int BLF_load_mem(char *name, unsigned char *mem, int mem_size)
FontBLF *font;
int i;
- if (!name || !mem || !mem_size)
+ if (!name)
return(-1);
i= blf_search(name);
@@ -181,19 +181,27 @@ int BLF_load_mem(char *name, unsigned char *mem, int mem_size)
return(-1);
}
-#ifdef WITH_FREETYPE2
- font= blf_font_new_from_mem(name, mem, mem_size);
+ font= blf_internal_new(name);
if (!font) {
- printf("Can't load font, %s from memory!!\n", name);
- return(-1);
+#ifdef WITH_FREETYPE2
+ if (!mem || !mem_size) {
+ printf("Can't load font, %s from memory!!\n", name);
+ return(-1);
+ }
+
+ font= blf_font_new_from_mem(name, mem, mem_size);
+#endif /* WITH_FREETYPE2 */
+
+ if (!font) {
+ printf("Can't load font, %s from memory!!\n", name);
+ return(-1);
+ }
}
global_font[global_font_num]= font;
i= global_font_num;
global_font_num++;
return(i);
-#endif /* WITH_FREETYPE2 */
- return(-1);
}
void BLF_set(int fontid)
@@ -202,6 +210,11 @@ void BLF_set(int fontid)
global_font_cur= fontid;
}
+int BLF_get(void)
+{
+ return(global_font_cur);
+}
+
void BLF_enable(int option)
{
FontBLF *font;
@@ -272,7 +285,7 @@ void BLF_draw(char *str)
FontBLF *font;
font= global_font[global_font_cur];
- if (font && font->draw && font->glyph_cache) {
+ if (font && font->draw) {
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -297,7 +310,7 @@ void BLF_boundbox(char *str, rctf *box)
FontBLF *font;
font= global_font[global_font_cur];
- if (font && font->boundbox_get && font->glyph_cache)
+ if (font && font->boundbox_get)
(*font->boundbox_get)(font, str, box);
}
@@ -306,7 +319,7 @@ float BLF_width(char *str)
FontBLF *font;
font= global_font[global_font_cur];
- if (font && font->width_get && font->glyph_cache)
+ if (font && font->width_get)
return((*font->width_get)(font, str));
return(0.0f);
}
@@ -316,7 +329,7 @@ float BLF_height(char *str)
FontBLF *font;
font= global_font[global_font_cur];
- if (font && font->height_get && font->glyph_cache)
+ if (font && font->height_get)
return((*font->height_get)(font, str));
return(0.0f);
}
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index a80e97327f3..d5c6ae5b359 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -110,6 +110,9 @@ void blf_font_draw(FontBLF *font, char *str)
int pen_x, pen_y;
int i, has_kerning;
+ if (!font->glyph_cache)
+ return;
+
face= (FT_Face)font->engine;
i= 0;
pen_x= 0;
@@ -161,6 +164,9 @@ void blf_font_boundbox(FontBLF *font, char *str, rctf *box)
int pen_x, pen_y;
int i, has_kerning;
+ if (!font->glyph_cache)
+ return;
+
face= (FT_Face)font->engine;
box->xmin= 32000.0f;
box->xmax= -32000.0f;
@@ -228,6 +234,9 @@ float blf_font_width(FontBLF *font, char *str)
{
rctf box;
+ if (!font->glyph_cache)
+ return(0.0f);
+
blf_font_boundbox(font, str, &box);
return((box.xmax - box.xmin) * font->aspect);
}
@@ -236,6 +245,9 @@ float blf_font_height(FontBLF *font, char *str)
{
rctf box;
+ if (!font->glyph_cache)
+ return(0.0f);
+
blf_font_boundbox(font, str, &box);
return((box.ymax - box.ymin) * font->aspect);
}
diff --git a/source/blender/blenfont/intern/blf_font_helv10.h b/source/blender/blenfont/intern/blf_font_helv10.h
new file mode 100644
index 00000000000..7a0a48d83bc
--- /dev/null
+++ b/source/blender/blenfont/intern/blf_font_helv10.h
@@ -0,0 +1,487 @@
+/**
+ * $Id:
+ *
+ * ***** 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) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BLF_FONT_HELV10_H
+#define BLF_FONT_HELV10_H
+
+static unsigned char helv10_bitmap_data[]= {
+ 0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0xa0,0xa0,0x50,0x50,0xf8,0x28,0x7c,0x28,
+ 0x28,0x20,0x70,0xa8,0x28,0x70,0xa0,0xa8,
+ 0x70,0x20,0x26,0x29,0x16,0x10,0x08,0x68,
+ 0x94,0x64,0x64,0x98,0x98,0xa4,0x60,0x50,
+ 0x50,0x20,0x80,0x40,0x40,0x20,0x40,0x40,
+ 0x80,0x80,0x80,0x80,0x40,0x40,0x20,0x80,
+ 0x40,0x40,0x20,0x20,0x20,0x20,0x40,0x40,
+ 0x80,0xa0,0x40,0xa0,0x20,0x20,0xf8,0x20,
+ 0x20,0x80,0x40,0x40,0xf8,0x80,0x80,0x80,
+ 0x40,0x40,0x40,0x40,0x20,0x20,0x70,0x88,
+ 0x88,0x88,0x88,0x88,0x88,0x70,0x40,0x40,
+ 0x40,0x40,0x40,0x40,0xc0,0x40,0xf8,0x80,
+ 0x40,0x30,0x08,0x08,0x88,0x70,0x70,0x88,
+ 0x08,0x08,0x30,0x08,0x88,0x70,0x10,0x10,
+ 0xf8,0x90,0x50,0x50,0x30,0x10,0x70,0x88,
+ 0x08,0x08,0xf0,0x80,0x80,0xf8,0x70,0x88,
+ 0x88,0xc8,0xb0,0x80,0x88,0x70,0x40,0x40,
+ 0x20,0x20,0x10,0x10,0x08,0xf8,0x70,0x88,
+ 0x88,0x88,0x70,0x88,0x88,0x70,0x70,0x88,
+ 0x08,0x68,0x98,0x88,0x88,0x70,0x80,0x00,
+ 0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x00,
+ 0x00,0x00,0x00,0x40,0x20,0x40,0x80,0x40,
+ 0x20,0xf0,0x00,0xf0,0x80,0x40,0x20,0x40,
+ 0x80,0x40,0x00,0x40,0x40,0x20,0x10,0x90,
+ 0x60,0x3e,0x00,0x40,0x00,0x9b,0x00,0xa4,
+ 0x80,0xa4,0x80,0xa2,0x40,0x92,0x40,0x4d,
+ 0x40,0x20,0x80,0x1f,0x00,0x82,0x82,0x7c,
+ 0x44,0x28,0x28,0x10,0x10,0xf0,0x88,0x88,
+ 0x88,0xf0,0x88,0x88,0xf0,0x78,0x84,0x80,
+ 0x80,0x80,0x80,0x84,0x78,0xf0,0x88,0x84,
+ 0x84,0x84,0x84,0x88,0xf0,0xf8,0x80,0x80,
+ 0x80,0xf8,0x80,0x80,0xf8,0x80,0x80,0x80,
+ 0x80,0xf0,0x80,0x80,0xf8,0x74,0x8c,0x84,
+ 0x8c,0x80,0x80,0x84,0x78,0x84,0x84,0x84,
+ 0x84,0xfc,0x84,0x84,0x84,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x60,0x90,0x10,
+ 0x10,0x10,0x10,0x10,0x10,0x88,0x88,0x90,
+ 0x90,0xe0,0xa0,0x90,0x88,0xf0,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x92,0x92,0x92,
+ 0xaa,0xaa,0xc6,0xc6,0x82,0x8c,0x8c,0x94,
+ 0x94,0xa4,0xa4,0xc4,0xc4,0x78,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x78,0x80,0x80,0x80,
+ 0x80,0xf0,0x88,0x88,0xf0,0x02,0x7c,0x8c,
+ 0x94,0x84,0x84,0x84,0x84,0x78,0x88,0x88,
+ 0x88,0x88,0xf0,0x88,0x88,0xf0,0x70,0x88,
+ 0x88,0x08,0x70,0x80,0x88,0x70,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0xf8,0x78,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x10,0x28,
+ 0x28,0x44,0x44,0x44,0x82,0x82,0x22,0x00,
+ 0x22,0x00,0x22,0x00,0x55,0x00,0x49,0x00,
+ 0x49,0x00,0x88,0x80,0x88,0x80,0x88,0x88,
+ 0x50,0x50,0x20,0x50,0x88,0x88,0x10,0x10,
+ 0x10,0x28,0x28,0x44,0x44,0x82,0xf8,0x80,
+ 0x40,0x20,0x20,0x10,0x08,0xf8,0xc0,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xc0,
+ 0x20,0x20,0x40,0x40,0x40,0x40,0x80,0x80,
+ 0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+ 0x40,0xc0,0x88,0x50,0x50,0x20,0x20,0xfc,
+ 0x80,0x80,0x40,0x68,0x90,0x90,0x70,0x10,
+ 0xe0,0xb0,0xc8,0x88,0x88,0xc8,0xb0,0x80,
+ 0x80,0x60,0x90,0x80,0x80,0x90,0x60,0x68,
+ 0x98,0x88,0x88,0x98,0x68,0x08,0x08,0x60,
+ 0x90,0x80,0xf0,0x90,0x60,0x40,0x40,0x40,
+ 0x40,0x40,0xe0,0x40,0x30,0x70,0x08,0x68,
+ 0x98,0x88,0x88,0x98,0x68,0x88,0x88,0x88,
+ 0x88,0xc8,0xb0,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x00,0x80,0x90,0x90,
+ 0xa0,0xc0,0xa0,0x90,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x92,0x92,
+ 0x92,0x92,0x92,0xec,0x88,0x88,0x88,0x88,
+ 0xc8,0xb0,0x70,0x88,0x88,0x88,0x88,0x70,
+ 0x80,0x80,0xb0,0xc8,0x88,0x88,0xc8,0xb0,
+ 0x08,0x08,0x68,0x98,0x88,0x88,0x98,0x68,
+ 0x80,0x80,0x80,0x80,0xc0,0xa0,0x60,0x90,
+ 0x10,0x60,0x90,0x60,0x60,0x40,0x40,0x40,
+ 0x40,0xe0,0x40,0x40,0x70,0x90,0x90,0x90,
+ 0x90,0x90,0x20,0x20,0x50,0x50,0x88,0x88,
+ 0x28,0x28,0x54,0x54,0x92,0x92,0x88,0x88,
+ 0x50,0x20,0x50,0x88,0x80,0x40,0x40,0x60,
+ 0xa0,0xa0,0x90,0x90,0xf0,0x80,0x40,0x20,
+ 0x10,0xf0,0x20,0x40,0x40,0x40,0x40,0x80,
+ 0x40,0x40,0x40,0x20,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,
+ 0x40,0x40,0x40,0x20,0x40,0x40,0x40,0x80,
+ 0x98,0x64,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x00,0x80,0x40,0x70,0xa8,0xa0,0xa0,0xa8,
+ 0x70,0x10,0xb0,0x48,0x40,0x40,0xe0,0x40,
+ 0x48,0x30,0x90,0x60,0x90,0x90,0x60,0x90,
+ 0x20,0xf8,0x20,0xf8,0x50,0x50,0x88,0x88,
+ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x80,
+ 0x80,0x80,0x70,0x88,0x18,0x70,0xc8,0x98,
+ 0x70,0xc0,0x88,0x70,0xa0,0x38,0x44,0x9a,
+ 0xa2,0x9a,0x44,0x38,0xe0,0x00,0xa0,0x20,
+ 0xe0,0x28,0x50,0xa0,0x50,0x28,0x08,0x08,
+ 0xf8,0xe0,0x38,0x44,0xaa,0xb2,0xba,0x44,
+ 0x38,0xe0,0x60,0x90,0x90,0x60,0xf8,0x00,
+ 0x20,0x20,0xf8,0x20,0x20,0xe0,0x40,0xa0,
+ 0x60,0xc0,0x20,0x40,0xe0,0x80,0x40,0x80,
+ 0x80,0xf0,0x90,0x90,0x90,0x90,0x90,0x28,
+ 0x28,0x28,0x28,0x28,0x68,0xe8,0xe8,0xe8,
+ 0x7c,0xc0,0xc0,0x40,0x40,0x40,0xc0,0x40,
+ 0xe0,0x00,0xe0,0xa0,0xe0,0xa0,0x50,0x28,
+ 0x50,0xa0,0x21,0x00,0x17,0x80,0x13,0x00,
+ 0x09,0x00,0x48,0x00,0x44,0x00,0xc4,0x00,
+ 0x42,0x00,0x27,0x12,0x15,0x0b,0x48,0x44,
+ 0xc4,0x42,0x21,0x00,0x17,0x80,0x13,0x00,
+ 0x09,0x00,0xc8,0x00,0x24,0x00,0x44,0x00,
+ 0xe2,0x00,0x60,0x90,0x80,0x40,0x20,0x20,
+ 0x00,0x20,0x82,0x82,0x7c,0x44,0x28,0x28,
+ 0x10,0x10,0x00,0x10,0x20,0x82,0x82,0x7c,
+ 0x44,0x28,0x28,0x10,0x10,0x00,0x10,0x08,
+ 0x82,0x82,0x7c,0x44,0x28,0x28,0x10,0x10,
+ 0x00,0x28,0x10,0x82,0x82,0x7c,0x44,0x28,
+ 0x28,0x10,0x10,0x00,0x28,0x14,0x82,0x82,
+ 0x7c,0x44,0x28,0x28,0x10,0x10,0x00,0x28,
+ 0x82,0x82,0x7c,0x44,0x28,0x28,0x10,0x10,
+ 0x10,0x28,0x10,0x8f,0x80,0x88,0x00,0x78,
+ 0x00,0x48,0x00,0x2f,0x80,0x28,0x00,0x18,
+ 0x00,0x1f,0x80,0x30,0x10,0x78,0x84,0x80,
+ 0x80,0x80,0x80,0x84,0x78,0xf8,0x80,0x80,
+ 0x80,0xf8,0x80,0x80,0xf8,0x00,0x20,0x40,
+ 0xf8,0x80,0x80,0x80,0xf8,0x80,0x80,0xf8,
+ 0x00,0x20,0x10,0xf8,0x80,0x80,0xf8,0x80,
+ 0x80,0x80,0xf8,0x00,0x50,0x20,0xf8,0x80,
+ 0x80,0x80,0xf8,0x80,0x80,0xf8,0x00,0x50,
+ 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+ 0x00,0x40,0x80,0x80,0x80,0x80,0x80,0x80,
+ 0x80,0x80,0x80,0x00,0x80,0x40,0x40,0x40,
+ 0x40,0x40,0x40,0x40,0x40,0x40,0x00,0xa0,
+ 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+ 0x40,0x00,0xa0,0x78,0x44,0x42,0x42,0xf2,
+ 0x42,0x44,0x78,0x8c,0x8c,0x94,0x94,0xa4,
+ 0xa4,0xc4,0xc4,0x00,0x50,0x28,0x78,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x78,0x00,0x10,
+ 0x20,0x78,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x78,0x00,0x10,0x08,0x78,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x78,0x00,0x28,0x10,0x78,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x78,0x00,
+ 0x50,0x28,0x78,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x78,0x00,0x48,0x88,0x50,0x20,0x50,
+ 0x88,0x80,0x78,0xc4,0xa4,0xa4,0x94,0x94,
+ 0x8c,0x78,0x04,0x78,0x84,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x00,0x10,0x20,0x78,0x84,
+ 0x84,0x84,0x84,0x84,0x84,0x84,0x00,0x20,
+ 0x10,0x78,0x84,0x84,0x84,0x84,0x84,0x84,
+ 0x84,0x00,0x28,0x10,0x78,0x84,0x84,0x84,
+ 0x84,0x84,0x84,0x84,0x00,0x48,0x10,0x10,
+ 0x10,0x28,0x28,0x44,0x44,0x82,0x00,0x10,
+ 0x08,0x80,0x80,0xf0,0x88,0x88,0xf0,0x80,
+ 0x80,0xa0,0x90,0x90,0x90,0xa0,0x90,0x90,
+ 0x60,0x68,0x90,0x90,0x70,0x10,0xe0,0x00,
+ 0x20,0x40,0x68,0x90,0x90,0x70,0x10,0xe0,
+ 0x00,0x20,0x10,0x68,0x90,0x90,0x70,0x10,
+ 0xe0,0x00,0x50,0x20,0x68,0x90,0x90,0x70,
+ 0x10,0xe0,0x00,0xa0,0x50,0x68,0x90,0x90,
+ 0x70,0x10,0xe0,0x00,0x50,0x68,0x90,0x90,
+ 0x70,0x10,0xe0,0x20,0x50,0x20,0x6c,0x92,
+ 0x90,0x7e,0x12,0xec,0x60,0x20,0x60,0x90,
+ 0x80,0x80,0x90,0x60,0x60,0x90,0x80,0xf0,
+ 0x90,0x60,0x00,0x20,0x40,0x60,0x90,0x80,
+ 0xf0,0x90,0x60,0x00,0x40,0x20,0x60,0x90,
+ 0x80,0xf0,0x90,0x60,0x00,0x50,0x20,0x60,
+ 0x90,0x80,0xf0,0x90,0x60,0x00,0x50,0x40,
+ 0x40,0x40,0x40,0x40,0x40,0x00,0x40,0x80,
+ 0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x80,
+ 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,
+ 0xa0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+ 0x00,0xa0,0x70,0x88,0x88,0x88,0x88,0x78,
+ 0x90,0x60,0x50,0x90,0x90,0x90,0x90,0x90,
+ 0xe0,0x00,0xa0,0x50,0x70,0x88,0x88,0x88,
+ 0x88,0x70,0x00,0x20,0x40,0x70,0x88,0x88,
+ 0x88,0x88,0x70,0x00,0x20,0x10,0x70,0x88,
+ 0x88,0x88,0x88,0x70,0x00,0x50,0x20,0x70,
+ 0x88,0x88,0x88,0x88,0x70,0x00,0x50,0x28,
+ 0x70,0x88,0x88,0x88,0x88,0x70,0x00,0x50,
+ 0x20,0x00,0xf8,0x00,0x20,0x70,0x88,0xc8,
+ 0xa8,0x98,0x74,0x70,0x90,0x90,0x90,0x90,
+ 0x90,0x00,0x20,0x40,0x70,0x90,0x90,0x90,
+ 0x90,0x90,0x00,0x40,0x20,0x70,0x90,0x90,
+ 0x90,0x90,0x90,0x00,0x50,0x20,0x70,0x90,
+ 0x90,0x90,0x90,0x90,0x00,0x50,0x80,0x40,
+ 0x40,0x60,0xa0,0xa0,0x90,0x90,0x00,0x20,
+ 0x10,0x80,0x80,0xb0,0xc8,0x88,0x88,0xc8,
+ 0xb0,0x80,0x80,0x80,0x40,0x40,0x60,0xa0,
+ 0xa0,0x90,0x90,0x00,0x50,
+};
+
+FontDataBLF blf_font_helv10 = {
+ -1, -2,
+ 10, 11,
+ {
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0, 0, 0, 0, 12, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0, 0, 0, 0, 3, -1},
+ {1, 8, -1, 0, 3, 0},
+ {3, 2, -1, -6, 4, 8},
+ {6, 7, 0, 0, 6, 10},
+ {5, 9, 0, 1, 6, 17},
+ {8, 8, 0, 0, 9, 26},
+ {6, 8, -1, 0, 8, 34},
+ {2, 3, -1, -5, 3, 42},
+ {3, 10, 0, 2, 4, 45},
+ {3, 10, -1, 2, 4, 55},
+ {3, 3, 0, -5, 4, 65},
+ {5, 5, 0, -1, 6, 68},
+ {2, 3, 0, 2, 3, 73},
+ {5, 1, -1, -3, 7, 76},
+ {1, 1, -1, 0, 3, 77},
+ {3, 8, 0, 0, 3, 78},
+ {5, 8, 0, 0, 6, 86},
+ {2, 8, -1, 0, 6, 94},
+ {5, 8, 0, 0, 6, 102},
+ {5, 8, 0, 0, 6, 110},
+ {5, 8, 0, 0, 6, 118},
+ {5, 8, 0, 0, 6, 126},
+ {5, 8, 0, 0, 6, 134},
+ {5, 8, 0, 0, 6, 142},
+ {5, 8, 0, 0, 6, 150},
+ {5, 8, 0, 0, 6, 158},
+ {1, 6, -1, 0, 3, 166},
+ {2, 8, 0, 2, 3, 172},
+ {3, 5, -1, -1, 6, 180},
+ {4, 3, 0, -2, 5, 185},
+ {3, 5, -1, -1, 6, 188},
+ {4, 8, -1, 0, 6, 193},
+ {10, 10, 0, 2, 11, 201},
+ {7, 8, 0, 0, 7, 221},
+ {5, 8, -1, 0, 7, 229},
+ {6, 8, -1, 0, 8, 237},
+ {6, 8, -1, 0, 8, 245},
+ {5, 8, -1, 0, 7, 253},
+ {5, 8, -1, 0, 6, 261},
+ {6, 8, -1, 0, 8, 269},
+ {6, 8, -1, 0, 8, 277},
+ {1, 8, -1, 0, 3, 285},
+ {4, 8, 0, 0, 5, 293},
+ {5, 8, -1, 0, 7, 301},
+ {4, 8, -1, 0, 6, 309},
+ {7, 8, -1, 0, 9, 317},
+ {6, 8, -1, 0, 8, 325},
+ {6, 8, -1, 0, 8, 333},
+ {5, 8, -1, 0, 7, 341},
+ {7, 9, -1, 1, 8, 349},
+ {5, 8, -1, 0, 7, 358},
+ {5, 8, -1, 0, 7, 366},
+ {5, 8, 0, 0, 5, 374},
+ {6, 8, -1, 0, 8, 382},
+ {7, 8, 0, 0, 7, 390},
+ {9, 8, 0, 0, 9, 398},
+ {5, 8, -1, 0, 7, 414},
+ {7, 8, 0, 0, 7, 422},
+ {5, 8, -1, 0, 7, 430},
+ {2, 10, -1, 2, 3, 438},
+ {3, 8, 0, 0, 3, 448},
+ {2, 10, 0, 2, 3, 456},
+ {5, 5, 0, -3, 6, 466},
+ {6, 1, 0, 2, 6, 471},
+ {2, 3, 0, -5, 3, 472},
+ {5, 6, 0, 0, 5, 475},
+ {5, 8, 0, 0, 6, 481},
+ {4, 6, 0, 0, 5, 489},
+ {5, 8, 0, 0, 6, 495},
+ {4, 6, 0, 0, 5, 503},
+ {4, 8, 0, 0, 4, 509},
+ {5, 8, 0, 2, 6, 517},
+ {5, 8, 0, 0, 6, 525},
+ {1, 8, 0, 0, 2, 533},
+ {1, 9, 0, 1, 2, 541},
+ {4, 8, 0, 0, 5, 550},
+ {1, 8, 0, 0, 2, 558},
+ {7, 6, 0, 0, 8, 566},
+ {5, 6, 0, 0, 6, 572},
+ {5, 6, 0, 0, 6, 578},
+ {5, 8, 0, 2, 6, 584},
+ {5, 8, 0, 2, 6, 592},
+ {3, 6, 0, 0, 4, 600},
+ {4, 6, 0, 0, 5, 606},
+ {3, 8, 0, 0, 4, 612},
+ {4, 6, 0, 0, 5, 620},
+ {5, 6, 0, 0, 6, 626},
+ {7, 6, 0, 0, 8, 632},
+ {5, 6, 0, 0, 6, 638},
+ {4, 8, 0, 2, 5, 644},
+ {4, 6, 0, 0, 5, 652},
+ {3, 10, 0, 2, 3, 658},
+ {1, 10, -1, 2, 3, 668},
+ {3, 10, 0, 2, 3, 678},
+ {6, 2, 0, -3, 7, 688},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0,0,0,0,0, -1},
+ {0, 0, 0, 0, 3, -1},
+ {1, 8, -1, 2, 3, 690},
+ {5, 8, 0, 1, 6, 698},
+ {5, 8, 0, 0, 6, 706},
+ {4, 6, 0, -1, 5, 714},
+ {5, 8, 0, 0, 6, 720},
+ {1, 10, -1, 2, 3, 728},
+ {5, 10, 0, 2, 6, 738},
+ {3, 1, 0, -7, 3, 748},
+ {7, 7, -1, 0, 9, 749},
+ {3, 5, 0, -3, 4, 756},
+ {5, 5, 0, 0, 6, 761},
+ {5, 3, -1, -2, 7, 766},
+ {3, 1, 0, -3, 4, 769},
+ {7, 7, -1, 0, 9, 770},
+ {3, 1, 0, -7, 3, 777},
+ {4, 4, 0, -3, 4, 778},
+ {5, 7, 0, 0, 6, 782},
+ {3, 4, 0, -3, 3, 789},
+ {3, 4, 0, -3, 3, 793},
+ {2, 2, 0, -6, 3, 797},
+ {4, 8, 0, 2, 5, 799},
+ {6, 10, 0, 2, 6, 807},
+ {2, 1, 0, -3, 3, 817},
+ {2, 2, 0, 2, 3, 818},
+ {2, 4, 0, -3, 3, 820},
+ {3, 5, 0, -3, 4, 824},
+ {5, 5, 0, 0, 6, 829},
+ {9, 8, 0, 0, 9, 834},
+ {8, 8, 0, 0, 9, 850},
+ {9, 8, 0, 0, 9, 858},
+ {4, 8, -1, 2, 6, 874},
+ {7, 11, 0, 0, 7, 882},
+ {7, 11, 0, 0, 7, 893},
+ {7, 11, 0, 0, 7, 904},
+ {7, 11, 0, 0, 7, 915},
+ {7, 10, 0, 0, 7, 926},
+ {7, 11, 0, 0, 7, 936},
+ {9, 8, 0, 0, 10, 947},
+ {6, 10, -1, 2, 8, 963},
+ {5, 11, -1, 0, 7, 973},
+ {5, 11, -1, 0, 7, 984},
+ {5, 11, -1, 0, 7, 995},
+ {5, 10, -1, 0, 7, 1006},
+ {2, 11, 0, 0, 3, 1016},
+ {2, 11, -1, 0, 3, 1027},
+ {3, 11, 0, 0, 3, 1038},
+ {3, 10, 0, 0, 3, 1049},
+ {7, 8, 0, 0, 8, 1059},
+ {6, 11, -1, 0, 8, 1067},
+ {6, 11, -1, 0, 8, 1078},
+ {6, 11, -1, 0, 8, 1089},
+ {6, 11, -1, 0, 8, 1100},
+ {6, 11, -1, 0, 8, 1111},
+ {6, 10, -1, 0, 8, 1122},
+ {5, 5, 0, -1, 6, 1132},
+ {6, 10, -1, 1, 8, 1137},
+ {6, 11, -1, 0, 8, 1147},
+ {6, 11, -1, 0, 8, 1158},
+ {6, 11, -1, 0, 8, 1169},
+ {6, 10, -1, 0, 8, 1180},
+ {7, 11, 0, 0, 7, 1190},
+ {5, 8, -1, 0, 7, 1201},
+ {4, 8, 0, 0, 5, 1209},
+ {5, 9, 0, 0, 5, 1217},
+ {5, 9, 0, 0, 5, 1226},
+ {5, 9, 0, 0, 5, 1235},
+ {5, 9, 0, 0, 5, 1244},
+ {5, 8, 0, 0, 5, 1253},
+ {5, 9, 0, 0, 5, 1261},
+ {7, 6, 0, 0, 8, 1270},
+ {4, 8, 0, 2, 5, 1276},
+ {4, 9, 0, 0, 5, 1284},
+ {4, 9, 0, 0, 5, 1293},
+ {4, 9, 0, 0, 5, 1302},
+ {4, 8, 0, 0, 5, 1311},
+ {2, 9, 1, 0, 2, 1319},
+ {2, 9, 0, 0, 2, 1328},
+ {3, 9, 1, 0, 2, 1337},
+ {3, 8, 0, 0, 2, 1346},
+ {5, 9, 0, 0, 6, 1354},
+ {4, 9, 0, 0, 5, 1363},
+ {5, 9, 0, 0, 6, 1372},
+ {5, 9, 0, 0, 6, 1381},
+ {5, 9, 0, 0, 6, 1390},
+ {5, 9, 0, 0, 6, 1399},
+ {5, 8, 0, 0, 6, 1408},
+ {5, 5, 0, -1, 6, 1416},
+ {6, 6, 0, 0, 6, 1421},
+ {4, 9, 0, 0, 5, 1427},
+ {4, 9, 0, 0, 5, 1436},
+ {4, 9, 0, 0, 5, 1445},
+ {4, 8, 0, 0, 5, 1454},
+ {4, 11, 0, 2, 5, 1462},
+ {5, 10, 0, 2, 6, 1473},
+ {4, 10, 0, 2, 5, 1483},
+ },
+ helv10_bitmap_data,
+ 0
+};
+
+#endif /* BLF_FONT_HELV10_H */
diff --git a/source/blender/blenfont/intern/blf_internal.c b/source/blender/blenfont/intern/blf_internal.c
new file mode 100644
index 00000000000..d5ec20f790a
--- /dev/null
+++ b/source/blender/blenfont/intern/blf_internal.c
@@ -0,0 +1,290 @@
+/**
+ * $Id:
+ *
+ * ***** 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) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef WITH_FREETYPE2
+
+#include <ft2build.h>
+
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+
+#endif /* WITH_FREETYPE2 */
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_vec_types.h"
+
+#include "BKE_utildefines.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_linklist.h" /* linknode */
+#include "BLI_string.h"
+#include "BLI_arithb.h"
+
+#include "BIF_gl.h"
+#include "BLF_api.h"
+
+#include "blf_internal_types.h"
+#include "blf_internal.h"
+#include "blf_font_helv10.h"
+
+
+int blf_internal_get_texture(FontBLF *font)
+{
+ FontDataBLF *data;
+ CharDataBLF *cd;
+ int width;
+ int height;
+ int c_rows, c_cols, c_width, c_height;
+ int i_width, i_height;
+ GLubyte *img, *img_row, *chr_row, *img_pxl;
+ int base_line, i, cell_x, cell_y, y, x;
+ int byte_idx, bit_idx;
+
+ data= (FontDataBLF *)font->engine;
+ if (data->texid != 0)
+ return(0);
+
+ width= data->xmax - data->xmin;
+ height= data->ymax - data->ymin;
+ c_rows= 16;
+ c_cols= 16;
+ c_width= 16;
+ c_height= 16;
+ i_width= c_cols * c_width;
+ i_height= c_rows * c_height;
+ base_line= -(data->ymin);
+ img= (GLubyte *)malloc(i_height * i_width);
+ memset((void *)img, 0, i_height * i_width);
+
+ if (width >= 16 || height >= 16) {
+ printf("Warning: Bad font size for: %s\n", font->name);
+ return(-1);
+ }
+
+ for (i= 0; i < 256; i++) {
+ cd= &data->chars[i];
+
+ if (cd->data_offset != -1) {
+ cell_x= i%16;
+ cell_y= i/16;
+
+ for (y= 0; y < cd->height; y++) {
+ img_row = &img[(cell_y*c_height + y + base_line - cd->yorig)*i_width];
+ chr_row = &data->bitmap_data[cd->data_offset + ((cd->width+7)/8)*y];
+
+ for (x= 0; x < cd->width; x++) {
+ img_pxl= &img_row[(cell_x*c_width + x - cd->xorig)];
+ byte_idx= x/8;
+ bit_idx= 7 - (x%8);
+
+ if (chr_row[byte_idx]&(1<<bit_idx)) {
+ img_pxl[0]= 255;
+ }
+ }
+ }
+ }
+ }
+
+ glGenTextures(1, &data->texid);
+ glBindTexture(GL_TEXTURE_2D, data->texid);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA4, i_width, i_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, img);
+ if (glGetError()) {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE4_ALPHA4, i_width, i_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, img);
+ }
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ free((void *)img);
+ return(0);
+}
+
+void blf_internal_size(FontBLF *font, int size, int dpi)
+{
+ return;
+}
+
+void blf_internal_draw(FontBLF *font, char *str)
+{
+ FontDataBLF *data;
+ CharDataBLF *cd;
+ unsigned char c;
+ float pos, cell_x, cell_y, x, y, z;
+ int base_line;
+ GLint cur_tex;
+
+ data= (FontDataBLF *)font->engine;
+ base_line= -(data->ymin);
+ pos= 0;
+ x= 0.0f;
+ y= 0.0f;
+ z= 0.0f;
+
+ glGetIntegerv(GL_TEXTURE_2D_BINDING_EXT, &cur_tex);
+ if (cur_tex != data->texid)
+ glBindTexture(GL_TEXTURE_2D, data->texid);
+
+ glBegin(GL_QUADS);
+ while ((c= (unsigned char) *str++)) {
+ cd= &data->chars[c];
+
+ if (cd->data_offset != -1) {
+ cell_x= (c%16)/16.0;
+ cell_y= (c/16)/16.0;
+
+ glTexCoord2f(cell_x + 1.0/16.0, cell_y);
+ glVertex3f(x + pos + 16.0, -base_line + y + 0.0, z);
+
+ glTexCoord2f(cell_x + 1.0/16.0, cell_y + 1.0/16.0);
+ glVertex3f(x + pos + 16.0, -base_line + y + 16.0, z);
+
+ glTexCoord2f(cell_x, cell_y + 1.0/16.0);
+ glVertex3f(x + pos + 0.0, -base_line + y + 16.0, z);
+
+ glTexCoord2f(cell_x, cell_y);
+ glVertex3f(x + pos + 0.0, -base_line + y + 0.0, z);
+ }
+
+ pos += cd->advance;
+ }
+ glEnd();
+}
+
+void blf_internal_boundbox(FontBLF *font, char *str, rctf *box)
+{
+ FontDataBLF *data;
+ unsigned char c;
+ int length= 0;
+ int ascent= 0;
+ int descent= 0;
+
+ data= (FontDataBLF *)font->engine;
+ while ((c= (unsigned char) *str++)) {
+ int d = data->chars[c].yorig;
+ int a = data->chars[c].height - data->chars[c].yorig;
+
+ length += data->chars[c].advance;
+ if (a > ascent)
+ ascent= a;
+ if (d > descent)
+ descent= d;
+ }
+ box->xmin = (float)0;
+ box->ymin = (float)-descent;
+ box->xmax = (float)length;
+ box->ymax = (float)ascent;
+}
+
+float blf_internal_width(FontBLF *font, char *str)
+{
+ FontDataBLF *data;
+ unsigned char c;
+ int length= 0;
+
+ data= (FontDataBLF *)font->engine;
+ while ((c= (unsigned char) *str++)) {
+ length += data->chars[c].advance;
+ }
+
+ return((float)(length * font->aspect));
+}
+
+float blf_internal_height(FontBLF *font, char *str)
+{
+ FontDataBLF *data;
+
+ data= (FontDataBLF *)font->engine;
+ return(((float)(data->ymax - data->ymin)) * font->aspect);
+}
+
+void blf_internal_free(FontBLF *font)
+{
+ MEM_freeN(font->name);
+ MEM_freeN(font);
+}
+
+FontBLF *blf_internal_new(char *name)
+{
+ FontBLF *font;
+
+ font= (FontBLF *)MEM_mallocN(sizeof(FontBLF), "blf_internal_new");
+ font->name= BLI_strdup(name);
+ font->filename= NULL;
+
+ if (!strcmp(name, "helv10")) {
+ font->engine= (void *)&blf_font_helv10;
+ font->size= 10;
+ }
+ else
+ font->engine= NULL;
+
+ if (!font->engine) {
+ MEM_freeN(font->name);
+ MEM_freeN(font);
+ return(NULL);
+ }
+
+ font->type= BLF_FONT_INTERNAL;
+ font->ref= 1;
+ font->aspect= 1.0f;
+ font->pos[0]= 0.0f;
+ font->pos[1]= 0.0f;
+ font->angle= 0.0f;
+ Mat4One(font->mat);
+ font->clip_rec.xmin= 0.0f;
+ font->clip_rec.xmax= 0.0f;
+ font->clip_rec.ymin= 0.0f;
+ font->clip_rec.ymax= 0.0f;
+ font->flags= 0;
+ font->dpi= 72;
+ font->cache.first= NULL;
+ font->cache.last= NULL;
+ font->glyph_cache= NULL;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&font->max_tex_size);
+
+ font->size_set= blf_internal_size;
+ font->draw= blf_internal_draw;
+ font->boundbox_get= blf_internal_boundbox;
+ font->width_get= blf_internal_width;
+ font->height_get= blf_internal_height;
+ font->free= blf_internal_free;
+
+ if (blf_internal_get_texture(font) != 0) {
+ MEM_freeN(font->name);
+ MEM_freeN(font);
+ return(NULL);
+ }
+
+ return(font);
+}
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index d160df67f18..87d5938db9c 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -38,6 +38,8 @@ int blf_dir_split(const char *str, char *file, int *size);
int blf_font_init(void);
void blf_font_exit(void);
+FontBLF *blf_internal_new(char *name);
+
#ifdef WITH_FREETYPE2
FontBLF *blf_font_new(char *name, char *filename);
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 7313eb97426..9df04522b1f 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -171,6 +171,24 @@ typedef struct FontBLF {
void (*free)(struct FontBLF *);
} FontBLF;
+typedef struct CharDataBLF {
+ signed char width, height;
+ signed char xorig, yorig;
+ signed char advance;
+
+ short data_offset;
+} CharDataBLF;
+
+typedef struct FontDataBLF {
+ int xmin, ymin;
+ int xmax, ymax;
+
+ CharDataBLF chars[256];
+ unsigned char *bitmap_data;
+
+ GLuint texid;
+} FontDataBLF;
+
typedef struct DirBLF {
struct DirBLF *next;
struct DirBLF *prev;
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 4146d313d41..9eb0b15aed4 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -34,6 +34,7 @@
struct ID;
struct Brush;
struct ImBuf;
+struct Scene;
struct wmOperator;
/* datablock functions */
@@ -43,6 +44,7 @@ void make_local_brush(struct Brush *brush);
void free_brush(struct Brush *brush);
/* brush library operations used by different paint panels */
+struct Brush **current_brush_source(struct Scene *sce);
int brush_set_nr(struct Brush **current_brush, int nr);
int brush_delete(struct Brush **current_brush);
void brush_check_exists(struct Brush **brush);
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index e384900e0cb..f08b14c7820 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -33,6 +33,7 @@ extern "C" {
#endif
#include "DNA_listBase.h"
+#include "RNA_types.h"
struct ARegion;
struct bScreen;
@@ -58,6 +59,7 @@ struct wmWindow;
struct wmWindowManager;
struct SpaceText;
struct SpaceImage;
+struct ID;
/* Structs */
@@ -67,68 +69,15 @@ typedef struct bContext bContext;
struct bContextDataResult;
typedef struct bContextDataResult bContextDataResult;
-enum {
- CTX_DATA_MAIN,
- CTX_DATA_SCENE,
- CTX_DATA_TOOL_SETTINGS,
-
- CTX_DATA_SELECTED_OBJECTS,
- CTX_DATA_SELECTED_BASES,
- CTX_DATA_SELECTED_EDITABLE_OBJECTS,
- CTX_DATA_SELECTED_EDITABLE_BASES,
- CTX_DATA_VISIBLE_OBJECTS,
- CTX_DATA_VISIBLE_BASES,
-
- CTX_DATA_ACTIVE_OBJECT,
- CTX_DATA_ACTIVE_BASE,
- CTX_DATA_EDIT_OBJECT,
-
- CTX_DATA_EDIT_IMAGE,
- CTX_DATA_EDIT_IMAGE_BUFFER,
-
- CTX_DATA_EDIT_TEXT,
-
- CTX_DATA_SELECTED_NODES,
-
- CTX_DATA_SELECTED_BONES,
- CTX_DATA_SELECTED_EDITABLE_BONES,
- CTX_DATA_SELECTED_PCHANS,
-
- CTX_DATA_ACTIVE_BONE,
- CTX_DATA_ACTIVE_PCHAN,
-
- CTX_DATA_VISIBLE_BONES,
- CTX_DATA_EDITABLE_BONES,
- CTX_DATA_VISIBLE_PCHANS,
-};
-
-typedef int bContextDataMember;
-
typedef int (*bContextDataCallback)(const bContext *C,
- bContextDataMember member, bContextDataResult *result);
+ const char *member, bContextDataResult *result);
/* Context */
bContext *CTX_create(void);
void CTX_free(bContext *C);
-bContext *CTX_copy(const bContext *C, int thread);
-int CTX_thread(const bContext *C);
-
-/* Context Task and Reports */
-
-typedef enum bContextTask {
- CTX_DRAWING = 0,
- CTX_EDITING = 1,
- CTX_EVALUATING = 2,
- CTX_UNDEFINED = 3
-} bContextTask;
-
-bContextTask CTX_task(const bContext *C);
-void CTX_task_set(bContext *C, bContextTask task);
-
-struct ReportList *CTX_reports(const bContext *C);
-void CTX_reports_set(bContext *C, struct ReportList *reports);
+bContext *CTX_copy(const bContext *C);
/* Window Manager Context */
@@ -139,7 +88,7 @@ struct ScrArea *CTX_wm_area(const bContext *C);
struct SpaceLink *CTX_wm_space_data(const bContext *C);
struct ARegion *CTX_wm_region(const bContext *C);
void *CTX_wm_region_data(const bContext *C);
-struct uiBlock *CTX_wm_ui_block(const bContext *C);
+struct ARegion *CTX_wm_menu(const bContext *C);
struct View3D *CTX_wm_view3d(const bContext *C);
struct RegionView3D *CTX_wm_region_view3d(const bContext *C);
@@ -149,25 +98,37 @@ struct SpaceImage *CTX_wm_space_image(const bContext *C);
void CTX_wm_manager_set(bContext *C, struct wmWindowManager *wm);
void CTX_wm_window_set(bContext *C, struct wmWindow *win);
void CTX_wm_screen_set(bContext *C, struct bScreen *screen); /* to be removed */
-void CTX_wm_area_set(bContext *C, struct ScrArea *win);
-void CTX_wm_region_set(bContext *C, struct ARegion *win);
-void CTX_wm_ui_block_set(bContext *C, struct uiBlock *block, bContextDataCallback cb);
+void CTX_wm_area_set(bContext *C, struct ScrArea *sa);
+void CTX_wm_region_set(bContext *C, struct ARegion *region);
+void CTX_wm_menu_set(bContext *C, struct ARegion *menu);
/* Data Context
- note: listbases consist of LinkData items and must be
freed with BLI_freelistN! */
-void CTX_data_pointer_set(bContextDataResult *result, void *data);
-void CTX_data_list_add(bContextDataResult *result, void *data);
+PointerRNA CTX_data_pointer_get(bContext *C, const char *member);
+ListBase CTX_data_collection_get(bContext *C, const char *member);
+void CTX_data_get(bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb);
+
+void CTX_data_id_pointer_set(bContextDataResult *result, struct ID *id);
+void CTX_data_pointer_set(bContextDataResult *result, struct ID *id, StructRNA *type, void *data);
+
+void CTX_data_id_list_add(bContextDataResult *result, struct ID *id);
+void CTX_data_list_add(bContextDataResult *result, struct ID *id, StructRNA *type, void *data);
+
+int CTX_data_equals(const char *member, const char *str);
+
+/*void CTX_data_pointer_set(bContextDataResult *result, void *data);
+void CTX_data_list_add(bContextDataResult *result, void *data);*/
#define CTX_DATA_BEGIN(C, Type, instance, member) \
{ \
ListBase ctx_data_list; \
- LinkData *link; \
+ CollectionPointerLink *ctx_link; \
CTX_data_##member(C, &ctx_data_list); \
- for(link=ctx_data_list.first; link; link=link->next) { \
- Type instance= link->data;
+ for(ctx_link=ctx_data_list.first; ctx_link; ctx_link=ctx_link->next) { \
+ Type instance= ctx_link->ptr.data;
#define CTX_DATA_END \
} \
@@ -202,7 +163,6 @@ struct Base *CTX_data_active_base(const bContext *C);
struct Object *CTX_data_edit_object(const bContext *C);
struct Image *CTX_data_edit_image(const bContext *C);
-struct ImBuf *CTX_data_edit_image_buffer(const bContext *C);
struct Text *CTX_data_edit_text(const bContext *C);
@@ -218,13 +178,6 @@ struct bPoseChannel *CTX_data_active_pchan(const bContext *C);
int CTX_data_selected_pchans(const bContext *C, ListBase *list);
int CTX_data_visible_pchans(const bContext *C, ListBase *list);
-/* Data Evaluation Context */
-
-float CTX_eval_frame(const bContext *C);
-
-int CTX_eval_render_resolution(const bContext *C);
-void CTX_eval_render_resolution_set(bContext *C, int render);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index a8b1ad49648..9503c569e8b 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -44,6 +44,8 @@ typedef struct FModifierTypeInfo {
/* admin/ident */
short type; /* FMODIFIER_TYPE_### */
short size; /* size in bytes of the struct */
+ short acttype; /* eFMI_Action_Types */
+ short requires; /* eFMI_Requirement_Flags */
char name[32]; /* name of modifier in interface */
char structName[32]; /* name of struct for SDNA */
@@ -54,25 +56,53 @@ typedef struct FModifierTypeInfo {
void (*copy_data)(struct FModifier *fcm, struct FModifier *src);
/* set settings for data that will be used for FCuModifier.data (memory already allocated using MEM_callocN) */
void (*new_data)(void *mdata);
+ /* verifies that the modifier settings are valid */
+ void (*verify_data)(struct FModifier *fcm);
/* evaluation */
/* evaluate the modifier for the given time and 'accumulated' value */
void (*evaluate_modifier)(struct FCurve *fcu, struct FModifier *fcm, float *cvalue, float evaltime);
} FModifierTypeInfo;
+/* Values which describe the behaviour of a FModifier Type */
+enum {
+ /* modifier only modifies values outside of data range */
+ FMI_TYPE_EXTRAPOLATION = 0,
+ /* modifier leaves data-points alone, but adjusts the interpolation between and around them */
+ FMI_TYPE_INTERPOLATION,
+ /* modifier only modifies the values of points (but times stay the same) */
+ FMI_TYPE_REPLACE_VALUES,
+ /* modifier generates a curve regardless of what came before */
+ FMI_TYPE_GENERATE_CURVE,
+} eFMI_Action_Types;
+
+/* Flags for the requirements of a FModifier Type */
+enum {
+ /* modifier requires original data-points (kindof beats the purpose of a modifier stack?) */
+ FMI_REQUIRES_ORIGINAL_DATA = (1<<0),
+ /* modifier doesn't require on any preceeding data (i.e. it will generate a curve).
+ * Use in conjunction with FMI_TYPE_GENRATE_CURVE
+ */
+ FMI_REQUIRES_NOTHING = (1<<1),
+ /* refer to modifier instance */
+ FMI_REQUIRES_RUNTIME_CHECK = (1<<2),
+} eFMI_Requirement_Flags;
+
/* Function Prototypes for FModifierTypeInfo's */
FModifierTypeInfo *fmodifier_get_typeinfo(struct FModifier *fcm);
FModifierTypeInfo *get_fmodifier_typeinfo(int type);
/* ---------------------- */
-// TODO... general API here..
struct FModifier *fcurve_add_modifier(struct FCurve *fcu, int type);
void fcurve_copy_modifiers(ListBase *dst, ListBase *src);
void fcurve_remove_modifier(struct FCurve *fcu, struct FModifier *fcm);
void fcurve_free_modifiers(struct FCurve *fcu);
void fcurve_bake_modifiers(struct FCurve *fcu, int start, int end);
+struct FModifier *fcurve_find_active_modifier(struct FCurve *fcu);
+void fcurve_set_active_modifier(struct FCurve *fcu, struct FModifier *fcm);
+
/* ************** F-Curves API ******************** */
/* -------- Data Managemnt -------- */
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h
index a3f451438bd..e12170b73c9 100644
--- a/source/blender/blenkernel/BKE_ipo.h
+++ b/source/blender/blenkernel/BKE_ipo.h
@@ -38,7 +38,7 @@ extern "C" {
struct Main;
struct Ipo;
-void do_versions_ipo_to_animato(struct Main *main);
+void do_versions_ipos_to_animato(struct Main *main);
/* --------------------- xxx stuff ------------------------ */
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 7d0c5b83e6e..09237e74d1d 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -388,28 +388,32 @@ void free_compbuf(struct CompBuf *cbuf); /* internal...*/
struct TexResult;
-#define TEX_NODE_OUTPUT 101
-#define TEX_NODE_CHECKER 102
-#define TEX_NODE_TEXTURE 103
-#define TEX_NODE_BRICKS 104
-#define TEX_NODE_MATH 105
-#define TEX_NODE_MIX_RGB 106
-#define TEX_NODE_RGBTOBW 107
-#define TEX_NODE_VALTORGB 108
-#define TEX_NODE_IMAGE 109
-#define TEX_NODE_CURVE_RGB 110
-#define TEX_NODE_INVERT 111
-#define TEX_NODE_HUE_SAT 112
-#define TEX_NODE_CURVE_TIME 113
-#define TEX_NODE_ROTATE 114
-#define TEX_NODE_VIEWER 115
-#define TEX_NODE_TRANSLATE 116
-#define TEX_NODE_COORD 117
-#define TEX_NODE_DISTANCE 118
+#define TEX_NODE_OUTPUT 401
+#define TEX_NODE_CHECKER 402
+#define TEX_NODE_TEXTURE 403
+#define TEX_NODE_BRICKS 404
+#define TEX_NODE_MATH 405
+#define TEX_NODE_MIX_RGB 406
+#define TEX_NODE_RGBTOBW 407
+#define TEX_NODE_VALTORGB 408
+#define TEX_NODE_IMAGE 409
+#define TEX_NODE_CURVE_RGB 410
+#define TEX_NODE_INVERT 411
+#define TEX_NODE_HUE_SAT 412
+#define TEX_NODE_CURVE_TIME 413
+#define TEX_NODE_ROTATE 414
+#define TEX_NODE_VIEWER 415
+#define TEX_NODE_TRANSLATE 416
+#define TEX_NODE_COORD 417
+#define TEX_NODE_DISTANCE 418
+#define TEX_NODE_COMPOSE 419
+#define TEX_NODE_DECOMPOSE 420
+#define TEX_NODE_VALTONOR 421
+#define TEX_NODE_SCALE 422
/* 201-299 reserved. Use like this: TEX_NODE_PROC + TEX_CLOUDS, etc */
-#define TEX_NODE_PROC 200
-#define TEX_NODE_PROC_MAX 300
+#define TEX_NODE_PROC 500
+#define TEX_NODE_PROC_MAX 600
extern struct ListBase node_all_textures;
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 250aaf7245a..a25a7cff51d 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -36,11 +36,14 @@ struct bContext;
struct bContextDataResult;
struct bScreen;
struct ListBase;
+struct Panel;
struct ScrArea;
struct SpaceType;
struct wmNotifier;
struct wmWindow;
struct wmWindowManager;
+struct uiLayout;
+struct uiMenuItem;
/* spacetype has everything stored to get an editor working, it gets initialized via
ED_spacetypes_init() in editors/area/spacetypes.c */
@@ -77,7 +80,7 @@ typedef struct SpaceType {
void (*keymap)(struct wmWindowManager *);
/* return context data */
- int (*context)(const struct bContext *, int, struct bContextDataResult *);
+ int (*context)(const struct bContext *, const char*, struct bContextDataResult *);
/* region type definitions */
ListBase regiontypes;
@@ -117,17 +120,55 @@ typedef struct ARegionType {
void (*cursor)(struct wmWindow *, struct ScrArea *, struct ARegion *ar);
/* return context data */
- int (*context)(const struct bContext *, int, struct bContextDataResult *);
+ int (*context)(const struct bContext *, const char *, struct bContextDataResult *);
/* custom drawing callbacks */
ListBase drawcalls;
+ /* panels type definitions */
+ ListBase paneltypes;
+
+ /* header type definitions */
+ ListBase headertypes;
+
/* hardcoded constraints, smaller than these values region is not visible */
int minsizex, minsizey;
/* default keymaps to add */
int keymapflag;
} ARegionType;
+/* panel types */
+
+typedef struct PanelType {
+ struct PanelType *next, *prev;
+
+ char *idname; /* unique name */
+ char *name; /* for panel header */
+ char *context; /* for buttons window */
+
+ /* verify if the panel should draw or not */
+ int (*poll)(const struct bContext *);
+ /* draw entirely, view changes should be handled here */
+ void (*draw)(const struct bContext *, struct Panel *);
+
+ /* python integration */
+ void *py_data;
+} PanelType;
+
+/* header types */
+
+typedef struct HeaderType {
+ struct HeaderType *next, *prev;
+
+ char *idname; /* unique name */
+ char *name; /* for UI */
+
+ /* draw entirely, view changes should be handled here */
+ void (*draw)(const struct bContext *, struct uiLayout *);
+
+ /* python integration */
+ void *py_data;
+} HeaderType;
/* spacetypes */
struct SpaceType *BKE_spacetype_from_id(int spaceid);
@@ -139,6 +180,7 @@ void BKE_spacetypes_free(void); /* only for quitting blender */
/* spacedata */
void BKE_spacedata_freelist(ListBase *lb);
void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2);
+void BKE_spacedata_copyfirst(ListBase *lb1, ListBase *lb2);
/* area/regions */
struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *ar);
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/anim.c b/source/blender/blenkernel/intern/anim.c
index 8c71a1d807e..fcd179d48de 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -34,6 +34,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
#include "BLI_arithb.h"
#include "BLI_rand.h"
#include "DNA_listBase.h"
@@ -72,6 +73,8 @@
#include <config.h>
#endif
+#include "ED_mesh.h"
+
static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int level, int animated);
void free_path(Path *path)
@@ -445,6 +448,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
Scene *sce = NULL;
Group *group = NULL;
GroupObject * go = NULL;
+ EditMesh *em;
float vec[3], no[3], pmat[4][4];
int lay, totvert, a, oblay;
@@ -452,12 +456,15 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
/* simple preventing of too deep nested groups */
if(level>MAX_DUPLI_RECUR) return;
-
- if(me->edit_mesh)
- dm= editmesh_get_derived_cage(scene, par, me->edit_mesh, CD_MASK_BAREMESH);
- else
+
+ em = EM_GetEditMesh(me);
+
+ if(em) {
+ dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
+ EM_EndEditMesh(me, em);
+ } else
dm= mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
-
+
if(G.rendering) {
vdd.orco= (float(*)[3])get_mesh_orco_verts(par);
transform_mesh_orco_verts(me, vdd.orco, me->totvert, 0);
@@ -557,17 +564,19 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
Scene *sce = NULL;
Group *group = NULL;
GroupObject *go = NULL;
+ EditMesh *em;
float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
/* simple preventing of too deep nested groups */
if(level>MAX_DUPLI_RECUR) return;
Mat4CpyMat4(pmat, par->obmat);
-
- if(me->edit_mesh) {
+
+ em = EM_GetEditMesh(me);
+ if(em) {
int totvert;
- dm= editmesh_get_derived_cage(scene, par, me->edit_mesh, CD_MASK_BAREMESH);
+ dm= editmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
totface= dm->getNumFaces(dm);
mface= MEM_mallocN(sizeof(MFace)*totface, "mface temp");
@@ -575,6 +584,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
totvert= dm->getNumVerts(dm);
mvert= MEM_mallocN(sizeof(MVert)*totvert, "mvert temp");
dm->copyVertArray(dm, mvert);
+
+ EM_EndEditMesh(me, em);
}
else {
dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index be64faec3cf..2033250585d 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -348,7 +348,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
CTX_data_scene_set(C, bfd->curscreen->scene);
CTX_wm_area_set(C, NULL);
CTX_wm_region_set(C, NULL);
- CTX_wm_ui_block_set(C, NULL, NULL);
+ CTX_wm_menu_set(C, NULL);
}
/* this can happen when active scene was lib-linked, and doesnt exist anymore */
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index e5dd9c2188d..30a35cbe91c 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -103,6 +103,8 @@ Brush *copy_brush(Brush *brush)
}
}
+ brushn->curve= curvemapping_copy(brush->curve);
+
/* enable fake user by default */
if (!(brushn->id.flag & LIB_FAKEUSER)) {
brushn->id.flag |= LIB_FAKEUSER;
@@ -183,6 +185,19 @@ void make_local_brush(Brush *brush)
/* Library Operations */
+Brush **current_brush_source(Scene *sce)
+{
+ if(G.f & G_SCULPTMODE)
+ return &sce->toolsettings->sculpt->brush;
+ else if(G.f & G_VERTEXPAINT)
+ return &sce->toolsettings->vpaint->brush;
+ else if(G.f & G_WEIGHTPAINT)
+ return &sce->toolsettings->wpaint->brush;
+ else if(G.f & G_TEXTUREPAINT)
+ return &sce->toolsettings->imapaint.brush;
+ return NULL;
+}
+
int brush_set_nr(Brush **current_brush, int nr)
{
ID *idtest, *id;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 5c8bec3af6f..b238116f0a1 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -38,6 +38,7 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
+#include "BLI_editVert.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
@@ -70,6 +71,7 @@
#include "BPY_extern.h"
#endif
+#include "ED_mesh.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -390,6 +392,7 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
{
DerivedMesh *dm;
Mesh *me= ob->data;
+ EditMesh *em = EM_GetEditMesh(me);
float vec[3] = {0.0f, 0.0f, 0.0f}, tvec[3];
float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
float imat[3][3], tmat[3][3];
@@ -403,9 +406,9 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
if (dgroup < 0) return;
/* get DerivedMesh */
- if (me->edit_mesh) {
+ if (em) {
/* target is in editmode, so get a special derived mesh */
- dm = CDDM_from_editmesh(me->edit_mesh, ob->data);
+ dm = CDDM_from_editmesh(em, ob->data);
}
else {
/* when not in EditMode, this should exist */
@@ -475,8 +478,9 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
}
/* free temporary DerivedMesh created (in EditMode case) */
- if (me->edit_mesh) {
+ if (em) {
if (dm) dm->release(dm);
+ EM_EndEditMesh(me, em);
}
}
@@ -3108,7 +3112,7 @@ static bConstraintTypeInfo CTI_TRANSFORM = {
/* ************************* Constraints Type-Info *************************** */
/* All of the constraints api functions use bConstraintTypeInfo structs to carry out
- * and operations that involve constraint specifc code.
+ * and operations that involve constraint specific code.
*/
/* These globals only ever get directly accessed in this file */
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index fc338e1bc95..47622611cb9 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -27,6 +27,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_ID.h"
#include "DNA_listBase.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -48,8 +49,6 @@
/* struct */
struct bContext {
- bContextTask task;
- ReportList *reports;
int thread;
/* windowmanager context */
@@ -59,9 +58,7 @@ struct bContext {
struct bScreen *screen;
struct ScrArea *area;
struct ARegion *region;
- struct uiBlock *block;
-
- bContextDataCallback block_cb;
+ struct ARegion *menu;
} wm;
/* data context */
@@ -86,57 +83,21 @@ bContext *CTX_create()
C= MEM_callocN(sizeof(bContext), "bContext");
- C->task= CTX_UNDEFINED;
- C->thread= 0;
-
return C;
}
-bContext *CTX_copy(const bContext *C, int thread)
+bContext *CTX_copy(const bContext *C)
{
- bContext *newC;
-
- if(C->task != CTX_UNDEFINED)
- BKE_report(C->reports, RPT_ERROR_INVALID_CONTEXT, "CTX_copy not allowed for this task");
-
- newC= MEM_dupallocN((void*)C);
- newC->thread= thread;
+ bContext *newC= MEM_dupallocN((void*)C);
return newC;
}
-int CTX_thread(const bContext *C)
-{
- return C->thread;
-}
-
void CTX_free(bContext *C)
{
MEM_freeN(C);
}
-/* context task and reports */
-
-bContextTask CTX_task(const bContext *C)
-{
- return C->task;
-}
-
-void CTX_task_set(bContext *C, bContextTask task)
-{
- C->task= task;
-}
-
-ReportList *CTX_reports(const bContext *C)
-{
- return C->reports;
-}
-
-void CTX_reports_set(bContext *C, ReportList *reports)
-{
- C->reports= reports;
-}
-
/* window manager context */
wmWindowManager *CTX_wm_manager(const bContext *C)
@@ -174,9 +135,9 @@ void *CTX_wm_region_data(const bContext *C)
return (C->wm.region)? C->wm.region->regiondata: NULL;
}
-struct uiBlock *CTX_wm_ui_block(const bContext *C)
+struct ARegion *CTX_wm_menu(const bContext *C)
{
- return C->wm.block;
+ return C->wm.menu;
}
View3D *CTX_wm_view3d(const bContext *C)
@@ -245,20 +206,19 @@ void CTX_wm_region_set(bContext *C, ARegion *region)
C->wm.region= region;
}
-void CTX_wm_ui_block_set(bContext *C, struct uiBlock *block, bContextDataCallback cb)
+void CTX_wm_menu_set(bContext *C, ARegion *menu)
{
- C->wm.block= block;
- C->wm.block_cb= cb;
+ C->wm.menu= menu;
}
/* data context utility functions */
struct bContextDataResult {
- void *pointer;
+ PointerRNA ptr;
ListBase list;
};
-static int ctx_data_get(bContext *C, bContextDataMember member, bContextDataResult *result)
+static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
{
int done= 0, recursion= C->data.recursion;
@@ -266,23 +226,19 @@ static int ctx_data_get(bContext *C, bContextDataMember member, bContextDataResu
/* we check recursion to ensure that we do not get infinite
* loops requesting data from ourselfs in a context callback */
- if(!done && recursion < 1 && C->wm.block) {
+ if(!done && recursion < 1 && C->wm.region) {
C->data.recursion= 1;
- done= C->wm.block_cb(C, member, result);
- }
- if(!done && recursion < 2 && C->wm.region) {
- C->data.recursion= 2;
if(C->wm.region->type && C->wm.region->type->context)
done= C->wm.region->type->context(C, member, result);
}
- if(!done && recursion < 3 && C->wm.area) {
- C->data.recursion= 3;
+ if(!done && recursion < 2 && C->wm.area) {
+ C->data.recursion= 2;
if(C->wm.area->type && C->wm.area->type->context)
done= C->wm.area->type->context(C, member, result);
}
- if(!done && recursion < 4 && C->wm.screen) {
+ if(!done && recursion < 3 && C->wm.screen) {
bContextDataCallback cb= C->wm.screen->context;
- C->data.recursion= 4;
+ C->data.recursion= 3;
if(cb)
done= cb(C, member, result);
}
@@ -292,22 +248,22 @@ static int ctx_data_get(bContext *C, bContextDataMember member, bContextDataResu
return done;
}
-static void *ctx_data_pointer_get(const bContext *C, bContextDataMember member)
+static void *ctx_data_pointer_get(const bContext *C, const char *member)
{
bContextDataResult result;
if(ctx_data_get((bContext*)C, member, &result))
- return result.pointer;
+ return result.ptr.data;
return NULL;
}
-static int ctx_data_pointer_verify(const bContext *C, bContextDataMember member, void **pointer)
+static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
{
bContextDataResult result;
if(ctx_data_get((bContext*)C, member, &result)) {
- *pointer= result.pointer;
+ *pointer= result.ptr.data;
return 1;
}
else {
@@ -316,7 +272,7 @@ static int ctx_data_pointer_verify(const bContext *C, bContextDataMember member,
}
}
-static int ctx_data_collection_get(const bContext *C, bContextDataMember member, ListBase *list)
+static int ctx_data_collection_get(const bContext *C, const char *member, ListBase *list)
{
bContextDataResult result;
@@ -328,17 +284,80 @@ static int ctx_data_collection_get(const bContext *C, bContextDataMember member,
return 0;
}
-void CTX_data_pointer_set(bContextDataResult *result, void *data)
+PointerRNA CTX_data_pointer_get(bContext *C, const char *member)
{
- result->pointer= data;
+ bContextDataResult result;
+
+ if(ctx_data_get((bContext*)C, member, &result)) {
+ return result.ptr;
+ }
+ else {
+ PointerRNA ptr;
+ memset(&ptr, 0, sizeof(ptr));
+ return ptr;
+ }
+
}
-void CTX_data_list_add(bContextDataResult *result, void *data)
+ListBase CTX_data_collection_get(bContext *C, const char *member)
{
- LinkData *link;
-
- link= MEM_callocN(sizeof(LinkData), "LinkData");
- link->data= data;
+ bContextDataResult result;
+
+ if(ctx_data_get((bContext*)C, member, &result)) {
+ return result.list;
+ }
+ else {
+ ListBase list;
+ memset(&list, 0, sizeof(list));
+ return list;
+ }
+}
+
+void CTX_data_get(bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb)
+{
+ bContextDataResult result;
+
+ if(ctx_data_get((bContext*)C, member, &result)) {
+ *r_ptr= result.ptr;
+ *r_lb= result.list;
+ }
+ else {
+ memset(r_ptr, 0, sizeof(*r_ptr));
+ memset(r_lb, 0, sizeof(*r_lb));
+ }
+}
+
+int CTX_data_equals(const char *member, const char *str)
+{
+ return (strcmp(member, str) == 0);
+}
+
+void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
+{
+ RNA_id_pointer_create(id, &result->ptr);
+}
+
+void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
+{
+ RNA_pointer_create(id, type, data, &result->ptr);
+}
+
+void CTX_data_id_list_add(bContextDataResult *result, ID *id)
+{
+ CollectionPointerLink *link;
+
+ link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_id_list_add");
+ RNA_id_pointer_create(id, &link->ptr);
+
+ BLI_addtail(&result->list, link);
+}
+
+void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data)
+{
+ CollectionPointerLink *link;
+
+ link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_list_add");
+ RNA_pointer_create(id, type, data, &link->ptr);
BLI_addtail(&result->list, link);
}
@@ -362,7 +381,7 @@ Main *CTX_data_main(const bContext *C)
{
Main *bmain;
- if(ctx_data_pointer_verify(C, CTX_DATA_MAIN, (void*)&bmain))
+ if(ctx_data_pointer_verify(C, "main", (void*)&bmain))
return bmain;
else
return C->data.main;
@@ -377,7 +396,7 @@ Scene *CTX_data_scene(const bContext *C)
{
Scene *scene;
- if(ctx_data_pointer_verify(C, CTX_DATA_SCENE, (void*)&scene))
+ if(ctx_data_pointer_verify(C, "scene", (void*)&scene))
return scene;
else
return C->data.scene;
@@ -400,124 +419,101 @@ ToolSettings *CTX_data_tool_settings(const bContext *C)
int CTX_data_selected_nodes(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_SELECTED_NODES, list);
+ return ctx_data_collection_get(C, "selected_nodes", list);
}
int CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_SELECTED_EDITABLE_OBJECTS, list);
+ return ctx_data_collection_get(C, "selected_editable_objects", list);
}
int CTX_data_selected_editable_bases(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_SELECTED_EDITABLE_BASES, list);
+ return ctx_data_collection_get(C, "selected_editable_bases", list);
}
int CTX_data_selected_objects(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_SELECTED_OBJECTS, list);
+ return ctx_data_collection_get(C, "selected_objects", list);
}
int CTX_data_selected_bases(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_SELECTED_BASES, list);
+ return ctx_data_collection_get(C, "selected_bases", list);
}
int CTX_data_visible_objects(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_VISIBLE_OBJECTS, list);
+ return ctx_data_collection_get(C, "visible_objects", list);
}
int CTX_data_visible_bases(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_VISIBLE_BASES, list);
+ return ctx_data_collection_get(C, "visible_bases", list);
}
struct Object *CTX_data_active_object(const bContext *C)
{
- return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_OBJECT);
+ return ctx_data_pointer_get(C, "active_object");
}
struct Base *CTX_data_active_base(const bContext *C)
{
- return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_BASE);
+ return ctx_data_pointer_get(C, "active_base");
}
struct Object *CTX_data_edit_object(const bContext *C)
{
- return ctx_data_pointer_get(C, CTX_DATA_EDIT_OBJECT);
+ return ctx_data_pointer_get(C, "edit_object");
}
struct Image *CTX_data_edit_image(const bContext *C)
{
- return ctx_data_pointer_get(C, CTX_DATA_EDIT_IMAGE);
-}
-
-struct ImBuf *CTX_data_edit_image_buffer(const bContext *C)
-{
- return ctx_data_pointer_get(C, CTX_DATA_EDIT_IMAGE_BUFFER);
+ return ctx_data_pointer_get(C, "edit_image");
}
struct Text *CTX_data_edit_text(const bContext *C)
{
- return ctx_data_pointer_get(C, CTX_DATA_EDIT_TEXT);
+ return ctx_data_pointer_get(C, "edit_text");
}
struct EditBone *CTX_data_active_bone(const bContext *C)
{
- return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_BONE);
+ return ctx_data_pointer_get(C, "active_bone");
}
int CTX_data_selected_bones(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_SELECTED_BONES, list);
+ return ctx_data_collection_get(C, "selected_bones", list);
}
int CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_SELECTED_EDITABLE_BONES, list);
+ return ctx_data_collection_get(C, "selected_editable_bones", list);
}
int CTX_data_visible_bones(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_VISIBLE_BONES, list);
+ return ctx_data_collection_get(C, "visible_bones", list);
}
int CTX_data_editable_bones(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_EDITABLE_BONES, list);
+ return ctx_data_collection_get(C, "editable_bones", list);
}
struct bPoseChannel *CTX_data_active_pchan(const bContext *C)
{
- return ctx_data_pointer_get(C, CTX_DATA_ACTIVE_PCHAN);
+ return ctx_data_pointer_get(C, "active_pchan");
}
int CTX_data_selected_pchans(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_SELECTED_PCHANS, list);
+ return ctx_data_collection_get(C, "selected_pchans", list);
}
int CTX_data_visible_pchans(const bContext *C, ListBase *list)
{
- return ctx_data_collection_get(C, CTX_DATA_VISIBLE_PCHANS, list);
-}
-
-
-/* data evaluation */
-
-float CTX_eval_frame(const bContext *C)
-{
- return (C->data.scene)? C->data.scene->r.cfra: 0.0f;
-}
-
-int CTX_eval_render_resolution(const bContext *C)
-{
- return C->eval.render;
-}
-
-void CTX_eval_render_resolution_set(bContext *C, int render)
-{
- C->eval.render= render;
+ return ctx_data_collection_get(C, "visible_pchans", list);
}
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 0f48133efc7..917fb7d1de4 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -55,7 +55,7 @@
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h"
-#include "DNA_oops_types.h"
+#include "DNA_outliner_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
index 249d3db9423..ae423cdd3aa 100644
--- a/source/blender/blenkernel/intern/exotic.c
+++ b/source/blender/blenkernel/intern/exotic.c
@@ -2388,7 +2388,7 @@ void write_stl(Scene *scene, char *str)
static void write_videoscape_mesh(Scene *scene, Object *ob, char *str)
{
Mesh *me= ob->data;
- EditMesh *em = me->edit_mesh;
+ EditMesh *em = EM_GetEditMesh(me);
Material *ma;
MFace *mface;
FILE *fp;
@@ -2489,6 +2489,8 @@ static void write_videoscape_mesh(Scene *scene, Object *ob, char *str)
}
fclose(fp);
+
+ if (em) EM_EndEditMesh(em);
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 6f3cad7995c..2dfa1db171f 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -6,6 +6,7 @@
#include <math.h>
#include <stdio.h>
#include <string.h>
+#include <float.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -58,7 +59,7 @@ void free_fcurve (FCurve *fcu)
fcurve_free_driver(fcu);
fcurve_free_modifiers(fcu);
- /* free f-cruve itself */
+ /* free f-curve itself */
MEM_freeN(fcu);
}
@@ -1105,25 +1106,39 @@ static float fcurve_eval_samples (FCurve *fcu, FPoint *fpts, float evaltime)
static FModifierTypeInfo FMI_MODNAME = {
FMODIFIER_TYPE_MODNAME, /* type */
sizeof(FMod_ModName), /* size */
+ FMI_TYPE_SOME_ACTION, /* action type */
+ FMI_REQUIRES_SOME_REQUIREMENT, /* requirements */
"Modifier Name", /* name */
"FMod_ModName", /* struct name */
fcm_modname_free, /* free data */
fcm_modname_relink, /* relink data */
fcm_modname_copy, /* copy data */
fcm_modname_new_data, /* new data */
+ fcm_modname_verify, /* verify */
fcm_modname_evaluate /* evaluate */
};
#endif
/* Generator F-Curve Modifier --------------------------- */
+/* Generators available:
+ * 1) simple polynomial generator:
+ * - Exanded form - (y = C[0]*(x^(n)) + C[1]*(x^(n-1)) + ... + C[n])
+ * - Factorised form - (y = (C[0][0]*x + C[0][1]) * (C[1][0]*x + C[1][1]) * ... * (C[n][0]*x + C[n][1]))
+ * 2) simple builin 'functions':
+ * of the form (y = C[0] * fn( C[1]*x + C[2] ) + C[3])
+ * where fn() can be any one of:
+ * sin, cos, tan, ln, sqrt
+ * 3) expression...
+ */
+
static void fcm_generator_free (FModifier *fcm)
{
FMod_Generator *data= (FMod_Generator *)fcm->data;
/* free polynomial coefficients array */
- if (data->poly_coefficients)
- MEM_freeN(data->poly_coefficients);
+ if (data->coefficients)
+ MEM_freeN(data->coefficients);
}
static void fcm_generator_copy (FModifier *fcm, FModifier *src)
@@ -1131,9 +1146,9 @@ static void fcm_generator_copy (FModifier *fcm, FModifier *src)
FMod_Generator *gen= (FMod_Generator *)fcm->data;
FMod_Generator *ogen= (FMod_Generator *)src->data;
- /* copy polynomial coefficients array? */
- if (ogen->poly_coefficients)
- gen->poly_coefficients= MEM_dupallocN(ogen->poly_coefficients);
+ /* copy coefficients array? */
+ if (ogen->coefficients)
+ gen->coefficients= MEM_dupallocN(ogen->coefficients);
}
static void fcm_generator_new_data (void *mdata)
@@ -1143,33 +1158,225 @@ static void fcm_generator_new_data (void *mdata)
/* set default generator to be linear 0-1 (gradient = 1, y-offset = 0) */
data->poly_order= 1;
- cp= data->poly_coefficients= MEM_callocN(sizeof(float)*2, "FMod_Generator_Coefs");
+ data->arraysize= 2;
+ cp= data->coefficients= MEM_callocN(sizeof(float)*2, "FMod_Generator_Coefs");
cp[0] = 0; // y-offset
cp[1] = 1; // gradient
}
+static void fcm_generator_verify (FModifier *fcm)
+{
+ FMod_Generator *data= (FMod_Generator *)fcm->data;
+
+ /* requirements depend on mode */
+ switch (data->mode) {
+ case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */
+ {
+ /* arraysize needs to be order+1, so resize if not */
+ if (data->arraysize != (data->poly_order+1)) {
+ float *nc;
+
+ /* make new coefficients array, and copy over as much data as can fit */
+ nc= MEM_callocN(sizeof(float)*(data->poly_order+1), "FMod_Generator_Coefs");
+
+ if (data->coefficients) {
+ if (data->arraysize > (data->poly_order+1))
+ memcpy(nc, data->coefficients, sizeof(float)*(data->poly_order+1));
+ else
+ memcpy(nc, data->coefficients, sizeof(float)*data->arraysize);
+
+ /* free the old data */
+ MEM_freeN(data->coefficients);
+ }
+
+ /* set the new data */
+ data->coefficients= nc;
+ data->arraysize= data->poly_order+1;
+ }
+ }
+ break;
+
+ case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* expanded polynomial expression */
+ {
+ /* arraysize needs to be 2*order, so resize if not */
+ if (data->arraysize != (data->poly_order * 2)) {
+ float *nc;
+
+ /* make new coefficients array, and copy over as much data as can fit */
+ nc= MEM_callocN(sizeof(float)*(data->poly_order*2), "FMod_Generator_Coefs");
+
+ if (data->coefficients) {
+ if (data->arraysize > (data->poly_order * 2))
+ memcpy(nc, data->coefficients, sizeof(float)*(data->poly_order * 2));
+ else
+ memcpy(nc, data->coefficients, sizeof(float)*data->arraysize);
+
+ /* free the old data */
+ MEM_freeN(data->coefficients);
+ }
+
+ /* set the new data */
+ data->coefficients= nc;
+ data->arraysize= data->poly_order * 2;
+ }
+ }
+ break;
+
+ case FCM_GENERATOR_FUNCTION: /* builtin function */
+ {
+ /* arraysize needs to be 4*/
+ if (data->arraysize != 4) {
+ float *nc;
+
+ /* free the old data */
+ if (data->coefficients)
+ MEM_freeN(data->coefficients);
+
+ /* make new coefficients array, and init using default values */
+ nc= data->coefficients= MEM_callocN(sizeof(float)*4, "FMod_Generator_Coefs");
+ data->arraysize= 4;
+
+ nc[0]= 1.0f;
+ nc[1]= 1.0f;
+ nc[2]= 0.0f;
+ nc[3]= 0.0f;
+ }
+ }
+ break;
+ }
+}
static void fcm_generator_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
{
FMod_Generator *data= (FMod_Generator *)fcm->data;
- /* behaviour depends on mode (NOTE: we don't need to do anything...) */
+ /* behaviour depends on mode
+ * NOTE: the data in its default state is fine too
+ */
switch (data->mode) {
- case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
+ case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */
{
/* we overwrite cvalue with the sum of the polynomial */
- float value= 0.0f, *cp = NULL;
+ float *powers = MEM_callocN(sizeof(float)*data->arraysize, "Poly Powers");
+ float value= 0.0f;
unsigned int i;
+ /* for each x^n, precalculate value based on previous one first... this should be
+ * faster that calling pow() for each entry
+ */
+ for (i=0; i < data->arraysize; i++) {
+ /* first entry is x^0 = 1, otherwise, calculate based on previous */
+ if (i)
+ powers[i]= powers[i-1] * evaltime;
+ else
+ powers[0]= 1;
+ }
+
/* for each coefficient, add to value, which we'll write to *cvalue in one go */
- // TODO: could this be more efficient (i.e. without need to recalc pow() everytime)
- cp= data->poly_coefficients;
- for (i=0; (i <= data->poly_order) && (cp); i++, cp++)
- value += (*cp) * (float)pow(evaltime, i);
+ for (i=0; i < data->arraysize; i++)
+ value += data->coefficients[i] * powers[i];
- /* only if something changed */
- if (data->poly_order)
- *cvalue= value;
+ /* only if something changed, write *cvalue in one go */
+ if (data->poly_order) {
+ if (data->flag & FCM_GENERATOR_ADDITIVE)
+ *cvalue += value;
+ else
+ *cvalue= value;
+ }
+
+ /* cleanup */
+ if (powers)
+ MEM_freeN(powers);
+ }
+ break;
+
+ case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* factorised polynomial */
+ {
+ float value= 1.0f, *cp=NULL;
+ unsigned int i;
+
+ /* for each coefficient pair, solve for that bracket before accumulating in value by multiplying */
+ for (cp=data->coefficients, i=0; (cp) && (i < data->poly_order); cp+=2, i++)
+ value *= (cp[0]*evaltime + cp[1]);
+
+ /* only if something changed, write *cvalue in one go */
+ if (data->poly_order) {
+ if (data->flag & FCM_GENERATOR_ADDITIVE)
+ *cvalue += value;
+ else
+ *cvalue= value;
+ }
+ }
+ break;
+
+ case FCM_GENERATOR_FUNCTION: /* builtin function */
+ {
+ double arg= data->coefficients[1]*evaltime + data->coefficients[2];
+ double (*fn)(double v) = NULL;
+
+ /* get function pointer to the func to use:
+ * WARNING: must perform special argument validation hereto guard against crashes
+ */
+ switch (data->func_type)
+ {
+ /* simple ones */
+ case FCM_GENERATOR_FN_SIN: /* sine wave */
+ fn= sin;
+ break;
+ case FCM_GENERATOR_FN_COS: /* cosine wave */
+ fn= cos;
+ break;
+
+ /* validation required */
+ case FCM_GENERATOR_FN_TAN: /* tangent wave */
+ {
+ /* check that argument is not on one of the discontinuities (i.e. 90deg, 270 deg, etc) */
+ if IS_EQ(fmod((arg - M_PI_2), M_PI), 0.0) {
+ if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
+ *cvalue = 0.0f; /* no value possible here */
+ }
+ else
+ fn= tan;
+ }
+ break;
+ case FCM_GENERATOR_FN_LN: /* natural log */
+ {
+ /* check that value is greater than 1? */
+ if (arg > 1.0f) {
+ fn= log;
+ }
+ else {
+ if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
+ *cvalue = 0.0f; /* no value possible here */
+ }
+ }
+ break;
+ case FCM_GENERATOR_FN_SQRT: /* square root */
+ {
+ /* no negative numbers */
+ if (arg > 0.0f) {
+ fn= sqrt;
+ }
+ else {
+ if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0)
+ *cvalue = 0.0f; /* no value possible here */
+ }
+ }
+ break;
+
+ default:
+ printf("Invalid Function-Generator for F-Modifier - %d \n", data->func_type);
+ }
+
+ /* execute function callback to set value if appropriate */
+ if (fn) {
+ float value= data->coefficients[0]*fn(arg) + data->coefficients[3];
+
+ if (data->flag & FCM_GENERATOR_ADDITIVE)
+ *cvalue += value;
+ else
+ *cvalue= value;
+ }
}
break;
@@ -1184,11 +1391,14 @@ static void fcm_generator_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue,
static FModifierTypeInfo FMI_GENERATOR = {
FMODIFIER_TYPE_GENERATOR, /* type */
sizeof(FMod_Generator), /* size */
+ FMI_TYPE_GENERATE_CURVE, /* action type */
+ FMI_REQUIRES_NOTHING, /* requirements */
"Generator", /* name */
"FMod_Generator", /* struct name */
fcm_generator_free, /* free data */
fcm_generator_copy, /* copy data */
fcm_generator_new_data, /* new data */
+ fcm_generator_verify, /* verify */
fcm_generator_evaluate /* evaluate */
};
@@ -1196,21 +1406,40 @@ static FModifierTypeInfo FMI_GENERATOR = {
static void fcm_envelope_free (FModifier *fcm)
{
- FMod_Envelope *data= (FMod_Envelope *)fcm->data;
+ FMod_Envelope *env= (FMod_Envelope *)fcm->data;
/* free envelope data array */
- if (data->data)
- MEM_freeN(data->data);
+ if (env->data)
+ MEM_freeN(env->data);
}
static void fcm_envelope_copy (FModifier *fcm, FModifier *src)
{
- FMod_Envelope *gen= (FMod_Envelope *)fcm->data;
- FMod_Envelope *ogen= (FMod_Envelope *)src->data;
+ FMod_Envelope *env= (FMod_Envelope *)fcm->data;
+ FMod_Envelope *oenv= (FMod_Envelope *)src->data;
/* copy envelope data array */
- if (ogen->data)
- gen->data= MEM_dupallocN(ogen->data);
+ if (oenv->data)
+ env->data= MEM_dupallocN(oenv->data);
+}
+
+static void fcm_envelope_new_data (void *mdata)
+{
+ FMod_Envelope *env= (FMod_Envelope *)mdata;
+
+ /* set default min/max ranges */
+ env->min= -1.0f;
+ env->max= 1.0f;
+}
+
+static void fcm_envelope_verify (FModifier *fcm)
+{
+ FMod_Envelope *env= (FMod_Envelope *)fcm->data;
+
+ /* if the are points, perform bubble-sort on them, as user may have changed the order */
+ if (env->data) {
+ // XXX todo...
+ }
}
static void fcm_envelope_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
@@ -1224,7 +1453,7 @@ static void fcm_envelope_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, f
if (env->data == NULL) return;
prevfed= env->data;
fed= prevfed + 1;
- lastfed= prevfed + env->totvert-1;
+ lastfed= prevfed + (env->totvert-1);
/* get min/max values for envelope at evaluation time (relative to mid-value) */
if (prevfed->time >= evaltime) {
@@ -1239,6 +1468,7 @@ static void fcm_envelope_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, f
}
else {
/* evaltime occurs somewhere between segments */
+ // TODO: implement binary search for this to make it faster?
for (a=0; prevfed && fed && (a < env->totvert-1); a++, prevfed=fed, fed++) {
/* evaltime occurs within the interval defined by these two envelope points */
if ((prevfed->time <= evaltime) && (fed->time >= evaltime)) {
@@ -1246,10 +1476,10 @@ static void fcm_envelope_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, f
diff= fed->time - prevfed->time;
afac= (evaltime - prevfed->time) / diff;
- bfac= (fed->time - evaltime)/(diff);
+ bfac= (fed->time - evaltime) / diff;
- min= afac*prevfed->min + bfac*fed->min;
- max= afac*prevfed->max + bfac*fed->max;
+ min= bfac*prevfed->min + afac*fed->min;
+ max= bfac*prevfed->max + afac*fed->max;
break;
}
@@ -1257,20 +1487,24 @@ static void fcm_envelope_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, f
}
/* adjust *cvalue
- * NOTE: env->min/max are relative to env->midval, and can be either +ve OR -ve, so we add...
+ * - fac is the ratio of how the current y-value corresponds to the reference range
+ * - thus, the new value is found by mapping the old range to the new!
*/
- fac= (*cvalue - min) / (max - min);
- *cvalue= (env->midval + env->min) + (fac * (env->max - env->min));
+ fac= (*cvalue - (env->midval + env->min)) / (env->max - env->min);
+ *cvalue= min + fac*(max - min);
}
static FModifierTypeInfo FMI_ENVELOPE = {
FMODIFIER_TYPE_ENVELOPE, /* type */
sizeof(FMod_Envelope), /* size */
+ FMI_TYPE_REPLACE_VALUES, /* action type */
+ 0, /* requirements */
"Envelope", /* name */
"FMod_Envelope", /* struct name */
fcm_envelope_free, /* free data */
fcm_envelope_copy, /* copy data */
- NULL, /* new data */
+ fcm_envelope_new_data, /* new data */
+ fcm_envelope_verify, /* verify */
fcm_envelope_evaluate /* evaluate */
};
@@ -1286,6 +1520,14 @@ static FModifierTypeInfo FMI_ENVELOPE = {
* as appropriate
*/
+static void fcm_cycles_new_data (void *mdata)
+{
+ FMod_Cycles *data= (FMod_Cycles *)mdata;
+
+ /* turn on cycles by default */
+ data->before_mode= data->after_mode= FCM_EXTRAPOLATE_CYCLIC;
+}
+
static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime)
{
FMod_Cycles *data= (FMod_Cycles *)fcm->data;
@@ -1331,7 +1573,7 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
* 2) if before first frame or after last frame, make sure some cycling is in use
*/
if (evaltime < prevkey[0]) {
- if (data->before_mode) {
+ if (data->before_mode) {
side= -1;
mode= data->before_mode;
cycles= data->before_cycles;
@@ -1347,8 +1589,7 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
if ELEM(0, side, mode)
return;
- /* extrapolation mode is 'cyclic' - find relative place within a cycle */
- // FIXME: adding the more fine-grained control of extrpolation mode
+ /* find relative place within a cycle */
{
float cycdx=0, cycdy=0, ofs=0;
@@ -1362,15 +1603,19 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
/* check if cycle is infinitely small, to be point of being impossible to use */
if (cycdx == 0)
return;
+
/* check that cyclic is still enabled for the specified time */
if (cycles == 0) {
/* catch this case so that we don't exit when we have cycles=0
* as this indicates infinite cycles...
*/
}
- else if ( ((float)side * (evaltime - ofs) / cycdx) > cycles )
+ else if ( ((float)side * (evaltime - ofs) / cycdx) > (cycles+1) ) {
+ /* we are too far away from range to evaluate
+ * TODO: but we should still hold last value...
+ */
return;
-
+ }
/* check if 'cyclic extrapolation', and thus calculate y-offset for this cycle */
if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) {
@@ -1399,11 +1644,14 @@ static void fcm_cycles_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
static FModifierTypeInfo FMI_CYCLES = {
FMODIFIER_TYPE_CYCLES, /* type */
sizeof(FMod_Cycles), /* size */
+ FMI_TYPE_EXTRAPOLATION, /* action type */
+ FMI_REQUIRES_ORIGINAL_DATA, /* requirements */
"Cycles", /* name */
"FMod_Cycles", /* struct name */
NULL, /* free data */
NULL, /* copy data */
- NULL, /* new data */
+ fcm_cycles_new_data, /* new data */
+ NULL /*fcm_cycles_verify*/, /* verify */
fcm_cycles_evaluate /* evaluate */
};
@@ -1413,11 +1661,14 @@ static FModifierTypeInfo FMI_CYCLES = {
static FModifierTypeInfo FMI_NOISE = {
FMODIFIER_TYPE_NOISE, /* type */
sizeof(FMod_Noise), /* size */
+ FMI_TYPE_REPLACE_VALUES, /* action type */
+ 0, /* requirements */
"Noise", /* name */
"FMod_Noise", /* struct name */
NULL, /* free data */
NULL, /* copy data */
fcm_noise_new_data, /* new data */
+ NULL /*fcm_noise_verify*/, /* verify */
fcm_noise_evaluate /* evaluate */
};
#endif // XXX not yet implemented
@@ -1428,11 +1679,14 @@ static FModifierTypeInfo FMI_NOISE = {
static FModifierTypeInfo FMI_FILTER = {
FMODIFIER_TYPE_FILTER, /* type */
sizeof(FMod_Filter), /* size */
+ FMI_TYPE_REPLACE_VALUES, /* action type */
+ 0, /* requirements */
"Filter", /* name */
"FMod_Filter", /* struct name */
NULL, /* free data */
NULL, /* copy data */
NULL, /* new data */
+ NULL /*fcm_filter_verify*/, /* verify */
fcm_filter_evaluate /* evaluate */
};
#endif // XXX not yet implemented
@@ -1480,18 +1734,21 @@ static void fcm_python_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, flo
static FModifierTypeInfo FMI_PYTHON = {
FMODIFIER_TYPE_PYTHON, /* type */
sizeof(FMod_Python), /* size */
+ FMI_TYPE_GENERATE_CURVE, /* action type */
+ FMI_REQUIRES_RUNTIME_CHECK, /* requirements */
"Python", /* name */
"FMod_Python", /* struct name */
fcm_python_free, /* free data */
fcm_python_copy, /* copy data */
fcm_python_new_data, /* new data */
+ NULL /*fcm_python_verify*/, /* verify */
fcm_python_evaluate /* evaluate */
};
/* F-Curve Modifier API --------------------------- */
/* All of the F-Curve Modifier api functions use FModifierTypeInfo structs to carry out
- * and operations that involve F-Curve modifier specifc code.
+ * and operations that involve F-Curve modifier specific code.
*/
/* These globals only ever get directly accessed in this file */
@@ -1499,7 +1756,8 @@ static FModifierTypeInfo *fmodifiersTypeInfo[FMODIFIER_NUM_TYPES];
static short FMI_INIT= 1; /* when non-zero, the list needs to be updated */
/* This function only gets called when FMI_INIT is non-zero */
-static void fmods_init_typeinfo () {
+static void fmods_init_typeinfo ()
+{
fmodifiersTypeInfo[0]= NULL; /* 'Null' F-Curve Modifier */
fmodifiersTypeInfo[1]= &FMI_GENERATOR; /* Generator F-Curve Modifier */
fmodifiersTypeInfo[2]= &FMI_ENVELOPE; /* Envelope F-Curve Modifier */
@@ -1568,10 +1826,12 @@ FModifier *fcurve_add_modifier (FCurve *fcu, int type)
/* add modifier itself */
fcm= MEM_callocN(sizeof(FModifier), "F-Curve Modifier");
+ fcm->type = type;
+ fcm->flag = FMODIFIER_FLAG_EXPANDED;
BLI_addtail(&fcu->modifiers, fcm);
/* add modifier's data */
- fcm->data= MEM_callocN(fmi->size, "F-Curve Modifier Data");
+ fcm->data= MEM_callocN(fmi->size, fmi->structName);
/* init custom settings if necessary */
if (fmi->new_data)
@@ -1614,11 +1874,13 @@ void fcurve_remove_modifier (FCurve *fcu, FModifier *fcm)
return;
/* free modifier's special data (stored inside fcm->data) */
- if (fmi && fmi->free_data)
- fmi->free_data(fcm);
-
- /* free modifier's data (fcm->data) */
- MEM_freeN(fcm->data);
+ if (fcm->data) {
+ if (fmi && fmi->free_data)
+ fmi->free_data(fcm);
+
+ /* free modifier's data (fcm->data) */
+ MEM_freeN(fcm->data);
+ }
/* remove modifier from stack */
if (fcu)
@@ -1674,12 +1936,48 @@ void fcurve_bake_modifiers (FCurve *fcu, int start, int end)
fcu->driver= driver;
}
+/* Find the active F-Curve Modifier */
+FModifier *fcurve_find_active_modifier (FCurve *fcu)
+{
+ FModifier *fcm;
+
+ /* sanity checks */
+ if ELEM(NULL, fcu, fcu->modifiers.first)
+ return NULL;
+
+ /* loop over modifiers until 'active' one is found */
+ for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
+ if (fcm->flag & FMODIFIER_FLAG_ACTIVE)
+ return fcm;
+ }
+
+ /* no modifier is active */
+ return NULL;
+}
+
+/* Set the active F-Curve Modifier */
+void fcurve_set_active_modifier (FCurve *fcu, FModifier *fcm)
+{
+ FModifier *fm;
+
+ /* sanity checks */
+ if ELEM(NULL, fcu, fcu->modifiers.first)
+ return;
+
+ /* deactivate all, and set current one active */
+ for (fm= fcu->modifiers.first; fm; fm= fm->next)
+ fm->flag &= ~FMODIFIER_FLAG_ACTIVE;
+
+ /* make given modifier active */
+ if (fcm)
+ fcm->flag |= FMODIFIER_FLAG_ACTIVE;
+}
+
/* ***************************** F-Curve - Evaluation ********************************* */
/* Evaluate and return the value of the given F-Curve at the specified frame ("evaltime")
* Note: this is also used for drivers
*/
-// TODO: set up the modifier system...
float evaluate_fcurve (FCurve *fcu, float evaltime)
{
FModifier *fcm;
@@ -1711,6 +2009,12 @@ float evaluate_fcurve (FCurve *fcu, float evaltime)
}
}
+ /* if curve can only have integral values, perform truncation (i.e. drop the decimal part)
+ * here so that the curve can be sampled correctly
+ */
+ if (fcu->flag & FCURVE_INT_VALUES)
+ cvalue= (float)((int)cvalue);
+
/* return evaluated value */
return cvalue;
}
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index dbb720fb0bc..b9417ccb467 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -1730,53 +1730,5 @@ void do_versions_ipos_to_animato(Main *main)
/* free unused drivers from actions + ipos */
free_fcurves(&drivers);
- printf("INFO: animato convert done \n"); // xxx debug
+ printf("INFO: Animato convert done \n"); // xxx debug
}
-
-
-
-#if 0 // XXX old animation system
-
-/* ***************************** IPO - DataAPI ********************************* */
-
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!! FIXME - BAD CRUFT WARNING !!!!!!!!!!!!!!!!!!!!!!!
-
-/* These functions here should be replaced eventually by the Data API, as this is
- * inflexible duplication...
- */
-
-/* --------------------- Get Pointer API ----------------------------- */
-
-
-/* GS reads the memory pointed at in a specific ordering. There are,
- * however two definitions for it. I have jotted them down here, both,
- * but I think the first one is actually used. The thing is that
- * big-endian systems might read this the wrong way round. OTOH, we
- * constructed the IDs that are read out with this macro explicitly as
- * well. I expect we'll sort it out soon... */
-
-/* from blendef: */
-#define GS(a) (*((short *)(a)))
-
-/* from misc_util: flip the bytes from x */
-/* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
-
-
-/* general function to get pointer to source/destination data */
-void *get_ipo_poin (ID *id, IpoCurve *icu, int *type)
-{
- void *poin= NULL;
- MTex *mtex= NULL;
-
- /* most channels will have float data, but those with other types will override this */
- *type= IPO_FLOAT;
-
- /* data is divided into 'blocktypes' based on ID-codes */
- // all adr codes put into converters!
-
- /* return pointer */
- return poin;
-}
-
-
-#endif // XXX old animation system
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 62c9699aaf9..1239bc80875 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);
@@ -7550,6 +7541,7 @@ static void meshdeformModifier_do(
DerivedMesh *tmpdm, *cagedm;
MDeformVert *dvert = NULL;
MDeformWeight *dw;
+ EditMesh *em = EM_GetEditMesh(me);
MVert *cagemvert;
float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
float weight, totweight, fac, co[3], *weights, (*dco)[3], (*bindcos)[3];
@@ -7559,10 +7551,11 @@ static void meshdeformModifier_do(
return;
/* get cage derivedmesh */
- if(me->edit_mesh) {
- tmpdm= editmesh_get_derived_cage_and_final(md->scene, ob, me->edit_mesh, &cagedm, 0);
+ if(em) {
+ tmpdm= editmesh_get_derived_cage_and_final(md->scene, ob, em, &cagedm, 0);
if(tmpdm)
tmpdm->release(tmpdm);
+ EM_EndEditMesh(em);
}
else
cagedm= mmd->object->derivedFinal;
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..7b59a1e6d9c 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -58,7 +58,7 @@
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h"
-#include "DNA_oops_types.h"
+#include "DNA_outliner_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -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;
}
@@ -553,15 +554,9 @@ void unlink_object(Scene *scene, Object *ob)
// XXX if(v3d->localvd->persp==V3D_CAMOB) v3d->localvd->persp= V3D_PERSP;
}
}
- else if(sl->spacetype==SPACE_OOPS) {
+ else if(sl->spacetype==SPACE_OUTLINER) {
SpaceOops *so= (SpaceOops *)sl;
- Oops *oops;
- oops= so->oops.first;
- while(oops) {
- if(oops->id==(ID *)ob) oops->id= NULL;
- oops= oops->next;
- }
if(so->treestore) {
TreeStoreElem *tselem= so->treestore->data;
int a;
@@ -569,7 +564,6 @@ void unlink_object(Scene *scene, Object *ob)
if(tselem->id==(ID *)ob) tselem->id= NULL;
}
}
- so->lockpoin= NULL;
}
}
@@ -1641,15 +1635,16 @@ static void ob_parbone(Object *ob, Object *par, float mat[][4])
static void give_parvert(Object *par, int nr, float *vec)
{
+ EditMesh *em;
int a, count;
vec[0]=vec[1]=vec[2]= 0.0f;
if(par->type==OB_MESH) {
Mesh *me= par->data;
-
- if(me->edit_mesh) {
- EditMesh *em = me->edit_mesh;
+ em = EM_GetEditMesh(me);
+
+ if(em) {
EditVert *eve;
for(eve= em->verts.first; eve; eve= eve->next) {
@@ -1658,6 +1653,7 @@ static void give_parvert(Object *par, int nr, float *vec)
break;
}
}
+ EM_EndEditMesh(me, em);
}
else {
DerivedMesh *dm = par->derivedFinal;
@@ -2300,10 +2296,13 @@ void object_handle_update(Scene *scene, Object *ob)
/* includes all keys and modifiers */
if(ob->type==OB_MESH) {
+ EditMesh *em = EM_GetEditMesh(ob->data);
+
// here was vieweditdatamask? XXX
- if(ob==scene->obedit)
- makeDerivedMesh(scene, ob, ((Mesh*)ob->data)->edit_mesh, CD_MASK_BAREMESH);
- else
+ if(ob==scene->obedit) {
+ makeDerivedMesh(scene, ob, em, CD_MASK_BAREMESH);
+ EM_EndEditMesh(ob->data, em);
+ } else
makeDerivedMesh(scene, ob, NULL, CD_MASK_BAREMESH);
}
else if(ob->type==OB_MBALL) {
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index afb4fb68c8c..928730fb1f0 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1575,7 +1575,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
}
#endif // XXX old animation system
- /* need to get every rand even if we don't use them so that randoms don't affect eachother */
+ /* need to get every rand even if we don't use them so that randoms don't affect each other */
rand= BLI_frand();
if(part->randlife!=0.0)
pa->lifetime*= 1.0f - part->randlife*rand;
@@ -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/scene.c b/source/blender/blenkernel/intern/scene.c
index 7db96c07592..22f26741c55 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -287,6 +287,8 @@ Scene *add_scene(char *name)
sce->toolsettings->skgen_subdivisions[1] = SKGEN_SUB_LENGTH;
sce->toolsettings->skgen_subdivisions[2] = SKGEN_SUB_ANGLE;
+ sce->toolsettings->proportional_size = 1.0f;
+
pset= &sce->toolsettings->particle;
pset->flag= PE_KEEP_LENGTHS|PE_LOCK_FIRST|PE_DEFLECT_EMITTER;
pset->emitterdist= 0.25f;
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 063c617e6bb..483876e5e05 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -54,8 +54,11 @@ static void spacetype_free(SpaceType *st)
{
ARegionType *art;
- for(art= st->regiontypes.first; art; art= art->next)
+ for(art= st->regiontypes.first; art; art= art->next) {
BLI_freelistN(&art->drawcalls);
+ BLI_freelistN(&art->paneltypes);
+ BLI_freelistN(&art->headertypes);
+ }
BLI_freelistN(&st->regiontypes);
}
@@ -199,7 +202,7 @@ void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2)
{
SpaceLink *sl;
- lb1->first= lb2->last= NULL; /* to be sure */
+ lb1->first= lb1->last= NULL; /* to be sure */
for (sl= lb2->first; sl; sl= sl->next) {
SpaceType *st= BKE_spacetype_from_id(sl->spacetype);
@@ -214,6 +217,27 @@ void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2)
}
}
+/* lb1 should be empty */
+void BKE_spacedata_copyfirst(ListBase *lb1, ListBase *lb2)
+{
+ SpaceLink *sl;
+
+ lb1->first= lb1->last= NULL; /* to be sure */
+
+ sl= lb2->first;
+ if(sl) {
+ SpaceType *st= BKE_spacetype_from_id(sl->spacetype);
+
+ if(st && st->duplicate) {
+ SpaceLink *slnew= st->duplicate(sl);
+
+ BLI_addtail(lb1, slnew);
+
+ region_copylist(st, &slnew->regionbase, &sl->regionbase);
+ }
+ }
+}
+
/* not region itself */
void BKE_area_region_free(SpaceType *st, ARegion *ar)
{
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 11f8dfdf330..2ee95ed928e 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;
@@ -1038,8 +1038,8 @@ static void do_gammacross_effect(Sequence * seq,int cfra,
} else {
do_gammacross_effect_byte(
facf0, facf1, x, y,
- (char*) ibuf1->rect, (char*) ibuf2->rect,
- (char*) out->rect);
+ (unsigned char*) ibuf1->rect, (unsigned char*) ibuf2->rect,
+ (unsigned char*) out->rect);
}
}
@@ -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;
+ // XXX struct RenderData *rd = NULL; // 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/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index f2197c932c9..417d9311563 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -52,10 +52,12 @@
#include "BLI_arithb.h"
#include "BLI_kdtree.h"
#include "BLI_kdopbvh.h"
+#include "BLI_editVert.h"
#include "RE_raytrace.h"
#include "MEM_guardedalloc.h"
+#include "ED_mesh.h"
/* Util macros */
#define TO_STR(a) #a
@@ -94,11 +96,14 @@ typedef void ( *Shrinkwrap_ForeachVertexCallback) (DerivedMesh *target, float *c
static DerivedMesh *object_get_derived_final(struct Scene *scene, Object *ob, CustomDataMask dataMask)
{
Mesh *me= ob->data;
-
- if (me->edit_mesh)
+ EditMesh *em = EM_GetEditMesh(me);
+
+ if (em)
{
DerivedMesh *final = NULL;
- editmesh_get_derived_cage_and_final(scene, ob, me->edit_mesh, &final, dataMask);
+ editmesh_get_derived_cage_and_final(scene, ob, em, &final, dataMask);
+
+ EM_EndEditMesh(me, em);
return final;
}
else
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 1f4f6d2e920..71307132243 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -395,8 +395,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/BLI_string.h b/source/blender/blenlib/BLI_string.h
index d9d030432d3..22b41d0055b 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -73,6 +73,12 @@ char *BLI_strncpy(char *dst, const char *src, int maxncpy);
*/
int BLI_snprintf(char *buffer, size_t count, const char *format, ...);
+ /*
+ * Print formatted string into a newly mallocN'd string
+ * and return it.
+ */
+char *BLI_sprintfN(const char *format, ...);
+
/**
* Compare two strings
*
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index a633b5811ff..f1c756bcce3 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -3945,6 +3945,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)
@@ -4294,6 +4345,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/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 8ba03ad1343..9204ab18bfa 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -152,7 +152,8 @@ int BLI_compare(struct direntry *entry1, struct direntry *entry2)
if( strcmp(entry1->relname, ".")==0 ) return (-1);
if( strcmp(entry2->relname, ".")==0 ) return (1);
if( strcmp(entry1->relname, "..")==0 ) return (-1);
-
+ if( strcmp(entry2->relname, "..")==0 ) return (1);
+
return (BLI_strcasecmp(entry1->relname,entry2->relname));
}
@@ -333,7 +334,6 @@ void BLI_adddirstrings()
char size[250];
static char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
int num, mode;
- off_t num1, num2, num3, num4, num5;
#ifdef WIN32
__int64 st_size;
#else
@@ -400,24 +400,19 @@ void BLI_adddirstrings()
* everyone starts using __USE_FILE_OFFSET64 or equivalent.
*/
st_size= (off_t)files[num].s.st_size;
-
- num1= st_size % 1000;
- num2= st_size/1000;
- num2= num2 % 1000;
- num3= st_size/(1000*1000);
- num3= num3 % 1000;
- num4= st_size/(1000*1000*1000);
- num4= num4 % 1000;
- num5= st_size/(1000000000000LL);
- num5= num5 % 1000;
-
- if(num5)
- sprintf(files[num].size, "%1d %03d %03d %03d K", (int)num5, (int)num4, (int)num3, (int)num2);
- else if(num4) sprintf(files[num].size, "%3d %03d %03d %03d", (int)num4, (int)num3, (int)num2, (int)num1);
- else if(num3) sprintf(files[num].size, "%7d %03d %03d", (int)num3, (int)num2, (int)num1);
- else if(num2) sprintf(files[num].size, "%11d %03d", (int)num2, (int)num1);
- else if(num1) sprintf(files[num].size, "%15d", (int)num1);
- else sprintf(files[num].size, "0");
+
+ if (st_size > 1024*1024*1024) {
+ sprintf(files[num].size, "%.2f GB", ((double)st_size)/(1024*1024*1024));
+ }
+ else if (st_size > 1024*1024) {
+ sprintf(files[num].size, "%.1f MB", ((double)st_size)/(1024*1024));
+ }
+ else if (st_size > 1024) {
+ sprintf(files[num].size, "%d KB", (int)(st_size/1024));
+ }
+ else {
+ sprintf(files[num].size, "%d B", (int)st_size);
+ }
strftime(datum, 32, "%d-%b-%y %H:%M", tm);
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index e0522e60dd0..8485a0c975b 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -40,6 +40,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_dynstr.h"
#include "BLI_string.h"
char *BLI_strdupn(const char *str, int len) {
@@ -81,6 +82,24 @@ int BLI_snprintf(char *buffer, size_t count, const char *format, ...)
return n;
}
+char *BLI_sprintfN(const char *format, ...)
+{
+ DynStr *ds;
+ va_list arg;
+ char *n;
+
+ va_start(arg, format);
+
+ ds= BLI_dynstr_new();
+ BLI_dynstr_vappendf(ds, format, arg);
+ n= BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+
+ va_end(arg);
+
+ return n;
+}
+
int BLI_streq(char *a, char *b) {
return (strcmp(a, b)==0);
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 338dc810641..b0b3e9daf2b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -81,7 +81,7 @@
#include "DNA_object_types.h"
#include "DNA_object_force.h"
#include "DNA_object_fluidsim.h" // NT
-#include "DNA_oops_types.h"
+#include "DNA_outliner_types.h"
#include "DNA_object_force.h"
#include "DNA_packedFile_types.h"
#include "DNA_particle_types.h"
@@ -1725,7 +1725,14 @@ static void direct_link_fcurves(FileData *fd, ListBase *list)
{
FMod_Generator *data= (FMod_Generator *)fcm->data;
- data->poly_coefficients= newdataadr(fd, data->poly_coefficients);
+ data->coefficients= newdataadr(fd, data->coefficients);
+ }
+ break;
+ case FMODIFIER_TYPE_ENVELOPE:
+ {
+ FMod_Envelope *data= (FMod_Envelope *)fcm->data;
+
+ data->data= newdataadr(fd, data->data);
}
break;
case FMODIFIER_TYPE_PYTHON:
@@ -3758,6 +3765,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;
@@ -4196,18 +4205,11 @@ static void lib_link_screen(FileData *fd, Main *main)
}
}
}
- else if(sl->spacetype==SPACE_OOPS) {
+ else if(sl->spacetype==SPACE_OUTLINER) {
SpaceOops *so= (SpaceOops *)sl;
- Oops *oops;
TreeStoreElem *tselem;
int a;
- oops= so->oops.first;
- while(oops) {
- oops->id= newlibadr(fd, NULL, oops->id);
- oops= oops->next;
- }
- so->lockpoin= NULL;
so->tree.first= so->tree.last= NULL;
so->search_tse.id= newlibadr(fd, NULL, so->search_tse.id);
@@ -4329,7 +4331,7 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
v3d->bgpic->ima= restore_pointer_by_name(newmain, (ID *)v3d->bgpic->ima, 1);
}
if(v3d->localvd) {
- Base *base;
+ /*Base *base;*/
v3d->localvd->camera= sc->scene->camera;
@@ -4405,17 +4407,10 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene)
SCRIPT_SET_NULL(scpt->script)
}
}
- else if(sl->spacetype==SPACE_OOPS) {
+ else if(sl->spacetype==SPACE_OUTLINER) {
SpaceOops *so= (SpaceOops *)sl;
- Oops *oops;
int a;
- oops= so->oops.first;
- while(oops) {
- oops->id= restore_pointer_by_name(newmain, (ID *)oops->id, 0);
- oops= oops->next;
- }
- so->lockpoin= NULL;
so->search_tse.id= restore_pointer_by_name(newmain, so->search_tse.id, 0);
if(so->treestore) {
@@ -4520,7 +4515,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
ScrArea *sa;
ScrVert *sv;
ScrEdge *se;
- Oops *oops;
int a;
link_list(fd, &(sc->vertbase));
@@ -4608,16 +4602,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sipo->ads= newdataadr(fd, sipo->ads);
}
- else if (sl->spacetype==SPACE_OOPS) {
+ else if (sl->spacetype==SPACE_OUTLINER) {
SpaceOops *soops= (SpaceOops*) sl;
- link_list(fd, &(soops->oops));
- oops= soops->oops.first;
- while(oops) {
- oops->link.first= oops->link.last= 0;
- oops= oops->next;
- }
-
soops->treestore= newdataadr(fd, soops->treestore);
if(soops->treestore) {
soops->treestore->data= newdataadr(fd, soops->treestore->data);
@@ -5516,7 +5503,7 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
view3d_split_250((View3D *)sl, lb);
break;
- case SPACE_OOPS:
+ case SPACE_OUTLINER:
{
SpaceOops *soops= (SpaceOops *)sl;
@@ -5529,8 +5516,6 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb)
ar->v2d.keeptot = V2D_KEEPTOT_STRICT;
ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
//ar->v2d.flag |= V2D_IS_INITIALISED;
-
- soops->type= SO_OUTLINER;
}
break;
case SPACE_TIME:
@@ -5960,10 +5945,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
while(sl) {
if(sl->spacetype==SPACE_TEXT) {
SpaceText *st= (SpaceText*) sl;
- if(st->font_id>1) {
- st->font_id= 0;
- st->lheight= 13;
- }
+ st->lheight= 12;
}
sl= sl->next;
}
@@ -7019,12 +7001,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
View3D *v3d= (View3D *)sl;
if(v3d->twtype==0) v3d->twtype= V3D_MANIP_TRANSLATE;
}
-#ifndef SHOWDEPGRAPH
- else if(sl->spacetype==SPACE_OOPS) {
- if ( ((SpaceOops *)sl)->type==SO_DEPSGRAPH)
- ((SpaceOops *)sl)->type=SO_OOPS;
- }
-#endif
else if(sl->spacetype==SPACE_TIME) {
SpaceTime *stime= (SpaceTime *)sl;
if(stime->redraws==0)
@@ -8095,28 +8071,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
@@ -8717,6 +8671,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)) {
@@ -9737,6 +9716,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 45742b8f020..1c9c5cad19f 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -121,7 +121,7 @@ Any case: direct data is ALWAYS after the lib block
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
-#include "DNA_oops_types.h"
+#include "DNA_outliner_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_particle_types.h"
#include "DNA_property_types.h"
@@ -805,9 +805,18 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
{
FMod_Generator *data= (FMod_Generator *)fcm->data;
- /* write polynomial coefficients array */
- if (data->poly_coefficients)
- writedata(wd, DATA, sizeof(float)*(data->poly_order+1), data->poly_coefficients);
+ /* write coefficients array */
+ if (data->coefficients)
+ writedata(wd, DATA, sizeof(float)*(data->arraysize), data->coefficients);
+ }
+ break;
+ case FMODIFIER_TYPE_ENVELOPE:
+ {
+ FMod_Envelope *data= (FMod_Envelope *)fcm->data;
+
+ /* write envelope data */
+ if (data->data)
+ writedata(wd, DATA, sizeof(FCM_EnvelopeData)*(data->totvert), data->data);
}
break;
case FMODIFIER_TYPE_PYTHON:
@@ -822,7 +831,7 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
}
}
- /* Write the constraint */
+ /* Write the modifier */
writestruct(wd, DATA, "FModifier", 1, fcm);
}
}
@@ -1811,29 +1820,11 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
writestruct(wd, DATA, "SpaceSeq", 1, sl);
if(sseq->gpd) write_gpencil(wd, sseq->gpd);
}
- else if(sl->spacetype==SPACE_OOPS) {
+ else if(sl->spacetype==SPACE_OUTLINER) {
SpaceOops *so= (SpaceOops *)sl;
- Oops *oops;
- /* cleanup */
- oops= so->oops.first;
- while(oops) {
- Oops *oopsn= oops->next;
- if(oops->id==0) {
- BLI_remlink(&so->oops, oops);
-// XXX free_oops(oops);
- }
- oops= oopsn;
- }
-
- /* ater cleanup, because of listbase! */
writestruct(wd, DATA, "SpaceOops", 1, so);
-
- oops= so->oops.first;
- while(oops) {
- writestruct(wd, DATA, "Oops", 1, oops);
- oops= oops->next;
- }
+
/* outliner */
if(so->treestore) {
writestruct(wd, DATA, "TreeStore", 1, so->treestore);
@@ -2152,7 +2143,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/animation/anim_channels.c b/source/blender/editors/animation/anim_channels.c
index 8dfb1c20bbe..ff9876bf715 100644
--- a/source/blender/editors/animation/anim_channels.c
+++ b/source/blender/editors/animation/anim_channels.c
@@ -804,11 +804,11 @@ static int animchannels_setflag_exec(bContext *C, wmOperator *op)
}
-void ANIM_OT_channels_enable_setting (wmOperatorType *ot)
+void ANIM_OT_channels_setting_enable (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Enable Channel Setting";
- ot->idname= "ANIM_OT_channels_enable_setting";
+ ot->idname= "ANIM_OT_channels_setting_enable";
/* api callbacks */
ot->invoke= WM_menu_invoke;
@@ -825,11 +825,11 @@ void ANIM_OT_channels_enable_setting (wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
-void ANIM_OT_channels_disable_setting (wmOperatorType *ot)
+void ANIM_OT_channels_setting_disable (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Disable Channel Setting";
- ot->idname= "ANIM_OT_channels_disable_setting";
+ ot->idname= "ANIM_OT_channels_setting_disable";
/* api callbacks */
ot->invoke= WM_menu_invoke;
@@ -846,11 +846,11 @@ void ANIM_OT_channels_disable_setting (wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
-void ANIM_OT_channels_toggle_setting (wmOperatorType *ot)
+void ANIM_OT_channels_setting_toggle (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Toggle Channel Setting";
- ot->idname= "ANIM_OT_channels_toggle_setting";
+ ot->idname= "ANIM_OT_channels_setting_toggle";
/* api callbacks */
ot->invoke= WM_menu_invoke;
@@ -868,11 +868,11 @@ void ANIM_OT_channels_toggle_setting (wmOperatorType *ot)
}
// XXX currently, this is a separate operator, but perhaps we could in future specify in keymaps whether to call invoke or exec?
-void ANIM_OT_channels_toggle_editable (wmOperatorType *ot)
+void ANIM_OT_channels_editable_toggle (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Toggle Channel Editability";
- ot->idname= "ANIM_OT_channels_toggle_editable";
+ ot->idname= "ANIM_OT_channels_editable_toggle";
/* api callbacks */
ot->exec= animchannels_setflag_exec;
@@ -910,11 +910,11 @@ static int animchannels_deselectall_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ANIM_OT_channels_deselectall (wmOperatorType *ot)
+void ANIM_OT_channels_select_all_toggle (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select All";
- ot->idname= "ANIM_OT_channels_deselectall";
+ ot->idname= "ANIM_OT_channels_select_all_toggle";
/* api callbacks */
ot->exec= animchannels_deselectall_exec;
@@ -1028,11 +1028,11 @@ static int animchannels_borderselect_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ANIM_OT_channels_borderselect(wmOperatorType *ot)
+void ANIM_OT_channels_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Border Select";
- ot->idname= "ANIM_OT_channels_borderselect";
+ ot->idname= "ANIM_OT_channels_select_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
@@ -1365,9 +1365,9 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, wmEvent *
mval[1]= (event->y - ar->winrct.ymin);
/* select mode is either replace (deselect all, then add) or add/extend */
- if (RNA_boolean_get(op->ptr, "extend_select"))
+ if (RNA_boolean_get(op->ptr, "extend"))
selectmode= SELECT_INVERT;
- else if (RNA_boolean_get(op->ptr, "select_children_only"))
+ else if (RNA_boolean_get(op->ptr, "children_only"))
selectmode= -1; /* this is a bit of a special case for ActionGroups only... should it be removed or extended to all instead? */
else
selectmode= SELECT_REPLACE;
@@ -1403,8 +1403,8 @@ void ANIM_OT_channels_mouseclick (wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* id-props */
- RNA_def_boolean(ot->srna, "extend_select", 0, "Extend Select", ""); // SHIFTKEY
- RNA_def_boolean(ot->srna, "select_children_only", 0, "Select Children Only", ""); // CTRLKEY|SHIFTKEY
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
+ RNA_def_boolean(ot->srna, "children_only", 0, "Select Children Only", ""); // CTRLKEY|SHIFTKEY
}
/* ************************************************************************** */
@@ -1412,16 +1412,16 @@ void ANIM_OT_channels_mouseclick (wmOperatorType *ot)
void ED_operatortypes_animchannels(void)
{
- WM_operatortype_append(ANIM_OT_channels_deselectall);
- WM_operatortype_append(ANIM_OT_channels_borderselect);
+ WM_operatortype_append(ANIM_OT_channels_select_all_toggle);
+ WM_operatortype_append(ANIM_OT_channels_select_border);
WM_operatortype_append(ANIM_OT_channels_mouseclick);
- WM_operatortype_append(ANIM_OT_channels_enable_setting);
- WM_operatortype_append(ANIM_OT_channels_disable_setting);
- WM_operatortype_append(ANIM_OT_channels_toggle_setting);
+ WM_operatortype_append(ANIM_OT_channels_setting_enable);
+ WM_operatortype_append(ANIM_OT_channels_setting_disable);
+ WM_operatortype_append(ANIM_OT_channels_setting_toggle);
// XXX does this need to be a separate operator?
- WM_operatortype_append(ANIM_OT_channels_toggle_editable);
+ WM_operatortype_append(ANIM_OT_channels_editable_toggle);
// XXX these need to be updated for new system... todo...
//WM_operatortype_append(ANIM_OT_channels_move_up);
@@ -1440,23 +1440,23 @@ void ED_keymap_animchannels(wmWindowManager *wm)
/* click-select */
// XXX for now, only leftmouse....
WM_keymap_add_item(keymap, "ANIM_OT_channels_mouseclick", LEFTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_mouseclick", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend_select", 1);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_mouseclick", LEFTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "select_children_only", 1);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_mouseclick", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_mouseclick", LEFTMOUSE, KM_PRESS, KM_CTRL|KM_SHIFT, 0)->ptr, "children_only", 1);
/* deselect all */
- WM_keymap_add_item(keymap, "ANIM_OT_channels_deselectall", AKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_deselectall", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
+ WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", AKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ANIM_OT_channels_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
/* borderselect */
- WM_keymap_add_item(keymap, "ANIM_OT_channels_borderselect", BKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ANIM_OT_channels_select_border", BKEY, KM_PRESS, 0, 0);
/* settings */
- WM_keymap_add_item(keymap, "ANIM_OT_channels_toggle_setting", WKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "ANIM_OT_channels_enable_setting", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "ANIM_OT_channels_disable_setting", WKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_toggle", WKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_enable", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "ANIM_OT_channels_setting_disable", WKEY, KM_PRESS, KM_ALT, 0);
/* settings - specialised hotkeys */
- WM_keymap_add_item(keymap, "ANIM_OT_channels_toggle_editable", TABKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ANIM_OT_channels_editable_toggle", TABKEY, KM_PRESS, 0, 0);
/* rearranging - actions only */
//WM_keymap_add_item(keymap, "ANIM_OT_channels_move_up", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 689520eb0fa..ea30fe83f35 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -310,6 +310,12 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
/* quick macro to test if AnimData is usable for drivers */
#define ANIMDATA_HAS_DRIVERS(id) ((id)->adt && (id)->adt->drivers.first)
+/* quick macro to test if a anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */
+#define ANIMCHANNEL_SELOK(test_func) \
+ ( !(filter_mode & (ANIMFILTER_SEL|ANIMFILTER_UNSEL)) || \
+ ((filter_mode & ANIMFILTER_SEL) && test_func) || \
+ ((filter_mode & ANIMFILTER_UNSEL) && test_func==0) )
+
/* ----------- 'Private' Stuff --------------- */
/* this function allocates memory for a new bAnimListElem struct for the
@@ -509,8 +515,8 @@ static int animdata_filter_fcurves (ListBase *anim_data, FCurve *first, bActionG
if (!(filter_mode & ANIMFILTER_CURVEVISIBLE) || (fcu->flag & FCURVE_VISIBLE)) {
/* only work with this channel and its subchannels if it is editable */
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_FCU(fcu)) {
- /* only include this curve if selected */
- if (!(filter_mode & ANIMFILTER_SEL) || (SEL_FCU(fcu))) {
+ /* only include this curve if selected in a way consistent with the filtering requirements */
+ if ( ANIMCHANNEL_SELOK(SEL_FCU(fcu)) ) {
/* only include if this curve is active */
if (!(filter_mode & ANIMFILTER_ACTIVE) || (fcu->flag & FCURVE_ACTIVE)) {
/* owner/ownertype will be either object or action-channel, depending if it was dopesheet or part of an action */
@@ -543,7 +549,7 @@ static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter
/* add this group as a channel first */
if ((filter_mode & ANIMFILTER_CHANNELS) || !(filter_mode & ANIMFILTER_CURVESONLY)) {
/* check if filtering by selection */
- if ( !(filter_mode & ANIMFILTER_SEL) || SEL_AGRP(agrp) ) {
+ if ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) {
ale= make_new_animlistelem(agrp, ANIMTYPE_GROUP, NULL, ANIMTYPE_NONE, owner_id);
if (ale) {
BLI_addtail(anim_data, ale);
@@ -569,8 +575,7 @@ static int animdata_filter_action (ListBase *anim_data, bAction *act, int filter
* - we're interested in keyframes, but not if they appear in selected channels
*/
if ( (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_AGRP(agrp)) ||
- ( (!(filter_mode & ANIMFILTER_SEL) || (SEL_AGRP(agrp))) &&
- (filter_mode & ANIMFILTER_CURVESONLY) ) )
+ ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) && (filter_mode & ANIMFILTER_CURVESONLY) ) )
{
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
// XXX the 'owner' info here needs review...
@@ -709,7 +714,7 @@ static int animdata_filter_gpencil (ListBase *anim_data, bScreen *sc, int filter
/* loop over layers as the conditions are acceptable */
for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
/* only if selected */
- if (!(filter_mode & ANIMFILTER_SEL) || SEL_GPL(gpl)) {
+ if ( ANIMCHANNEL_SELOK(SEL_GPL(gpl)) ) {
/* only if editable */
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
/* add to list */
@@ -784,7 +789,6 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
/* add material's F-Curve channels? */
if (FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- //items += animdata_filter_ipocurves(anim_data, ma->ipo, filter_mode, base, ANIMTYPE_OBJECT, (ID *)ma);
// XXX the 'owner' info here is still subject to improvement
items += animdata_filter_action(anim_data, ma->adt->action, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);
}
@@ -873,7 +877,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
/* add this object as a channel first */
if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
/* check if filtering by selection */
- if ( !(filter_mode & ANIMFILTER_SEL) || ((base->flag & SELECT) || (base == sce->basact)) ) {
+ if (ANIMCHANNEL_SELOK( ((base->flag & SELECT) || (base == sce->basact)) )) {
ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, NULL);
if (ale) {
BLI_addtail(anim_data, ale);
@@ -1041,7 +1045,7 @@ static int animdata_filter_dopesheet_scene (ListBase *anim_data, bDopeSheet *ads
/* add scene as a channel first (even if we aren't showing scenes we still need to show the scene's sub-data */
if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
/* check if filtering by selection */
- if ( !(filter_mode & ANIMFILTER_SEL) || (sce->flag & SCE_DS_SELECTED) ) {
+ if (ANIMCHANNEL_SELOK( (sce->flag & SCE_DS_SELECTED) )) {
ale= make_new_animlistelem(sce, ANIMTYPE_SCENE, NULL, ANIMTYPE_NONE, NULL);
if (ale) {
BLI_addtail(anim_data, ale);
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 7817afc929c..fc52d9c4511 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -629,21 +629,17 @@ static int ed_marker_select(bContext *C, wmEvent *evt, int extend)
return OPERATOR_PASS_THROUGH;
}
-static int ed_marker_select_extend_invoke(bContext *C, wmOperator *op, wmEvent *evt)
-{
- return ed_marker_select(C, evt, 1);
-}
-
static int ed_marker_select_invoke(bContext *C, wmOperator *op, wmEvent *evt)
{
- return ed_marker_select(C, evt, 0);
+ short extend= RNA_boolean_get(op->ptr, "extend");
+ return ed_marker_select(C, evt, extend);
}
-static void MARKER_OT_mouseselect(wmOperatorType *ot)
+static void MARKER_OT_select(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select Time Marker";
- ot->idname= "MARKER_OT_mouseselect";
+ ot->idname= "MARKER_OT_select";
/* api callbacks */
ot->invoke= ed_marker_select_invoke;
@@ -651,20 +647,8 @@ static void MARKER_OT_mouseselect(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-static void MARKER_OT_mouseselect_extend(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Extend Select Time Marker";
- ot->idname= "MARKER_OT_mouseselect_extend";
-
- /* api callbacks */
- ot->invoke= ed_marker_select_extend_invoke;
- ot->poll= ED_operator_areaactive;
-
- /* flags */
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend", "extend the selection");
}
/* *************************** border select markers **************** */
@@ -731,11 +715,11 @@ static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
return 1;
}
-static void MARKER_OT_border_select(wmOperatorType *ot)
+static void MARKER_OT_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Marker Border select";
- ot->idname= "MARKER_OT_border_select";
+ ot->idname= "MARKER_OT_select_border";
/* api callbacks */
ot->exec= ed_marker_border_select_exec;
@@ -796,11 +780,11 @@ static int ed_marker_select_all_invoke(bContext *C, wmOperator *op, wmEvent *evt
return ed_marker_select_all_exec(C, op);
}
-static void MARKER_OT_select_all(wmOperatorType *ot)
+static void MARKER_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "(De)select all markers";
- ot->idname= "MARKER_OT_select_all";
+ ot->idname= "MARKER_OT_select_all_toggle";
/* api callbacks */
ot->exec= ed_marker_select_all_exec;
@@ -866,10 +850,9 @@ void ED_marker_operatortypes(void)
WM_operatortype_append(MARKER_OT_add);
WM_operatortype_append(MARKER_OT_move);
WM_operatortype_append(MARKER_OT_duplicate);
- WM_operatortype_append(MARKER_OT_mouseselect);
- WM_operatortype_append(MARKER_OT_mouseselect_extend);
- WM_operatortype_append(MARKER_OT_border_select);
- WM_operatortype_append(MARKER_OT_select_all);
+ WM_operatortype_append(MARKER_OT_select);
+ WM_operatortype_append(MARKER_OT_select_border);
+ WM_operatortype_append(MARKER_OT_select_all_toggle);
WM_operatortype_append(MARKER_OT_delete);
}
@@ -881,10 +864,10 @@ void ED_marker_keymap(wmWindowManager *wm)
WM_keymap_verify_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_move", EVT_TWEAK_S, KM_ANY, 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_verify_item(keymap, "MARKER_OT_mouseselect", SELECTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "MARKER_OT_mouseselect_extend", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_verify_item(keymap, "MARKER_OT_border_select", BKEY, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "MARKER_OT_select_all", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
+ WM_keymap_verify_item(keymap, "MARKER_OT_select_border", BKEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "MARKER_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "MARKER_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MARKER_OT_move", GKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index b51fa223eb3..f8c7cc909ae 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -243,11 +243,11 @@ static int previewrange_define_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ANIM_OT_previewrange_define(wmOperatorType *ot)
+void ANIM_OT_previewrange_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Preview Range";
- ot->idname= "ANIM_OT_previewrange_define";
+ ot->idname= "ANIM_OT_previewrange_set";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
@@ -374,7 +374,7 @@ void ED_operatortypes_anim(void)
WM_operatortype_append(ANIM_OT_change_frame);
WM_operatortype_append(ANIM_OT_time_toggle);
- WM_operatortype_append(ANIM_OT_previewrange_define);
+ WM_operatortype_append(ANIM_OT_previewrange_set);
WM_operatortype_append(ANIM_OT_previewrange_clear);
// XXX this is used all over... maybe for screen instead?
@@ -397,6 +397,6 @@ void ED_keymap_anim(wmWindowManager *wm)
WM_keymap_verify_item(keymap, "ANIM_OT_time_toggle", TKEY, KM_PRESS, KM_CTRL, 0);
/* preview range */
- WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_define", PKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_previewrange_clear", PKEY, KM_PRESS, KM_ALT, 0);
}
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 4b5ab6296b4..d67a40518e3 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -96,7 +96,7 @@
static void add_bezt_to_keycolumnslist(ListBase *keys, BezTriple *bezt)
{
- /* The equivilant of add_to_cfra_elem except this version
+ /* The equivalent of add_to_cfra_elem except this version
* makes ActKeyColumns - one of the two datatypes required
* for action editor drawing.
*/
@@ -136,7 +136,7 @@ static void add_bezt_to_keycolumnslist(ListBase *keys, BezTriple *bezt)
static void add_bezt_to_keyblockslist(ListBase *blocks, FCurve *fcu, int index)
{
- /* The equivilant of add_to_cfra_elem except this version
+ /* The equivalent of add_to_cfra_elem except this version
* makes ActKeyBlocks - one of the two datatypes required
* for action editor drawing.
*/
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index fc6ed9b00bb..48ca06fb73d 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -420,13 +420,20 @@ short copy_animedit_keys (bAnimContext *ac, ListBase *anim_data)
/* clear buffer first */
free_anim_copybuf();
- /* assume that each of these is an ipo-block */
+ /* assume that each of these is an F-Curve */
for (ale= anim_data->first; ale; ale= ale->next) {
FCurve *fcu= (FCurve *)ale->key_data;
tAnimCopybufItem *aci;
BezTriple *bezt, *newbuf;
int i;
+ /* firstly, check if F-Curve has any selected keyframes
+ * - skip if no selected keyframes found (so no need to create unnecessary copy-buffer data)
+ * - this check should also eliminate any problems associated with using sample-data
+ */
+ if (ANIM_fcurve_keys_bezier_loop(NULL, fcu, NULL, ANIM_editkeyframes_ok(BEZT_OK_SELECTED), NULL) == 0)
+ continue;
+
/* init copybuf item info */
aci= MEM_callocN(sizeof(tAnimCopybufItem), "AnimCopybufItem");
aci->id= ale->id;
@@ -436,7 +443,6 @@ short copy_animedit_keys (bAnimContext *ac, ListBase *anim_data)
BLI_addtail(&animcopybuf, aci);
/* add selected keyframes to buffer */
- // XXX we don't cope with sample-data yet
// TODO: currently, we resize array everytime we add a new vert - this works ok as long as it is assumed only a few keys are copied
for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
if (BEZSELECTED(bezt)) {
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index f490fb77438..b04eaa0c378 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -206,7 +206,7 @@ static int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen
*/
for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
/* compute and get midpoint */
- int mid = (start + end) / 2;
+ int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */
float midfra= array[mid].vec[1][0];
/* check if exactly equal to midpoint */
@@ -994,7 +994,7 @@ void ANIM_OT_keyingset_add_new (wmOperatorType *ot)
/* name */
RNA_def_string(ot->srna, "name", "KeyingSet", 64, "Name", "Name of Keying Set");
/* flags */
- RNA_def_boolean(ot->srna, "absolute", 1, "Absolute", "Keying Set defines specifc paths/settings to be keyframed (i.e. is not reliant on context info)");
+ RNA_def_boolean(ot->srna, "absolute", 1, "Absolute", "Keying Set defines specific paths/settings to be keyframed (i.e. is not reliant on context info)");
/* keying flags */
RNA_def_boolean(ot->srna, "insertkey_needed", 0, "Insert Keyframes - Only Needed", "Only insert keyframes where they're needed in the relevant F-Curves.");
RNA_def_boolean(ot->srna, "insertkey_visual", 0, "Insert Keyframes - Visual", "Insert keyframes based on 'visual transforms'.");
@@ -1046,7 +1046,7 @@ char *ANIM_build_keyingsets_menu (ListBase *list, short for_edit)
/* ******************************************* */
/* KEYFRAME MODIFICATION */
-/* mode for common_modifykey */
+/* mode for commonkey_modifykey */
enum {
COMMONKEY_MODE_INSERT = 0,
COMMONKEY_MODE_DELETE,
@@ -1623,34 +1623,6 @@ static void commonkey_context_getv3d (const bContext *C, ListBase *sources, bKey
/* set id-block to key to */
ob= base->object;
cks->id= (ID *)ob;
-
- /* when ob's keyframes are in an action, default to using 'Object' as achan name */
- if (ob->ipoflag & OB_ACTION_OB)
- cks->actname= "Object";
-
- /* set ipo-flags */
- // TODO: add checks for lib-linked data
- if ((ob->ipo) || (ob->action)) {
- if (ob->ipo) {
- cks->ipo= ob->ipo;
- }
- else {
- bActionChannel *achan;
-
- cks->act= ob->action;
- achan= get_action_channel(ob->action, cks->actname);
-
- if (achan && achan->ipo)
- cks->ipo= achan->ipo;
- }
- /* cks->ipo can be NULL while editing */
- if(cks->ipo) {
- /* deselect all ipo-curves */
- for (icu= cks->ipo->curve.first; icu; icu= icu->next) {
- icu->flag &= ~IPO_SELECT;
- }
- }
- }
}
CTX_DATA_END;
}
@@ -1799,6 +1771,23 @@ static void commonkey_context_getsbuts (const bContext *C, ListBase *sources, bK
#endif // XXX old keyingsets code based on adrcodes... to be restored in due course
+#if 0 // XXX new relative keyingsets code
+
+/* Check if context data is suitable for the given absolute Keying Set */
+static short keyingset_context_ok_poll (bContext *C, KeyingSet *ks)
+{
+
+ return 1;
+}
+
+/* Get list of data-sources from context for inserting keyframes using the given relative Keying Set */
+static short commonkey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks)
+{
+
+}
+
+#endif // XXX new relative keyingsets code
+
/* Given a KeyingSet and context info (if required), modify keyframes for the channels specified
* by the KeyingSet. This takes into account many of the different combinations of using KeyingSets.
* Returns the number of channels that keyframes were added to
@@ -1900,10 +1889,10 @@ static int modify_key_op_poll(bContext *C)
return 0;
/* if Outliner, only allow in DataBlocks view */
- if (sa->spacetype == SPACE_OOPS) {
+ if (sa->spacetype == SPACE_OUTLINER) {
SpaceOops *so= (SpaceOops *)CTX_wm_space_data(C);
- if ((so->type != SO_OUTLINER) || (so->outlinevis != SO_DATABLOCKS))
+ if ((so->outlinevis != SO_DATABLOCKS))
return 0;
}
diff --git a/source/blender/editors/armature/BIF_generate.h b/source/blender/editors/armature/BIF_generate.h
new file mode 100644
index 00000000000..bc655a4cdff
--- /dev/null
+++ b/source/blender/editors/armature/BIF_generate.h
@@ -0,0 +1,45 @@
+/**
+ * $Id: $
+ *
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_GENERATE_H
+#define BIF_GENERATE_H
+
+struct ToolSettings;
+struct EditBone;
+struct BArcIterator;
+struct bArmature;
+struct ListBase;
+
+typedef int(NextSubdivisionFunc)(struct ToolSettings*, struct BArcIterator*, int, int, float[3], float[3]);
+
+float calcArcCorrelation(struct BArcIterator *iter, int start, int end, float v0[3], float n[3]);
+
+int nextFixedSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
+int nextLengthSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
+int nextAdaptativeSubdivision(struct ToolSettings *toolsettings, struct BArcIterator *iter, int start, int end, float head[3], float p[3]);
+
+struct EditBone * subdivideArcBy(struct ToolSettings *toolsettings, struct bArmature *arm, ListBase *editbones, struct BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion);
+
+void setBoneRollFromNormal(struct EditBone *bone, float *no, float invmat[][4], float tmat[][3]);
+
+
+#endif /* BIF_GENERATE_H */
diff --git a/source/blender/editors/armature/BIF_retarget.h b/source/blender/editors/armature/BIF_retarget.h
new file mode 100644
index 00000000000..049ddf5baa5
--- /dev/null
+++ b/source/blender/editors/armature/BIF_retarget.h
@@ -0,0 +1,160 @@
+/**
+ * $Id: $
+ *
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_RETARGET_H
+#define BIF_RETARGET_H
+
+#include "DNA_listBase.h"
+
+#include "BLI_graph.h"
+#include "BLI_ghash.h"
+#include "BLI_threads.h"
+
+#include "reeb.h"
+
+struct Object;
+struct bArmature;
+struct bContext;
+
+struct EditBone;
+
+struct RigJoint;
+struct RigGraph;
+struct RigNode;
+struct RigArc;
+struct RigEdge;
+
+#define USE_THREADS
+
+typedef struct RigGraph {
+ ListBase arcs;
+ ListBase nodes;
+
+ float length;
+
+ FreeArc free_arc;
+ FreeNode free_node;
+ RadialSymmetry radial_symmetry;
+ AxialSymmetry axial_symmetry;
+ /*********************************/
+
+ int flag;
+
+ ListBase controls;
+ ListBase* editbones;
+
+ struct RigNode *head;
+ ReebGraph *link_mesh;
+
+
+ struct ThreadedWorker *worker;
+
+ GHash *bones_map; /* map of editbones by name */
+ GHash *controls_map; /* map of rigcontrols by bone pointer */
+
+ struct Object *ob;
+} RigGraph;
+
+typedef struct RigNode {
+ void *next, *prev;
+ float p[3];
+ int flag;
+
+ int degree;
+ struct BArc **arcs;
+
+ int subgraph_index;
+
+ int symmetry_level;
+ int symmetry_flag;
+ float symmetry_axis[3];
+ /*********************************/
+
+ ReebNode *link_mesh;
+} RigNode;
+
+typedef struct RigArc {
+ void *next, *prev;
+ RigNode *head, *tail;
+ int flag;
+
+ float length;
+
+ int symmetry_level;
+ int symmetry_group;
+ int symmetry_flag;
+ /*********************************/
+
+ ListBase edges;
+ int count;
+ ReebArc *link_mesh;
+} RigArc;
+
+typedef struct RigEdge {
+ struct RigEdge *next, *prev;
+ float head[3], tail[3];
+ float length;
+ float angle; /* angle to next edge */
+ float up_angle; /* angle between up_axis and the joint normal (defined as Previous edge CrossProduct Current edge */
+ struct EditBone *bone;
+ float up_axis[3];
+} RigEdge;
+
+/* Graph flags */
+#define RIG_FREE_BONELIST 1
+
+/* Control flags */
+#define RIG_CTRL_HEAD_DONE 1
+#define RIG_CTRL_TAIL_DONE 2
+#define RIG_CTRL_PARENT_DEFORM 4
+#define RIG_CTRL_FIT_ROOT 8
+#define RIG_CTRL_FIT_BONE 16
+
+#define RIG_CTRL_DONE (RIG_CTRL_HEAD_DONE|RIG_CTRL_TAIL_DONE)
+
+/* Control tail flags */
+typedef enum {
+ TL_NONE = 0,
+ TL_TAIL,
+ TL_HEAD
+} LinkTailMode;
+
+typedef struct RigControl {
+ struct RigControl *next, *prev;
+ float head[3], tail[3];
+ struct EditBone *bone;
+ struct EditBone *link;
+ struct EditBone *link_tail;
+ float up_axis[3];
+ float offset[3];
+ float qrot[4]; /* for dual linked bones, store the rotation of the linked bone for the finalization */
+ int flag;
+ LinkTailMode tail_mode;
+} RigControl;
+
+void BIF_retargetArc(struct bContext *C, ReebArc *earc, RigGraph *template_rigg);
+RigGraph *RIG_graphFromArmature(struct bContext *C, struct Object *ob, struct bArmature *arm);
+int RIG_nbJoints(RigGraph *rg);
+char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index);
+void RIG_freeRigGraph(BGraph *rg);
+
+#endif /* BIF_RETARGET_H */
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 9f50bb3f044..8142189b61b 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);
@@ -41,11 +41,11 @@ void ARMATURE_OT_subdivide_simple(struct wmOperatorType *ot);
void ARMATURE_OT_subdivide_multi(struct wmOperatorType *ot);
void ARMATURE_OT_parent_set(struct wmOperatorType *ot);
void ARMATURE_OT_parent_clear(struct wmOperatorType *ot);
-void ARMATURE_OT_de_select_all(struct wmOperatorType *ot);
-void ARMATURE_OT_selection_invert(struct wmOperatorType *ot);
+void ARMATURE_OT_select_all_toggle(struct wmOperatorType *ot);
+void ARMATURE_OT_select_invert(struct wmOperatorType *ot);
void ARMATURE_OT_select_hierarchy(struct wmOperatorType *ot);
-void ARMATURE_OT_select_connected(struct wmOperatorType *ot);
-void ARMATURE_OT_delete_selected(struct wmOperatorType *ot);
+void ARMATURE_OT_select_linked(struct wmOperatorType *ot);
+void ARMATURE_OT_delete(struct wmOperatorType *ot);
void ARMATURE_OT_duplicate_selected(struct wmOperatorType *ot);
void ARMATURE_OT_extrude(struct wmOperatorType *ot);
void ARMATURE_OT_click_extrude(struct wmOperatorType *ot);
@@ -55,11 +55,41 @@ void POSE_OT_reveal(struct wmOperatorType *ot);
void POSE_OT_rot_clear(struct wmOperatorType *ot);
void POSE_OT_loc_clear(struct wmOperatorType *ot);
void POSE_OT_scale_clear(struct wmOperatorType *ot);
-void POSE_OT_de_select_all(struct wmOperatorType *ot);
-void POSE_OT_selection_invert(struct wmOperatorType *ot);
+void POSE_OT_select_all_toggle(struct wmOperatorType *ot);
+void POSE_OT_select_invert(struct wmOperatorType *ot);
void POSE_OT_select_parent(struct wmOperatorType *ot);
void POSE_OT_select_hierarchy(struct wmOperatorType *ot);
-void POSE_OT_select_connected(struct wmOperatorType *ot);
+void POSE_OT_select_linked(struct wmOperatorType *ot);
+
+void SKETCH_OT_gesture(struct wmOperatorType *ot);
+void SKETCH_OT_delete(struct wmOperatorType *ot);
+void SKETCH_OT_draw_stroke(struct wmOperatorType *ot);
+void SKETCH_OT_draw_preview(struct wmOperatorType *ot);
+void SKETCH_OT_finish_stroke(struct wmOperatorType *ot);
+void SKETCH_OT_cancel_stroke(struct wmOperatorType *ot);
+void SKETCH_OT_select(struct wmOperatorType *ot);
+
+/* editarmature.c */
+struct bArmature;
+struct EditBone;
+struct ListBase;
+
+void make_boneList(struct ListBase *edbo, struct ListBase *bones, struct EditBone *parent);
+
+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/armature_ops.c b/source/blender/editors/armature/armature_ops.c
index e80d4d017d9..bc171acfac7 100644
--- a/source/blender/editors/armature/armature_ops.c
+++ b/source/blender/editors/armature/armature_ops.c
@@ -120,16 +120,25 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(ARMATURE_OT_parent_set);
WM_operatortype_append(ARMATURE_OT_parent_clear);
- WM_operatortype_append(ARMATURE_OT_de_select_all);
- WM_operatortype_append(ARMATURE_OT_selection_invert);
+ WM_operatortype_append(ARMATURE_OT_select_all_toggle);
+ WM_operatortype_append(ARMATURE_OT_select_invert);
WM_operatortype_append(ARMATURE_OT_select_hierarchy);
- WM_operatortype_append(ARMATURE_OT_select_connected);
+ WM_operatortype_append(ARMATURE_OT_select_linked);
- WM_operatortype_append(ARMATURE_OT_delete_selected);
+ WM_operatortype_append(ARMATURE_OT_delete);
WM_operatortype_append(ARMATURE_OT_duplicate_selected);
WM_operatortype_append(ARMATURE_OT_extrude);
WM_operatortype_append(ARMATURE_OT_click_extrude);
-
+
+ /* SKETCH */
+ WM_operatortype_append(SKETCH_OT_gesture);
+ WM_operatortype_append(SKETCH_OT_delete);
+ WM_operatortype_append(SKETCH_OT_draw_stroke);
+ WM_operatortype_append(SKETCH_OT_draw_preview);
+ WM_operatortype_append(SKETCH_OT_finish_stroke);
+ WM_operatortype_append(SKETCH_OT_cancel_stroke);
+ WM_operatortype_append(SKETCH_OT_select);
+
/* POSE */
WM_operatortype_append(POSE_OT_hide);
WM_operatortype_append(POSE_OT_reveal);
@@ -138,12 +147,12 @@ void ED_operatortypes_armature(void)
WM_operatortype_append(POSE_OT_loc_clear);
WM_operatortype_append(POSE_OT_scale_clear);
- WM_operatortype_append(POSE_OT_de_select_all);
- WM_operatortype_append(POSE_OT_selection_invert);
+ WM_operatortype_append(POSE_OT_select_all_toggle);
+ WM_operatortype_append(POSE_OT_select_invert);
WM_operatortype_append(POSE_OT_select_parent);
WM_operatortype_append(POSE_OT_select_hierarchy);
- WM_operatortype_append(POSE_OT_select_connected);
+ WM_operatortype_append(POSE_OT_select_linked);
WM_operatortype_append(ARMATURE_OT_test); // XXX temp test for context iterators... to be removed
}
@@ -167,36 +176,42 @@ void ED_keymap_armature(wmWindowManager *wm)
/* only the menu-version of subdivide is registered in keymaps for now */
WM_keymap_add_item(keymap, "ARMATURE_OT_subdivs", SKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "ARMATURE_OT_set_parent", PKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "ARMATURE_OT_clear_parent", PKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "ARMATURE_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "ARMATURE_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "ARMATURE_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "ARMATURE_OT_selection_invert", IKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "ARMATURE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ARMATURE_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_test", TKEY, KM_PRESS, 0, 0); // XXX temp test for context iterators... to be removed
kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
- RNA_boolean_set(kmi->ptr, "add_to_sel", 0);
+ RNA_boolean_set(kmi->ptr, "extend", 0);
kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
- RNA_boolean_set(kmi->ptr, "add_to_sel", 1);
+ RNA_boolean_set(kmi->ptr, "extend", 1);
kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
- RNA_boolean_set(kmi->ptr, "add_to_sel", 0);
+ RNA_boolean_set(kmi->ptr, "extend", 0);
kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
- RNA_boolean_set(kmi->ptr, "add_to_sel", 1);
+ RNA_boolean_set(kmi->ptr, "extend", 1);
- WM_keymap_add_item(keymap, "ARMATURE_OT_select_connected", LKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "ARMATURE_OT_delete_selected", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ARMATURE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ARMATURE_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_duplicate_selected", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "ARMATURE_OT_extrude", EKEY, KM_PRESS, 0, 0);
kmi= WM_keymap_add_item(keymap, "ARMATURE_OT_extrude", EKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "forked", 1);
WM_keymap_add_item(keymap, "ARMATURE_OT_click_extrude", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+ /* Armature ------------------------ */
+ WM_keymap_add_item(keymap, "SKETCH_OT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SKETCH_OT_finish_stroke", SELECTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SKETCH_OT_cancel_stroke", ESCKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SKETCH_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
+
/* Pose ------------------------ */
/* only set in posemode, by space_view3d listener */
keymap= WM_keymap_listbase(wm, "Pose", 0, 0);
@@ -210,25 +225,25 @@ void ED_keymap_armature(wmWindowManager *wm)
WM_keymap_add_item(keymap, "POSE_OT_loc_clear", GKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "POSE_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "POSE_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "POSE_OT_selection_invert", IKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "POSE_OT_select_parent", PKEY, KM_PRESS, KM_SHIFT, 0);
kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
- RNA_boolean_set(kmi->ptr, "add_to_sel", 0);
+ RNA_boolean_set(kmi->ptr, "extend", 0);
kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", LEFTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_PARENT);
- RNA_boolean_set(kmi->ptr, "add_to_sel", 1);
+ RNA_boolean_set(kmi->ptr, "extend", 1);
kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
- RNA_boolean_set(kmi->ptr, "add_to_sel", 0);
+ RNA_boolean_set(kmi->ptr, "extend", 0);
kmi= WM_keymap_add_item(keymap, "POSE_OT_select_hierarchy", RIGHTBRACKETKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD);
- RNA_boolean_set(kmi->ptr, "add_to_sel", 1);
+ RNA_boolean_set(kmi->ptr, "extend", 1);
- WM_keymap_add_item(keymap, "POSE_OT_select_connected", LKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "POSE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
}
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 021f87ea663..659cd586902 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"
+#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 */
{
@@ -1347,11 +1351,11 @@ static int pose_select_connected_invoke(bContext *C, wmOperator *op, wmEvent *ev
return OPERATOR_FINISHED;
}
-void POSE_OT_select_connected(wmOperatorType *ot)
+void POSE_OT_select_linked(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select Connected";
- ot->idname= "POSE_OT_select_connected";
+ ot->idname= "POSE_OT_select_linked";
/* api callbacks */
ot->exec= NULL;
@@ -1369,7 +1373,7 @@ void POSE_OT_select_connected(wmOperatorType *ot)
/* called in space.c */
/* previously "selectconnected_armature" */
-static int armature_select_connected_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
bArmature *arm;
EditBone *bone, *curBone, *next;
@@ -1441,15 +1445,15 @@ static int armature_select_connected_invoke(bContext *C, wmOperator *op, wmEvent
return OPERATOR_FINISHED;
}
-void ARMATURE_OT_select_connected(wmOperatorType *ot)
+void ARMATURE_OT_select_linked(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select Connected";
- ot->idname= "ARMATURE_OT_select_connected";
+ ot->idname= "ARMATURE_OT_select_linked";
/* api callbacks */
ot->exec= NULL;
- ot->invoke= armature_select_connected_invoke;
+ ot->invoke= armature_select_linked_invoke;
ot->poll= ED_operator_editarmature;
/* flags */
@@ -1672,11 +1676,11 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ARMATURE_OT_delete_selected(wmOperatorType *ot)
+void ARMATURE_OT_delete(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Delete Selected Bone(s)";
- ot->idname= "ARMATURE_OT_delete_selected";
+ ot->idname= "ARMATURE_OT_delete";
/* api callbacks */
ot->invoke = WM_operator_confirm;
@@ -1758,6 +1762,8 @@ void mouse_armature(bContext *C, short mval[2], int extend)
view3d_set_viewcontext(C, &vc);
+ BIF_sk_selectStroke(C, mval, extend);
+
nearBone= get_nearest_editbonepoint(&vc, mval, arm->edbo, 1, &selmask);
if (nearBone) {
@@ -1851,6 +1857,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);
+
+// BIF_freeTemplates(); /* force template update when entering editmode */
}
@@ -2085,14 +2093,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 +2117,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 +2355,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 +2397,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 +2421,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 +2511,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 +2525,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 +2540,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 +2601,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 +2618,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 +3229,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 +3406,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) {
@@ -3647,11 +3754,11 @@ static int armature_parent_set_invoke(bContext *C, wmOperator *op, wmEvent *even
}
CTX_DATA_END;
- uiMenuItemEnumO(head, "", 0, "ARMATURE_OT_set_parent", "type", ARM_PAR_CONNECT);
+ uiMenuItemEnumO(head, "", 0, "ARMATURE_OT_parent_set", "type", ARM_PAR_CONNECT);
/* ob becomes parent, make the associated menus */
if (allchildbones)
- uiMenuItemEnumO(head, "", 0, "ARMATURE_OT_set_parent", "type", ARM_PAR_OFFSET);
+ uiMenuItemEnumO(head, "", 0, "ARMATURE_OT_parent_set", "type", ARM_PAR_OFFSET);
uiPupMenuEnd(C, head);
@@ -3662,7 +3769,7 @@ void ARMATURE_OT_parent_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Make Parent";
- ot->idname= "ARMATURE_OT_set_parent";
+ ot->idname= "ARMATURE_OT_parent_set";
/* api callbacks */
ot->invoke = armature_parent_set_invoke;
@@ -3715,7 +3822,7 @@ void ARMATURE_OT_parent_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear Parent";
- ot->idname= "ARMATURE_OT_clear_parent";
+ ot->idname= "ARMATURE_OT_parent_clear";
/* api callbacks */
ot->invoke = WM_menu_invoke;
@@ -3730,7 +3837,7 @@ void ARMATURE_OT_parent_clear(wmOperatorType *ot)
/* **************** Selections ******************/
-static int armature_selection_invert_exec(bContext *C, wmOperator *op)
+static int armature_select_invert_exec(bContext *C, wmOperator *op)
{
/* Set the flags */
CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) {
@@ -3745,15 +3852,15 @@ static int armature_selection_invert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ARMATURE_OT_selection_invert(wmOperatorType *ot)
+void ARMATURE_OT_select_invert(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Invert Selection";
- ot->idname= "ARMATURE_OT_selection_invert";
+ ot->idname= "ARMATURE_OT_select_invert";
/* api callbacks */
- ot->exec= armature_selection_invert_exec;
+ ot->exec= armature_select_invert_exec;
ot->poll= ED_operator_editarmature;
/* flags */
@@ -3788,12 +3895,12 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ARMATURE_OT_de_select_all(wmOperatorType *ot)
+void ARMATURE_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "deselect all editbone";
- ot->idname= "ARMATURE_OT_de_select_all";
+ ot->idname= "ARMATURE_OT_select_all_toggle";
/* api callbacks */
ot->exec= armature_de_select_all_exec;
@@ -3813,7 +3920,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
bArmature *arm;
EditBone *curbone, *pabone, *chbone;
int direction = RNA_enum_get(op->ptr, "direction");
- int add_to_sel = RNA_boolean_get(op->ptr, "add_to_sel");
+ int add_to_sel = RNA_boolean_get(op->ptr, "extend");
ob= obedit;
arm= (bArmature *)ob->data;
@@ -3883,7 +3990,7 @@ void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
/* props */
RNA_def_enum(ot->srna, "direction", direction_items,
BONE_SELECT_PARENT, "Direction", "");
- RNA_def_boolean(ot->srna, "add_to_sel", 0, "Add to Selection", "");
+ RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
}
/* ***************** EditBone Alignment ********************* */
@@ -4714,7 +4821,7 @@ void POSE_OT_rot_clear(wmOperatorType *ot)
/* ***************** selections ********************** */
-static int pose_selection_invert_exec(bContext *C, wmOperator *op)
+static int pose_select_invert_exec(bContext *C, wmOperator *op)
{
/* Set the flags */
@@ -4729,15 +4836,15 @@ static int pose_selection_invert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void POSE_OT_selection_invert(wmOperatorType *ot)
+void POSE_OT_select_invert(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Invert Selection";
- ot->idname= "POSE_OT_selection_invert";
+ ot->idname= "POSE_OT_select_invert";
/* api callbacks */
- ot->exec= pose_selection_invert_exec;
+ ot->exec= pose_select_invert_exec;
ot->poll= ED_operator_posemode;
/* flags */
@@ -4765,12 +4872,12 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void POSE_OT_de_select_all(wmOperatorType *ot)
+void POSE_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "deselect all bones";
- ot->idname= "POSE_OT_de_select_all";
+ ot->idname= "POSE_OT_select_all_toggle";
/* api callbacks */
ot->exec= pose_de_select_all_exec;
@@ -5009,7 +5116,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 +5343,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 +5357,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 +5405,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;
+ 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;
- parent = add_editbone(obedit, "Bone");
- parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
- VECCOPY(parent->head, head->p);
+ initArcIterator(iter, arc, head);
- 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);
-
- 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 +5457,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 +5571,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/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c
new file mode 100644
index 00000000000..a1990814a02
--- /dev/null
+++ b/source/blender/editors/armature/editarmature_generate.c
@@ -0,0 +1,329 @@
+/**
+ * $Id: editarmature_generate.c $
+ *
+ * ***** 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 *****
+ * editarmature.c: Interface for creating and posing armature objects
+ */
+
+#include <string.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_scene_types.h"
+#include "DNA_armature_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_graph.h"
+
+#include "BKE_utildefines.h"
+#include "BKE_global.h"
+#include "BKE_context.h"
+
+#include "ED_armature.h"
+#include "armature_intern.h"
+#include "BIF_generate.h"
+
+void setBoneRollFromNormal(EditBone *bone, float *no, float invmat[][4], float tmat[][3])
+{
+ if (no != NULL && !VecIsNull(no))
+ {
+ float tangent[3], cotangent[3], normal[3];
+
+ VECCOPY(normal, no);
+ Mat3MulVecfl(tmat, normal);
+
+ VecSubf(tangent, bone->tail, bone->head);
+ Crossf(cotangent, tangent, normal);
+ Crossf(normal, cotangent, tangent);
+
+ Normalize(normal);
+
+ bone->roll = ED_rollBoneToVector(bone, normal);
+ }
+}
+
+float calcArcCorrelation(BArcIterator *iter, int start, int end, float v0[3], float n[3])
+{
+ int len = 2 + abs(end - start);
+
+ if (len > 2)
+ {
+ float avg_t = 0.0f;
+ float s_t = 0.0f;
+ float s_xyz = 0.0f;
+ int i;
+
+ /* First pass, calculate average */
+ for (i = start; i <= end; i++)
+ {
+ float v[3];
+
+ IT_peek(iter, i);
+ VecSubf(v, iter->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 (i = start; i <= end; i++)
+ {
+ float v[3], d[3];
+ float dt;
+
+ IT_peek(iter, i);
+ VecSubf(v, iter->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 1.0f - s_xyz / s_t;
+ }
+ else
+ {
+ return 1.0f;
+ }
+}
+
+int nextFixedSubdivision(ToolSettings *toolsettings, BArcIterator *iter, int start, int end, float head[3], float p[3])
+{
+ static float stroke_length = 0;
+ static float current_length;
+ static char n;
+ float *v1, *v2;
+ float length_threshold;
+ int i;
+
+ if (stroke_length == 0)
+ {
+ current_length = 0;
+
+ IT_peek(iter, start);
+ v1 = iter->p;
+
+ for (i = start + 1; i <= end; i++)
+ {
+ IT_peek(iter, i);
+ v2 = iter->p;
+
+ stroke_length += VecLenf(v1, v2);
+
+ v1 = v2;
+ }
+
+ n = 0;
+ current_length = 0;
+ }
+
+ n++;
+
+ length_threshold = n * stroke_length / toolsettings->skgen_subdivision_number;
+
+ IT_peek(iter, start);
+ v1 = iter->p;
+
+ /* < and not <= because we don't care about end, it is P_EXACT anyway */
+ for (i = start + 1; i < end; i++)
+ {
+ IT_peek(iter, i);
+ v2 = iter->p;
+
+ current_length += VecLenf(v1, v2);
+
+ if (current_length >= length_threshold)
+ {
+ VECCOPY(p, v2);
+ return i;
+ }
+
+ v1 = v2;
+ }
+
+ stroke_length = 0;
+
+ return -1;
+}
+int nextAdaptativeSubdivision(ToolSettings *toolsettings, BArcIterator *iter, int start, int end, float head[3], float p[3])
+{
+ float correlation_threshold = toolsettings->skgen_correlation_limit;
+ float *start_p;
+ float n[3];
+ int i;
+
+ IT_peek(iter, start);
+ start_p = iter->p;
+
+ for (i = start + 2; i <= end; i++)
+ {
+ /* Calculate normal */
+ IT_peek(iter, i);
+ VecSubf(n, iter->p, head);
+
+ if (calcArcCorrelation(iter, start, i, start_p, n) < correlation_threshold)
+ {
+ IT_peek(iter, i - 1);
+ VECCOPY(p, iter->p);
+ return i - 1;
+ }
+ }
+
+ return -1;
+}
+
+int nextLengthSubdivision(ToolSettings *toolsettings, BArcIterator *iter, int start, int end, float head[3], float p[3])
+{
+ float lengthLimit = toolsettings->skgen_length_limit;
+ int same = 1;
+ int i;
+
+ i = start + 1;
+ while (i <= end)
+ {
+ float *vec0;
+ float *vec1;
+
+ IT_peek(iter, i - 1);
+ vec0 = iter->p;
+
+ IT_peek(iter, i);
+ vec1 = iter->p;
+
+ /* If lengthLimit hits the current segment */
+ if (VecLenf(vec1, 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, 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(p, dv);
+ VecMulf(p, f);
+ VecAddf(p, p, vec0);
+ }
+ else
+ {
+ VECCOPY(p, vec1);
+ }
+ }
+ else
+ {
+ float dv[3];
+
+ VecSubf(dv, vec1, vec0);
+ Normalize(dv);
+
+ VECCOPY(p, dv);
+ VecMulf(p, lengthLimit);
+ VecAddf(p, p, head);
+ }
+
+ return i - 1; /* restart at lower bound */
+ }
+ else
+ {
+ i++;
+ same = 0; // Reset same
+ }
+ }
+
+ return -1;
+}
+
+EditBone * subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *editbones, BArcIterator *iter, float invmat[][4], float tmat[][3], NextSubdivisionFunc next_subdividion)
+{
+ EditBone *lastBone = NULL;
+ EditBone *child = NULL;
+ EditBone *parent = NULL;
+ int bone_start = 0;
+ int end = iter->length;
+ int index;
+
+ IT_head(iter);
+
+ parent = addEditBone(arm, "Bone");
+ VECCOPY(parent->head, iter->p);
+
+ index = next_subdividion(toolsettings, iter, bone_start, end, parent->head, parent->tail);
+ while (index != -1)
+ {
+ IT_peek(iter, index);
+
+ child = addEditBone(arm, "Bone");
+ VECCOPY(child->head, parent->tail);
+ child->parent = parent;
+ child->flag |= BONE_CONNECTED;
+
+ /* going to next bone, fix parent */
+ Mat4MulVecfl(invmat, parent->tail);
+ Mat4MulVecfl(invmat, parent->head);
+ setBoneRollFromNormal(parent, iter->no, invmat, tmat);
+
+ parent = child; // new child is next parent
+ bone_start = index; // start next bone from current index
+
+ index = next_subdividion(toolsettings, iter, bone_start, end, parent->head, parent->tail);
+ }
+
+ iter->tail(iter);
+
+ VECCOPY(parent->tail, iter->p);
+
+ /* fix last bone */
+ Mat4MulVecfl(invmat, parent->tail);
+ Mat4MulVecfl(invmat, parent->head);
+ setBoneRollFromNormal(parent, iter->no, invmat, tmat);
+ lastBone = parent;
+
+ return lastBone;
+}
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
new file mode 100644
index 00000000000..5fc8d52ffef
--- /dev/null
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -0,0 +1,2961 @@
+/**
+ * $Id:
+ *
+ * ***** 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.
+ *
+ * Contributor(s): Martin Poirier
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * autoarmature.c: Interface for automagically manipulating armature (retarget, created, ...)
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "PIL_time.h"
+
+#include "DNA_ID.h"
+#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_view3d_types.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_editVert.h"
+#include "BLI_ghash.h"
+#include "BLI_graph.h"
+#include "BLI_rand.h"
+#include "BLI_threads.h"
+
+//#include "BDR_editobject.h"
+
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+#include "BKE_constraint.h"
+#include "BKE_armature.h"
+#include "BKE_context.h"
+
+#include "ED_armature.h"
+#include "BIF_retarget.h"
+//#include "BIF_space.h"
+//#include "BIF_toolbox.h"
+
+#include "PIL_time.h"
+
+//#include "mydevice.h"
+#include "reeb.h" // FIX ME
+//#include "blendef.h"
+
+#include "armature_intern.h"
+
+/************ RIG RETARGET DATA STRUCTURES ***************/
+
+typedef struct MemoNode {
+ float weight;
+ int next;
+} MemoNode;
+
+typedef struct RetargetParam {
+ RigGraph *rigg;
+ RigArc *iarc;
+ RigNode *inode_start;
+ bContext *context;
+} RetargetParam;
+
+typedef enum
+{
+ RETARGET_LENGTH,
+ RETARGET_AGGRESSIVE
+} RetargetMode;
+
+typedef enum
+{
+ METHOD_BRUTE_FORCE = 0,
+ METHOD_MEMOIZE = 1
+} RetargetMethod;
+
+typedef enum
+{
+ ARC_FREE = 0,
+ ARC_TAKEN = 1,
+ ARC_USED = 2
+} ArcUsageFlags;
+
+RigGraph *GLOBAL_RIGG = NULL;
+
+/*******************************************************************************************************/
+
+void *exec_retargetArctoArc(void *param);
+
+static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second);
+float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]);
+
+/* two levels */
+#define SHAPE_LEVELS (SHAPE_RADIX * SHAPE_RADIX)
+
+/*********************************** EDITBONE UTILS ****************************************************/
+
+int countEditBoneChildren(ListBase *list, EditBone *parent)
+{
+ EditBone *ebone;
+ int count = 0;
+
+ for (ebone = list->first; ebone; ebone = ebone->next)
+ {
+ if (ebone->parent == parent)
+ {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+EditBone* nextEditBoneChild(ListBase *list, EditBone *parent, int n)
+{
+ EditBone *ebone;
+
+ for (ebone = list->first; ebone; ebone = ebone->next)
+ {
+ if (ebone->parent == parent)
+ {
+ if (n == 0)
+ {
+ return ebone;
+ }
+ n--;
+ }
+ }
+
+ return NULL;
+}
+
+void getEditBoneRollUpAxis(EditBone *bone, float roll, float up_axis[3])
+{
+ float mat[3][3], nor[3];
+
+ VecSubf(nor, bone->tail, bone->head);
+
+ vec_roll_to_mat3(nor, roll, mat);
+ VECCOPY(up_axis, mat[2]);
+}
+
+float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4], float qroll[4], float aligned_axis[3])
+{
+ float nor[3], new_up_axis[3], x_axis[3], z_axis[3];
+
+ VECCOPY(new_up_axis, old_up_axis);
+ QuatMulVecf(qrot, new_up_axis);
+
+ VecSubf(nor, bone->tail, bone->head);
+
+ Crossf(x_axis, nor, aligned_axis);
+ Crossf(z_axis, x_axis, nor);
+
+ Normalize(new_up_axis);
+ Normalize(x_axis);
+ Normalize(z_axis);
+
+ if (Inpf(new_up_axis, x_axis) < 0)
+ {
+ VecMulf(x_axis, -1);
+ }
+
+ if (Inpf(new_up_axis, z_axis) < 0)
+ {
+ VecMulf(z_axis, -1);
+ }
+
+ if (NormalizedVecAngle2(x_axis, new_up_axis) < NormalizedVecAngle2(z_axis, new_up_axis))
+ {
+ RotationBetweenVectorsToQuat(qroll, new_up_axis, x_axis); /* set roll rotation quat */
+ return ED_rollBoneToVector(bone, x_axis);
+ }
+ else
+ {
+ RotationBetweenVectorsToQuat(qroll, new_up_axis, z_axis); /* set roll rotation quat */
+ return ED_rollBoneToVector(bone, z_axis);
+ }
+}
+
+float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4], float qroll[4])
+{
+ if (previous == NULL)
+ {
+ QuatOne(qroll);
+ return rollBoneByQuat(edge->bone, edge->up_axis, qrot);
+ }
+ else
+ {
+ float new_up_axis[3];
+ float vec_first[3], vec_second[3], normal[3];
+
+ if (previous->bone)
+ {
+ VecSubf(vec_first, previous->bone->tail, previous->bone->head);
+ }
+ else if (previous->prev->bone)
+ {
+ VecSubf(vec_first, edge->bone->head, previous->prev->bone->tail);
+ }
+ else
+ {
+ /* SHOULDN'T BE HERE */
+ QuatOne(qroll);
+ return rollBoneByQuat(edge->bone, edge->up_axis, qrot);
+ }
+
+ VecSubf(vec_second, edge->bone->tail, edge->bone->head);
+
+ Normalize(vec_first);
+ Normalize(vec_second);
+
+ Crossf(normal, vec_first, vec_second);
+ Normalize(normal);
+
+ AxisAngleToQuat(qroll, vec_second, edge->up_angle);
+
+ QuatMulVecf(qroll, normal);
+
+ VECCOPY(new_up_axis, edge->up_axis);
+ QuatMulVecf(qrot, new_up_axis);
+
+ Normalize(new_up_axis);
+
+ /* real qroll between normal and up_axis */
+ RotationBetweenVectorsToQuat(qroll, new_up_axis, normal);
+
+ return ED_rollBoneToVector(edge->bone, normal);
+ }
+}
+
+float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4])
+{
+ float new_up_axis[3];
+
+ VECCOPY(new_up_axis, old_up_axis);
+ QuatMulVecf(qrot, new_up_axis);
+
+ Normalize(new_up_axis);
+
+ return ED_rollBoneToVector(bone, new_up_axis);
+}
+
+/************************************ DESTRUCTORS ******************************************************/
+
+void RIG_freeRigArc(BArc *arc)
+{
+ BLI_freelistN(&((RigArc*)arc)->edges);
+}
+
+void RIG_freeRigGraph(BGraph *rg)
+{
+ RigGraph *rigg = (RigGraph*)rg;
+ BNode *node;
+ BArc *arc;
+
+#ifdef USE_THREADS
+ BLI_destroy_worker(rigg->worker);
+#endif
+
+ if (rigg->link_mesh)
+ {
+ REEB_freeGraph(rigg->link_mesh);
+ }
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ RIG_freeRigArc(arc);
+ }
+ BLI_freelistN(&rg->arcs);
+
+ for (node = rg->nodes.first; node; node = node->next)
+ {
+ BLI_freeNode(rg, (BNode*)node);
+ }
+ BLI_freelistN(&rg->nodes);
+
+ BLI_freelistN(&rigg->controls);
+
+ BLI_ghash_free(rigg->bones_map, NULL, NULL);
+ BLI_ghash_free(rigg->controls_map, NULL, NULL);
+
+ if (rigg->flag & RIG_FREE_BONELIST)
+ {
+ BLI_freelistN(rigg->editbones);
+ MEM_freeN(rigg->editbones);
+ }
+
+ MEM_freeN(rg);
+}
+
+/************************************* ALLOCATORS ******************************************************/
+
+static RigGraph *newRigGraph()
+{
+ RigGraph *rg;
+ int totthread;
+
+ rg = MEM_callocN(sizeof(RigGraph), "rig graph");
+
+ rg->head = NULL;
+
+ rg->bones_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
+ rg->controls_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
+
+ rg->free_arc = RIG_freeRigArc;
+ rg->free_node = NULL;
+
+#ifdef USE_THREADS
+// if(G.scene->r.mode & R_FIXED_THREADS)
+// {
+// totthread = G.scene->r.threads;
+// }
+// else
+// {
+ totthread = BLI_system_thread_count();
+// }
+
+ rg->worker = BLI_create_worker(exec_retargetArctoArc, totthread, 20); /* fix number of threads */
+#endif
+
+ return rg;
+}
+
+static RigArc *newRigArc(RigGraph *rg)
+{
+ RigArc *arc;
+
+ arc = MEM_callocN(sizeof(RigArc), "rig arc");
+ arc->count = 0;
+ BLI_addtail(&rg->arcs, arc);
+
+ return arc;
+}
+
+static RigControl *newRigControl(RigGraph *rg)
+{
+ RigControl *ctrl;
+
+ ctrl = MEM_callocN(sizeof(RigControl), "rig control");
+
+ BLI_addtail(&rg->controls, ctrl);
+
+ return ctrl;
+}
+
+static RigNode *newRigNodeHead(RigGraph *rg, RigArc *arc, float p[3])
+{
+ RigNode *node;
+ node = MEM_callocN(sizeof(RigNode), "rig node");
+ BLI_addtail(&rg->nodes, node);
+
+ VECCOPY(node->p, p);
+ node->degree = 1;
+ node->arcs = NULL;
+
+ arc->head = node;
+
+ return node;
+}
+
+static void addRigNodeHead(RigGraph *rg, RigArc *arc, RigNode *node)
+{
+ node->degree++;
+
+ arc->head = node;
+}
+
+static RigNode *newRigNode(RigGraph *rg, float p[3])
+{
+ RigNode *node;
+ node = MEM_callocN(sizeof(RigNode), "rig node");
+ BLI_addtail(&rg->nodes, node);
+
+ VECCOPY(node->p, p);
+ node->degree = 0;
+ node->arcs = NULL;
+
+ return node;
+}
+
+static RigNode *newRigNodeTail(RigGraph *rg, RigArc *arc, float p[3])
+{
+ RigNode *node = newRigNode(rg, p);
+
+ node->degree = 1;
+ arc->tail = node;
+
+ return node;
+}
+
+static void RIG_appendEdgeToArc(RigArc *arc, RigEdge *edge)
+{
+ BLI_addtail(&arc->edges, edge);
+
+ if (edge->prev == NULL)
+ {
+ VECCOPY(edge->head, arc->head->p);
+ }
+ else
+ {
+ RigEdge *last_edge = edge->prev;
+ VECCOPY(edge->head, last_edge->tail);
+ RIG_calculateEdgeAngles(last_edge, edge);
+ }
+
+ edge->length = VecLenf(edge->head, edge->tail);
+
+ arc->length += edge->length;
+
+ arc->count += 1;
+}
+
+static void RIG_addEdgeToArc(RigArc *arc, float tail[3], EditBone *bone)
+{
+ RigEdge *edge;
+
+ edge = MEM_callocN(sizeof(RigEdge), "rig edge");
+
+ VECCOPY(edge->tail, tail);
+ edge->bone = bone;
+
+ if (bone)
+ {
+ getEditBoneRollUpAxis(bone, bone->roll, edge->up_axis);
+ }
+
+ RIG_appendEdgeToArc(arc, edge);
+}
+/************************************** CLONING TEMPLATES **********************************************/
+
+static void renameTemplateBone(char *name, char *template_name, ListBase *editbones, char *side_string, char *num_string)
+{
+ int i, j;
+
+ for (i = 0, j = 0; template_name[i] != '\0' && i < 31 && j < 31; i++)
+ {
+ if (template_name[i] == '&')
+ {
+ if (template_name[i+1] == 'S' || template_name[i+1] == 's')
+ {
+ j += sprintf(name + j, side_string);
+ i++;
+ }
+ else if (template_name[i+1] == 'N' || template_name[i+1] == 'n')
+ {
+ j += sprintf(name + j, num_string);
+ i++;
+ }
+ else
+ {
+ name[j] = template_name[i];
+ j++;
+ }
+ }
+ else
+ {
+ name[j] = template_name[i];
+ j++;
+ }
+ }
+
+ name[j] = '\0';
+
+ unique_editbone_name(editbones, name, NULL);
+}
+
+static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_ctrl, GHash *ptr_hash, char *side_string, char *num_string)
+{
+ RigControl *ctrl;
+ char name[32];
+
+ ctrl = newRigControl(rg);
+
+ VECCOPY(ctrl->head, src_ctrl->head);
+ VECCOPY(ctrl->tail, src_ctrl->tail);
+ VECCOPY(ctrl->up_axis, src_ctrl->up_axis);
+ VECCOPY(ctrl->offset, src_ctrl->offset);
+
+ ctrl->tail_mode = src_ctrl->tail_mode;
+ ctrl->flag = src_ctrl->flag;
+
+ renameTemplateBone(name, src_ctrl->bone->name, rg->editbones, side_string, num_string);
+ ctrl->bone = duplicateEditBoneObjects(src_ctrl->bone, name, rg->editbones, src_rg->ob, rg->ob);
+ ctrl->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
+ BLI_ghash_insert(ptr_hash, src_ctrl->bone, ctrl->bone);
+
+ ctrl->link = src_ctrl->link;
+ ctrl->link_tail = src_ctrl->link_tail;
+
+ return ctrl;
+}
+
+static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash *ptr_hash, char *side_string, char *num_string)
+{
+ RigEdge *src_edge;
+ RigArc *arc;
+
+ arc = newRigArc(rg);
+
+ arc->head = BLI_ghash_lookup(ptr_hash, src_arc->head);
+ arc->tail = BLI_ghash_lookup(ptr_hash, src_arc->tail);
+
+ arc->head->degree++;
+ arc->tail->degree++;
+
+ arc->length = src_arc->length;
+
+ arc->count = src_arc->count;
+
+ for (src_edge = src_arc->edges.first; src_edge; src_edge = src_edge->next)
+ {
+ RigEdge *edge;
+
+ edge = MEM_callocN(sizeof(RigEdge), "rig edge");
+
+ VECCOPY(edge->head, src_edge->head);
+ VECCOPY(edge->tail, src_edge->tail);
+ VECCOPY(edge->up_axis, src_edge->up_axis);
+
+ edge->length = src_edge->length;
+ edge->angle = src_edge->angle;
+ edge->up_angle = src_edge->up_angle;
+
+ if (src_edge->bone != NULL)
+ {
+ char name[32];
+ renameTemplateBone(name, src_edge->bone->name, rg->editbones, side_string, num_string);
+ edge->bone = duplicateEditBoneObjects(src_edge->bone, name, rg->editbones, src_rg->ob, rg->ob);
+ edge->bone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL|BONE_ACTIVE);
+ BLI_ghash_insert(ptr_hash, src_edge->bone, edge->bone);
+ }
+
+ BLI_addtail(&arc->edges, edge);
+ }
+
+ return arc;
+}
+
+static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob, char *side_string, char *num_string)
+{
+ GHash *ptr_hash;
+ RigNode *node;
+ RigArc *arc;
+ RigControl *ctrl;
+ RigGraph *rg;
+
+ ptr_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+ rg = newRigGraph();
+
+ rg->ob = ob;
+ rg->editbones = editbones;
+
+ preEditBoneDuplicate(rg->editbones); /* prime bones for duplication */
+ preEditBoneDuplicate(src->editbones); /* prime bones for duplication */
+
+ /* Clone nodes */
+ for (node = src->nodes.first; node; node = node->next)
+ {
+ RigNode *cloned_node = newRigNode(rg, node->p);
+ BLI_ghash_insert(ptr_hash, node, cloned_node);
+ }
+
+ rg->head = BLI_ghash_lookup(ptr_hash, src->head);
+
+ /* Clone arcs */
+ for (arc = src->arcs.first; arc; arc = arc->next)
+ {
+ cloneArc(rg, src, arc, ptr_hash, side_string, num_string);
+ }
+
+ /* Clone controls */
+ for (ctrl = src->controls.first; ctrl; ctrl = ctrl->next)
+ {
+ cloneControl(rg, src, ctrl, ptr_hash, side_string, num_string);
+ }
+
+ /* Relink bones properly */
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ RigEdge *edge;
+
+ for (edge = arc->edges.first; edge; edge = edge->next)
+ {
+ if (edge->bone != NULL)
+ {
+ EditBone *bone;
+
+ updateDuplicateSubtargetObjects(edge->bone, src->editbones, src->ob, rg->ob);
+
+ if (edge->bone->parent)
+ {
+ bone = BLI_ghash_lookup(ptr_hash, edge->bone->parent);
+
+ if (bone != NULL)
+ {
+ edge->bone->parent = bone;
+ }
+ else
+ {
+ /* disconnect since parent isn't cloned
+ * this will only happen when cloning from selected bones
+ * */
+ edge->bone->flag &= ~BONE_CONNECTED;
+ }
+ }
+ }
+ }
+ }
+
+ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
+ {
+ EditBone *bone;
+
+ updateDuplicateSubtargetObjects(ctrl->bone, src->editbones, src->ob, rg->ob);
+
+ if (ctrl->bone->parent)
+ {
+ bone = BLI_ghash_lookup(ptr_hash, ctrl->bone->parent);
+
+ if (bone != NULL)
+ {
+ ctrl->bone->parent = bone;
+ }
+ else
+ {
+ /* disconnect since parent isn't cloned
+ * this will only happen when cloning from selected bones
+ * */
+ ctrl->bone->flag &= ~BONE_CONNECTED;
+ }
+ }
+
+ ctrl->link = BLI_ghash_lookup(ptr_hash, ctrl->link);
+ ctrl->link_tail = BLI_ghash_lookup(ptr_hash, ctrl->link_tail);
+ }
+
+ BLI_ghash_free(ptr_hash, NULL, NULL);
+
+ return rg;
+}
+
+
+/*******************************************************************************************************/
+
+static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second)
+{
+ float vec_first[3], vec_second[3];
+
+ VecSubf(vec_first, edge_first->tail, edge_first->head);
+ VecSubf(vec_second, edge_second->tail, edge_second->head);
+
+ Normalize(vec_first);
+ Normalize(vec_second);
+
+ edge_first->angle = NormalizedVecAngle2(vec_first, vec_second);
+
+ if (edge_second->bone != NULL)
+ {
+ float normal[3];
+
+ Crossf(normal, vec_first, vec_second);
+ Normalize(normal);
+
+ edge_second->up_angle = NormalizedVecAngle2(normal, edge_second->up_axis);
+ }
+}
+
+/************************************ CONTROL BONES ****************************************************/
+
+static void RIG_addControlBone(RigGraph *rg, EditBone *bone)
+{
+ RigControl *ctrl = newRigControl(rg);
+ ctrl->bone = bone;
+ VECCOPY(ctrl->head, bone->head);
+ VECCOPY(ctrl->tail, bone->tail);
+ getEditBoneRollUpAxis(bone, bone->roll, ctrl->up_axis);
+ ctrl->tail_mode = TL_NONE;
+
+ BLI_ghash_insert(rg->controls_map, bone->name, ctrl);
+}
+
+static int RIG_parentControl(RigControl *ctrl, EditBone *link)
+{
+ if (link)
+ {
+ float offset[3];
+ int flag = 0;
+
+ VecSubf(offset, ctrl->bone->head, link->head);
+
+ /* if root matches, check for direction too */
+ if (Inpf(offset, offset) < 0.0001)
+ {
+ float vbone[3], vparent[3];
+
+ flag |= RIG_CTRL_FIT_ROOT;
+
+ VecSubf(vbone, ctrl->bone->tail, ctrl->bone->head);
+ VecSubf(vparent, link->tail, link->head);
+
+ /* test for opposite direction */
+ if (Inpf(vbone, vparent) > 0)
+ {
+ float nor[3];
+ float len;
+
+ Crossf(nor, vbone, vparent);
+
+ len = Inpf(nor, nor);
+ if (len < 0.0001)
+ {
+ flag |= RIG_CTRL_FIT_BONE;
+ }
+ }
+ }
+
+ /* Bail out if old one is automatically better */
+ if (flag < ctrl->flag)
+ {
+ return 0;
+ }
+
+ /* if there's already a link
+ * overwrite only if new link is higher in the chain */
+ if (ctrl->link && flag == ctrl->flag)
+ {
+ EditBone *bone = NULL;
+
+ for (bone = ctrl->link; bone; bone = bone->parent)
+ {
+ /* if link is in the chain, break and use that one */
+ if (bone == link)
+ {
+ break;
+ }
+ }
+
+ /* not in chain, don't update link */
+ if (bone == NULL)
+ {
+ return 0;
+ }
+ }
+
+
+ ctrl->link = link;
+ ctrl->flag = flag;
+
+ VECCOPY(ctrl->offset, offset);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+static void RIG_reconnectControlBones(RigGraph *rg)
+{
+ RigControl *ctrl;
+ int change = 1;
+
+ /* first pass, link to deform bones */
+ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
+ {
+ bPoseChannel *pchan;
+ bConstraint *con;
+ int found = 0;
+
+ /* DO SOME MAGIC HERE */
+ for (pchan= rg->ob->pose->chanbase.first; pchan; pchan= pchan->next)
+ {
+ for (con= pchan->constraints.first; con; con= con->next)
+ {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ /* constraint targets */
+ if (cti && cti->get_constraint_targets)
+ {
+ int target_index;
+
+ cti->get_constraint_targets(con, &targets);
+
+ for (target_index = 0, ct= targets.first; ct; target_index++, ct= ct->next)
+ {
+ if ((ct->tar == rg->ob) && strcmp(ct->subtarget, ctrl->bone->name) == 0)
+ {
+ /* SET bone link to bone corresponding to pchan */
+ EditBone *link = BLI_ghash_lookup(rg->bones_map, pchan->name);
+
+ /* Making sure bone is in this armature */
+ if (link != NULL)
+ {
+ /* for pole targets, link to parent bone instead, if possible */
+ if (con->type == CONSTRAINT_TYPE_KINEMATIC && target_index == 1)
+ {
+ if (link->parent && BLI_ghash_haskey(rg->bones_map, link->parent->name))
+ {
+ link = link->parent;
+ }
+ }
+
+ found = RIG_parentControl(ctrl, link);
+ }
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
+ }
+ }
+ }
+
+ /* if not found yet, check parent */
+ if (found == 0)
+ {
+ if (ctrl->bone->parent)
+ {
+ /* make sure parent is a deforming bone
+ * NULL if not
+ * */
+ EditBone *link = BLI_ghash_lookup(rg->bones_map, ctrl->bone->parent->name);
+
+ found = RIG_parentControl(ctrl, link);
+ }
+
+ /* check if bone is not superposed on another one */
+ {
+ RigArc *arc;
+ RigArc *best_arc = NULL;
+ EditBone *link = NULL;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ RigEdge *edge;
+ for (edge = arc->edges.first; edge; edge = edge->next)
+ {
+ if (edge->bone)
+ {
+ int fit = 0;
+
+ fit = VecLenf(ctrl->bone->head, edge->bone->head) < 0.0001;
+ fit = fit || VecLenf(ctrl->bone->tail, edge->bone->tail) < 0.0001;
+
+ if (fit)
+ {
+ /* pick the bone on the arc with the lowest symmetry level
+ * means you connect control to the trunk of the skeleton */
+ if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level)
+ {
+ best_arc = arc;
+ link = edge->bone;
+ }
+ }
+ }
+ }
+ }
+
+ found = RIG_parentControl(ctrl, link);
+ }
+ }
+
+ /* if not found yet, check child */
+ if (found == 0)
+ {
+ RigArc *arc;
+ RigArc *best_arc = NULL;
+ EditBone *link = NULL;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ RigEdge *edge;
+ for (edge = arc->edges.first; edge; edge = edge->next)
+ {
+ if (edge->bone && edge->bone->parent == ctrl->bone)
+ {
+ /* pick the bone on the arc with the lowest symmetry level
+ * means you connect control to the trunk of the skeleton */
+ if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level)
+ {
+ best_arc = arc;
+ link = edge->bone;
+ }
+ }
+ }
+ }
+
+ found = RIG_parentControl(ctrl, link);
+ }
+
+ }
+
+
+ /* second pass, make chains in control bones */
+ while (change)
+ {
+ change = 0;
+
+ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
+ {
+ /* if control is not linked yet */
+ if (ctrl->link == NULL)
+ {
+ bPoseChannel *pchan;
+ bConstraint *con;
+ RigControl *ctrl_parent = NULL;
+ RigControl *ctrl_child;
+ int found = 0;
+
+ if (ctrl->bone->parent)
+ {
+ ctrl_parent = BLI_ghash_lookup(rg->controls_map, ctrl->bone->parent->name);
+ }
+
+ /* check constraints first */
+
+ /* DO SOME MAGIC HERE */
+ for (pchan= rg->ob->pose->chanbase.first; pchan; pchan= pchan->next)
+ {
+ for (con= pchan->constraints.first; con; con= con->next)
+ {
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+ ListBase targets = {NULL, NULL};
+ bConstraintTarget *ct;
+
+ /* constraint targets */
+ if (cti && cti->get_constraint_targets)
+ {
+ cti->get_constraint_targets(con, &targets);
+
+ for (ct= targets.first; ct; ct= ct->next)
+ {
+ if ((ct->tar == rg->ob) && strcmp(ct->subtarget, ctrl->bone->name) == 0)
+ {
+ /* SET bone link to ctrl corresponding to pchan */
+ RigControl *link = BLI_ghash_lookup(rg->controls_map, pchan->name);
+
+ /* if owner is a control bone, link with it */
+ if (link && link->link)
+ {
+ RIG_parentControl(ctrl, link->bone);
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (cti->flush_constraint_targets)
+ cti->flush_constraint_targets(con, &targets, 0);
+ }
+ }
+ }
+
+ if (found == 0)
+ {
+ /* check if parent is already linked */
+ if (ctrl_parent && ctrl_parent->link)
+ {
+ RIG_parentControl(ctrl, ctrl_parent->bone);
+ change = 1;
+ }
+ else
+ {
+ /* check childs */
+ for (ctrl_child = rg->controls.first; ctrl_child; ctrl_child = ctrl_child->next)
+ {
+ /* if a child is linked, link to that one */
+ if (ctrl_child->link && ctrl_child->bone->parent == ctrl->bone)
+ {
+ RIG_parentControl(ctrl, ctrl_child->bone);
+ change = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* third pass, link control tails */
+ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
+ {
+ /* fit bone already means full match, so skip those */
+ if ((ctrl->flag & RIG_CTRL_FIT_BONE) == 0)
+ {
+ GHashIterator ghi;
+
+ /* look on deform bones first */
+ BLI_ghashIterator_init(&ghi, rg->bones_map);
+
+ for( ; !BLI_ghashIterator_isDone(&ghi); BLI_ghashIterator_step(&ghi))
+ {
+ EditBone *bone = (EditBone*)BLI_ghashIterator_getValue(&ghi);
+
+ /* don't link with parent */
+ if (bone->parent != ctrl->bone)
+ {
+ if (VecLenf(ctrl->bone->tail, bone->head) < 0.01)
+ {
+ ctrl->tail_mode = TL_HEAD;
+ ctrl->link_tail = bone;
+ break;
+ }
+ else if (VecLenf(ctrl->bone->tail, bone->tail) < 0.01)
+ {
+ ctrl->tail_mode = TL_TAIL;
+ ctrl->link_tail = bone;
+ break;
+ }
+ }
+ }
+
+ /* if we haven't found one yet, look in control bones */
+ if (ctrl->tail_mode == TL_NONE)
+ {
+ }
+ }
+ }
+
+}
+
+/*******************************************************************************************************/
+
+static void RIG_joinArcs(RigGraph *rg, RigNode *node, RigArc *joined_arc1, RigArc *joined_arc2)
+{
+ RigEdge *edge, *next_edge;
+
+ /* ignore cases where joint is at start or end */
+ if (joined_arc1->head == joined_arc2->head || joined_arc1->tail == joined_arc2->tail)
+ {
+ return;
+ }
+
+ /* swap arcs to make sure arc1 is before arc2 */
+ if (joined_arc1->head == joined_arc2->tail)
+ {
+ RigArc *tmp = joined_arc1;
+ joined_arc1 = joined_arc2;
+ joined_arc2 = tmp;
+ }
+
+ for (edge = joined_arc2->edges.first; edge; edge = next_edge)
+ {
+ next_edge = edge->next;
+
+ RIG_appendEdgeToArc(joined_arc1, edge);
+ }
+
+ joined_arc1->tail = joined_arc2->tail;
+
+ joined_arc2->edges.first = joined_arc2->edges.last = NULL;
+
+ BLI_removeArc((BGraph*)rg, (BArc*)joined_arc2);
+
+ BLI_removeNode((BGraph*)rg, (BNode*)node);
+}
+
+static void RIG_removeNormalNodes(RigGraph *rg)
+{
+ RigNode *node, *next_node;
+
+ for (node = rg->nodes.first; node; node = next_node)
+ {
+ next_node = node->next;
+
+ if (node->degree == 2)
+ {
+ RigArc *arc, *joined_arc1 = NULL, *joined_arc2 = NULL;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->head == node || arc->tail == node)
+ {
+ if (joined_arc1 == NULL)
+ {
+ joined_arc1 = arc;
+ }
+ else
+ {
+ joined_arc2 = arc;
+ break;
+ }
+ }
+ }
+
+ RIG_joinArcs(rg, node, joined_arc1, joined_arc2);
+ }
+ }
+}
+
+static void RIG_removeUneededOffsets(RigGraph *rg)
+{
+ RigArc *arc;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ RigEdge *first_edge, *last_edge;
+
+ first_edge = arc->edges.first;
+ last_edge = arc->edges.last;
+
+ if (first_edge->bone == NULL)
+ {
+ if (first_edge->bone == NULL && VecLenf(first_edge->tail, arc->head->p) <= 0.001)
+ {
+ BLI_remlink(&arc->edges, first_edge);
+ MEM_freeN(first_edge);
+ }
+ else if (arc->head->degree == 1)
+ {
+ RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, first_edge->tail, 0.001);
+
+ if (new_node)
+ {
+ BLI_remlink(&arc->edges, first_edge);
+ MEM_freeN(first_edge);
+ BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)new_node, (BNode*)arc->head);
+ }
+ else
+ {
+ RigEdge *next_edge = first_edge->next;
+
+ if (next_edge)
+ {
+ BLI_remlink(&arc->edges, first_edge);
+ MEM_freeN(first_edge);
+
+ VECCOPY(arc->head->p, next_edge->head);
+ }
+ }
+ }
+ else
+ {
+ /* check if all arc connected start with a null edge */
+ RigArc *other_arc;
+ for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next)
+ {
+ if (other_arc != arc)
+ {
+ RigEdge *test_edge;
+ if (other_arc->head == arc->head)
+ {
+ test_edge = other_arc->edges.first;
+
+ if (test_edge->bone != NULL)
+ {
+ break;
+ }
+ }
+ else if (other_arc->tail == arc->head)
+ {
+ test_edge = other_arc->edges.last;
+
+ if (test_edge->bone != NULL)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ if (other_arc == NULL)
+ {
+ RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, first_edge->tail, 0.001);
+
+ if (new_node)
+ {
+ /* remove null edge in other arcs too */
+ for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next)
+ {
+ if (other_arc != arc)
+ {
+ RigEdge *test_edge;
+ if (other_arc->head == arc->head)
+ {
+ BLI_replaceNodeInArc((BGraph*)rg, (BArc*)other_arc, (BNode*)new_node, (BNode*)other_arc->head);
+ test_edge = other_arc->edges.first;
+ BLI_remlink(&other_arc->edges, test_edge);
+ MEM_freeN(test_edge);
+ }
+ else if (other_arc->tail == arc->head)
+ {
+ BLI_replaceNodeInArc((BGraph*)rg, (BArc*)other_arc, (BNode*)new_node, (BNode*)other_arc->tail);
+ test_edge = other_arc->edges.last;
+ BLI_remlink(&other_arc->edges, test_edge);
+ MEM_freeN(test_edge);
+ }
+ }
+ }
+
+ BLI_remlink(&arc->edges, first_edge);
+ MEM_freeN(first_edge);
+ BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)new_node, (BNode*)arc->head);
+ }
+ else
+ {
+ RigEdge *next_edge = first_edge->next;
+
+ if (next_edge)
+ {
+ BLI_remlink(&arc->edges, first_edge);
+ MEM_freeN(first_edge);
+
+ VECCOPY(arc->head->p, next_edge->head);
+
+ /* remove null edge in other arcs too */
+ for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next)
+ {
+ if (other_arc != arc)
+ {
+ RigEdge *test_edge;
+ if (other_arc->head == arc->head)
+ {
+ test_edge = other_arc->edges.first;
+ BLI_remlink(&other_arc->edges, test_edge);
+ MEM_freeN(test_edge);
+ }
+ else if (other_arc->tail == arc->head)
+ {
+ test_edge = other_arc->edges.last;
+ BLI_remlink(&other_arc->edges, test_edge);
+ MEM_freeN(test_edge);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (last_edge->bone == NULL)
+ {
+ if (VecLenf(last_edge->head, arc->tail->p) <= 0.001)
+ {
+ BLI_remlink(&arc->edges, last_edge);
+ MEM_freeN(last_edge);
+ }
+ else if (arc->tail->degree == 1)
+ {
+ RigNode *new_node = (RigNode*)BLI_FindNodeByPosition((BGraph*)rg, last_edge->head, 0.001);
+
+ if (new_node)
+ {
+ RigEdge *previous_edge = last_edge->prev;
+
+ BLI_remlink(&arc->edges, last_edge);
+ MEM_freeN(last_edge);
+ BLI_replaceNodeInArc((BGraph*)rg, (BArc*)arc, (BNode*)new_node, (BNode*)arc->tail);
+
+ /* set previous angle to 0, since there's no following edges */
+ if (previous_edge)
+ {
+ previous_edge->angle = 0;
+ }
+ }
+ else
+ {
+ RigEdge *previous_edge = last_edge->prev;
+
+ if (previous_edge)
+ {
+ BLI_remlink(&arc->edges, last_edge);
+ MEM_freeN(last_edge);
+
+ VECCOPY(arc->tail->p, previous_edge->tail);
+ previous_edge->angle = 0;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node, int selected)
+{
+ EditBone *bone, *last_bone = root_bone;
+ RigArc *arc = NULL;
+ int contain_head = 0;
+
+ for(bone = root_bone; bone; bone = nextEditBoneChild(list, bone, 0))
+ {
+ int nb_children;
+
+ if (selected == 0 || (bone->flag & BONE_SELECTED))
+ {
+ if ((bone->flag & BONE_NO_DEFORM) == 0)
+ {
+ BLI_ghash_insert(rg->bones_map, bone->name, bone);
+
+ if (arc == NULL)
+ {
+ arc = newRigArc(rg);
+
+ if (starting_node == NULL)
+ {
+ starting_node = newRigNodeHead(rg, arc, root_bone->head);
+ }
+ else
+ {
+ addRigNodeHead(rg, arc, starting_node);
+ }
+ }
+
+ if (bone->parent && (bone->flag & BONE_CONNECTED) == 0)
+ {
+ RIG_addEdgeToArc(arc, bone->head, NULL);
+ }
+
+ RIG_addEdgeToArc(arc, bone->tail, bone);
+
+ last_bone = bone;
+
+ if (strcmp(bone->name, "head") == 0)
+ {
+ contain_head = 1;
+ }
+ }
+ else if ((bone->flag & BONE_EDITMODE_LOCKED) == 0) /* ignore locked bones */
+ {
+ RIG_addControlBone(rg, bone);
+ }
+ }
+
+ nb_children = countEditBoneChildren(list, bone);
+ if (nb_children > 1)
+ {
+ RigNode *end_node = NULL;
+ int i;
+
+ if (arc != NULL)
+ {
+ end_node = newRigNodeTail(rg, arc, bone->tail);
+ }
+ else
+ {
+ end_node = newRigNode(rg, bone->tail);
+ }
+
+ for (i = 0; i < nb_children; i++)
+ {
+ root_bone = nextEditBoneChild(list, bone, i);
+ RIG_arcFromBoneChain(rg, list, root_bone, end_node, selected);
+ }
+
+ /* arc ends here, break */
+ break;
+ }
+ }
+
+ /* If the loop exited without forking */
+ if (arc != NULL && bone == NULL)
+ {
+ newRigNodeTail(rg, arc, last_bone->tail);
+ }
+
+ if (contain_head)
+ {
+ rg->head = arc->tail;
+ }
+}
+
+/*******************************************************************************************************/
+static void RIG_findHead(RigGraph *rg)
+{
+ if (rg->head == NULL)
+ {
+ if (BLI_countlist(&rg->arcs) == 1)
+ {
+ RigArc *arc = rg->arcs.first;
+
+ rg->head = (RigNode*)arc->head;
+ }
+ else
+ {
+ RigArc *arc;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ RigEdge *edge = arc->edges.last;
+
+ if (edge->bone->flag & (BONE_TIPSEL|BONE_SELECTED))
+ {
+ rg->head = arc->tail;
+ break;
+ }
+ }
+ }
+
+ if (rg->head == NULL)
+ {
+ rg->head = rg->nodes.first;
+ }
+ }
+}
+
+/*******************************************************************************************************/
+
+void RIG_printNode(RigNode *node, char name[])
+{
+ printf("%s %p %i <%0.3f, %0.3f, %0.3f>\n", name, node, node->degree, node->p[0], node->p[1], node->p[2]);
+
+ if (node->symmetry_flag & SYM_TOPOLOGICAL)
+ {
+ if (node->symmetry_flag & SYM_AXIAL)
+ printf("Symmetry AXIAL\n");
+ else if (node->symmetry_flag & SYM_RADIAL)
+ printf("Symmetry RADIAL\n");
+
+ printvecf("symmetry axis", node->symmetry_axis);
+ }
+}
+
+void RIG_printArcBones(RigArc *arc)
+{
+ RigEdge *edge;
+
+ for (edge = arc->edges.first; edge; edge = edge->next)
+ {
+ if (edge->bone)
+ printf("%s ", edge->bone->name);
+ else
+ printf("---- ");
+ }
+ printf("\n");
+}
+
+void RIG_printCtrl(RigControl *ctrl, char *indent)
+{
+ char text[128];
+
+ printf("%sBone: %s\n", indent, ctrl->bone->name);
+ printf("%sLink: %s\n", indent, ctrl->link ? ctrl->link->name : "!NONE!");
+
+ sprintf(text, "%soffset", indent);
+ printvecf(text, ctrl->offset);
+
+ printf("%sFlag: %i\n", indent, ctrl->flag);
+}
+
+void RIG_printLinkedCtrl(RigGraph *rg, EditBone *bone, int tabs)
+{
+ RigControl *ctrl;
+ char indent[64];
+ char *s = indent;
+ int i;
+
+ for (i = 0; i < tabs; i++)
+ {
+ s[0] = '\t';
+ s++;
+ }
+ s[0] = 0;
+
+ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
+ {
+ if (ctrl->link == bone)
+ {
+ RIG_printCtrl(ctrl, indent);
+ RIG_printLinkedCtrl(rg, ctrl->bone, tabs + 1);
+ }
+ }
+}
+
+void RIG_printArc(RigGraph *rg, RigArc *arc)
+{
+ RigEdge *edge;
+
+ RIG_printNode((RigNode*)arc->head, "head");
+
+ for (edge = arc->edges.first; edge; edge = edge->next)
+ {
+ printf("\tinner joints %0.3f %0.3f %0.3f\n", edge->tail[0], edge->tail[1], edge->tail[2]);
+ printf("\t\tlength %f\n", edge->length);
+ printf("\t\tangle %f\n", edge->angle * 180 / M_PI);
+ if (edge->bone)
+ {
+ printf("\t\t%s\n", edge->bone->name);
+ RIG_printLinkedCtrl(rg, edge->bone, 3);
+ }
+ }
+ printf("symmetry level: %i flag: %i group %i\n", arc->symmetry_level, arc->symmetry_flag, arc->symmetry_group);
+
+ RIG_printNode((RigNode*)arc->tail, "tail");
+}
+
+void RIG_printGraph(RigGraph *rg)
+{
+ RigArc *arc;
+
+ printf("---- ARCS ----\n");
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ RIG_printArc(rg, arc);
+ printf("\n");
+ }
+
+ if (rg->head)
+ {
+ RIG_printNode(rg->head, "HEAD NODE:");
+ }
+ else
+ {
+ printf("HEAD NODE: NONE\n");
+ }
+}
+
+/*******************************************************************************************************/
+
+RigGraph *RIG_graphFromArmature(bContext *C, Object *ob, bArmature *arm)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ EditBone *ebone;
+ RigGraph *rg;
+
+ rg = newRigGraph();
+
+ if (obedit == ob)
+ {
+ bArmature *arm = obedit->data;
+ rg->editbones = arm->edbo;
+ }
+ else
+ {
+ rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones");
+ make_boneList(rg->editbones, &arm->bonebase, NULL);
+ rg->flag |= RIG_FREE_BONELIST;
+ }
+
+ rg->ob = ob;
+
+ /* Do the rotations */
+ for (ebone = rg->editbones->first; ebone; ebone=ebone->next){
+ if (ebone->parent == NULL)
+ {
+ RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 0);
+ }
+ }
+
+ BLI_removeDoubleNodes((BGraph*)rg, 0.001);
+
+ RIG_removeNormalNodes(rg);
+
+ RIG_removeUneededOffsets(rg);
+
+ BLI_buildAdjacencyList((BGraph*)rg);
+
+ RIG_findHead(rg);
+
+ BLI_markdownSymmetry((BGraph*)rg, (BNode*)rg->head, scene->toolsettings->skgen_symmetry_limit);
+
+ RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */
+
+ if (BLI_isGraphCyclic((BGraph*)rg))
+ {
+ printf("armature cyclic\n");
+ }
+
+ return rg;
+}
+
+RigGraph *armatureSelectedToGraph(bContext *C, Object *ob, bArmature *arm)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ EditBone *ebone;
+ RigGraph *rg;
+
+ rg = newRigGraph();
+
+ if (obedit == ob)
+ {
+ rg->editbones = arm->edbo;
+ }
+ else
+ {
+ rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones");
+ make_boneList(rg->editbones, &arm->bonebase, NULL);
+ rg->flag |= RIG_FREE_BONELIST;
+ }
+
+ rg->ob = ob;
+
+ /* Do the rotations */
+ for (ebone = rg->editbones->first; ebone; ebone=ebone->next){
+ if (ebone->parent == NULL)
+ {
+ RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 1);
+ }
+ }
+
+ BLI_removeDoubleNodes((BGraph*)rg, 0.001);
+
+ RIG_removeNormalNodes(rg);
+
+ RIG_removeUneededOffsets(rg);
+
+ BLI_buildAdjacencyList((BGraph*)rg);
+
+ RIG_findHead(rg);
+
+ BLI_markdownSymmetry((BGraph*)rg, (BNode*)rg->head, scene->toolsettings->skgen_symmetry_limit);
+
+ RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */
+
+ if (BLI_isGraphCyclic((BGraph*)rg))
+ {
+ printf("armature cyclic\n");
+ }
+
+ return rg;
+}
+/************************************ GENERATING *****************************************************/
+
+static EditBone *add_editbonetolist(char *name, ListBase *list)
+{
+ EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
+
+ BLI_strncpy(bone->name, name, 32);
+ unique_editbone_name(list, bone->name, NULL);
+
+ BLI_addtail(list, bone);
+
+ bone->flag |= BONE_TIPSEL;
+ bone->weight= 1.0F;
+ bone->dist= 0.25F;
+ bone->xwidth= 0.1;
+ bone->zwidth= 0.1;
+ bone->ease1= 1.0;
+ bone->ease2= 1.0;
+ bone->rad_head= 0.10;
+ bone->rad_tail= 0.05;
+ bone->segments= 1;
+ bone->layer= 1;//arm->layer;
+
+ return bone;
+}
+
+void generateMissingArcsFromNode(RigGraph *rigg, ReebNode *node, int multi_level_limit)
+{
+ while (node->multi_level > multi_level_limit && node->link_up)
+ {
+ node = node->link_up;
+ }
+
+ while (node->multi_level < multi_level_limit && node->link_down)
+ {
+ node = node->link_down;
+ }
+
+ if (node->multi_level == multi_level_limit)
+ {
+ int i;
+
+ for (i = 0; i < node->degree; i++)
+ {
+ ReebArc *earc = node->arcs[i];
+
+ if (earc->flag == ARC_FREE && earc->head == node)
+ {
+ ReebNode *other = BIF_otherNodeFromIndex(earc, node);
+
+ earc->flag = ARC_USED;
+
+ //generateBonesForArc(rigg, earc, node, other);
+ generateMissingArcsFromNode(rigg, other, multi_level_limit);
+ }
+ }
+ }
+}
+
+void generateMissingArcs(RigGraph *rigg)
+{
+ ReebGraph *reebg = rigg->link_mesh;
+ int multi_level_limit = 5;
+
+ for (reebg = rigg->link_mesh; reebg; reebg = reebg->link_up)
+ {
+ ReebArc *earc;
+
+ for (earc = reebg->arcs.first; earc; earc = earc->next)
+ {
+ if (earc->flag == ARC_USED)
+ {
+ generateMissingArcsFromNode(rigg, earc->head, multi_level_limit);
+ generateMissingArcsFromNode(rigg, earc->tail, multi_level_limit);
+ }
+ }
+ }
+}
+
+/************************************ RETARGETTING *****************************************************/
+
+static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float tail[3], float qrot[4], float resize);
+
+static void repositionTailControl(RigGraph *rigg, RigControl *ctrl);
+
+static void finalizeControl(RigGraph *rigg, RigControl *ctrl, float resize)
+{
+ if ((ctrl->flag & RIG_CTRL_DONE) == RIG_CTRL_DONE)
+ {
+ RigControl *ctrl_child;
+
+#if 0
+ printf("CTRL: %s LINK: %s", ctrl->bone->name, ctrl->link->name);
+
+ if (ctrl->link_tail)
+ {
+ printf(" TAIL: %s", ctrl->link_tail->name);
+ }
+
+ printf("\n");
+#endif
+
+ /* if there was a tail link: apply link, recalc resize factor and qrot */
+ if (ctrl->tail_mode != TL_NONE)
+ {
+ float *tail_vec = NULL;
+ float v1[3], v2[3], qtail[4];
+
+ if (ctrl->tail_mode == TL_TAIL)
+ {
+ tail_vec = ctrl->link_tail->tail;
+ }
+ else if (ctrl->tail_mode == TL_HEAD)
+ {
+ tail_vec = ctrl->link_tail->head;
+ }
+
+ VecSubf(v1, ctrl->bone->tail, ctrl->bone->head);
+ VecSubf(v2, tail_vec, ctrl->bone->head);
+
+ VECCOPY(ctrl->bone->tail, tail_vec);
+
+ RotationBetweenVectorsToQuat(qtail, v1, v2);
+ QuatMul(ctrl->qrot, qtail, ctrl->qrot);
+
+ resize = VecLength(v2) / VecLenf(ctrl->head, ctrl->tail);
+ }
+
+ ctrl->bone->roll = rollBoneByQuat(ctrl->bone, ctrl->up_axis, ctrl->qrot);
+
+ /* Cascade to connected control bones */
+ for (ctrl_child = rigg->controls.first; ctrl_child; ctrl_child = ctrl_child->next)
+ {
+ if (ctrl_child->link == ctrl->bone)
+ {
+ repositionControl(rigg, ctrl_child, ctrl->bone->head, ctrl->bone->tail, ctrl->qrot, resize);
+ }
+ if (ctrl_child->link_tail == ctrl->bone)
+ {
+ repositionTailControl(rigg, ctrl_child);
+ }
+ }
+ }
+}
+
+static void repositionTailControl(RigGraph *rigg, RigControl *ctrl)
+{
+ ctrl->flag |= RIG_CTRL_TAIL_DONE;
+
+ finalizeControl(rigg, ctrl, 1); /* resize will be recalculated anyway so we don't need it */
+}
+
+static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float tail[3], float qrot[4], float resize)
+{
+ float parent_offset[3], tail_offset[3];
+
+ VECCOPY(parent_offset, ctrl->offset);
+ VecMulf(parent_offset, resize);
+ QuatMulVecf(qrot, parent_offset);
+
+ VecAddf(ctrl->bone->head, head, parent_offset);
+
+ ctrl->flag |= RIG_CTRL_HEAD_DONE;
+
+ QUATCOPY(ctrl->qrot, qrot);
+
+ if (ctrl->tail_mode == TL_NONE)
+ {
+ VecSubf(tail_offset, ctrl->tail, ctrl->head);
+ VecMulf(tail_offset, resize);
+ QuatMulVecf(qrot, tail_offset);
+
+ VecAddf(ctrl->bone->tail, ctrl->bone->head, tail_offset);
+
+ ctrl->flag |= RIG_CTRL_TAIL_DONE;
+ }
+
+ finalizeControl(rigg, ctrl, resize);
+}
+
+static void repositionBone(bContext *C, RigGraph *rigg, RigEdge *edge, float vec0[3], float vec1[3], float up_axis[3])
+{
+ Scene *scene = CTX_data_scene(C);
+ EditBone *bone;
+ RigControl *ctrl;
+ float qrot[4], resize;
+ float v1[3], v2[3];
+ float l1, l2;
+
+ bone = edge->bone;
+
+ VecSubf(v1, edge->tail, edge->head);
+ VecSubf(v2, vec1, vec0);
+
+ l1 = Normalize(v1);
+ l2 = Normalize(v2);
+
+ resize = l2 / l1;
+
+ RotationBetweenVectorsToQuat(qrot, v1, v2);
+
+ VECCOPY(bone->head, vec0);
+ VECCOPY(bone->tail, vec1);
+
+ if (!VecIsNull(up_axis))
+ {
+ float qroll[4];
+
+ if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_VIEW)
+ {
+ bone->roll = rollBoneByQuatAligned(bone, edge->up_axis, qrot, qroll, up_axis);
+ }
+ else if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_JOINT)
+ {
+ bone->roll = rollBoneByQuatJoint(edge, edge->next, qrot, qroll);
+ }
+ else
+ {
+ QuatOne(qroll);
+ }
+
+ QuatMul(qrot, qroll, qrot);
+ }
+ else
+ {
+ bone->roll = rollBoneByQuat(bone, edge->up_axis, qrot);
+ }
+
+ for (ctrl = rigg->controls.first; ctrl; ctrl = ctrl->next)
+ {
+ if (ctrl->link == bone)
+ {
+ repositionControl(rigg, ctrl, vec0, vec1, qrot, resize);
+ }
+ if (ctrl->link_tail == bone)
+ {
+ repositionTailControl(rigg, ctrl);
+ }
+ }
+}
+
+static RetargetMode detectArcRetargetMode(RigArc *arc);
+static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start);
+
+
+static RetargetMode detectArcRetargetMode(RigArc *iarc)
+{
+ RetargetMode mode = RETARGET_AGGRESSIVE;
+ ReebArc *earc = iarc->link_mesh;
+ RigEdge *edge;
+ int large_angle = 0;
+ float avg_angle = 0;
+ float avg_length = 0;
+ int nb_edges = 0;
+
+
+ for (edge = iarc->edges.first; edge; edge = edge->next)
+ {
+ avg_angle += edge->angle;
+ nb_edges++;
+ }
+
+ avg_angle /= nb_edges - 1; /* -1 because last edge doesn't have an angle */
+
+ avg_length = iarc->length / nb_edges;
+
+
+ if (nb_edges > 2)
+ {
+ for (edge = iarc->edges.first; edge; edge = edge->next)
+ {
+ if (fabs(edge->angle - avg_angle) > M_PI / 6)
+ {
+ large_angle = 1;
+ }
+ }
+ }
+ else if (nb_edges == 2 && avg_angle > 0)
+ {
+ large_angle = 1;
+ }
+
+
+ if (large_angle == 0)
+ {
+ mode = RETARGET_LENGTH;
+ }
+
+ if (earc->bcount <= (iarc->count - 1))
+ {
+ mode = RETARGET_LENGTH;
+ }
+
+ mode = RETARGET_AGGRESSIVE;
+
+ return mode;
+}
+
+#ifndef USE_THREADS
+static void printMovesNeeded(int *positions, int nb_positions)
+{
+ int moves = 0;
+ int i;
+
+ for (i = 0; i < nb_positions; i++)
+ {
+ moves += positions[i] - (i + 1);
+ }
+
+ printf("%i moves needed\n", moves);
+}
+
+static void printPositions(int *positions, int nb_positions)
+{
+ int i;
+
+ for (i = 0; i < nb_positions; i++)
+ {
+ printf("%i ", positions[i]);
+ }
+ printf("\n");
+}
+#endif
+
+#define MAX_COST FLT_MAX /* FIX ME */
+
+static float costDistance(BArcIterator *iter, float *vec0, float *vec1, int i0, int i1, float distance_weight)
+{
+ EmbedBucket *bucket = NULL;
+ float max_dist = 0;
+ float v1[3], v2[3], c[3];
+ float v1_inpf;
+
+ if (distance_weight > 0)
+ {
+ VecSubf(v1, vec0, vec1);
+
+ v1_inpf = Inpf(v1, v1);
+
+ if (v1_inpf > 0)
+ {
+ int j;
+ for (j = i0 + 1; j < i1 - 1; j++)
+ {
+ float dist;
+
+ bucket = IT_peek(iter, j);
+
+ VecSubf(v2, bucket->p, vec1);
+
+ Crossf(c, v1, v2);
+
+ dist = Inpf(c, c) / v1_inpf;
+
+ max_dist = dist > max_dist ? dist : max_dist;
+ }
+
+ return distance_weight * max_dist;
+ }
+ else
+ {
+ return MAX_COST;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static float costAngle(float original_angle, float vec_first[3], float vec_second[3], float angle_weight)
+{
+ if (angle_weight > 0)
+ {
+ float current_angle;
+
+ if (!VecIsNull(vec_first) && !VecIsNull(vec_second))
+ {
+ current_angle = saacos(Inpf(vec_first, vec_second));
+
+ return angle_weight * fabs(current_angle - original_angle);
+ }
+ else
+ {
+ return angle_weight * M_PI;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static float costLength(float original_length, float current_length, float length_weight)
+{
+ if (current_length == 0)
+ {
+ return MAX_COST;
+ }
+ else
+ {
+ float length_ratio = fabs((current_length - original_length) / original_length);
+ return length_weight * length_ratio * length_ratio;
+ }
+}
+
+#if 0
+static float calcCostLengthDistance(BArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec1, float *vec2, int i1, int i2)
+{
+ float vec[3];
+ float length;
+
+ VecSubf(vec, vec2, vec1);
+ length = Normalize(vec);
+
+ return costLength(edge->length, length) + costDistance(iter, vec1, vec2, i1, i2);
+}
+#endif
+
+static float calcCostAngleLengthDistance(BArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec0, float *vec1, float *vec2, int i1, int i2, float angle_weight, float length_weight, float distance_weight)
+{
+ float vec_second[3], vec_first[3];
+ float length2;
+ float new_cost = 0;
+
+ VecSubf(vec_second, vec2, vec1);
+ length2 = Normalize(vec_second);
+
+
+ /* Angle cost */
+ if (edge->prev)
+ {
+ VecSubf(vec_first, vec1, vec0);
+ Normalize(vec_first);
+
+ new_cost += costAngle(edge->prev->angle, vec_first, vec_second, angle_weight);
+ }
+
+ /* Length cost */
+ new_cost += costLength(edge->length, length2, length_weight);
+
+ /* Distance cost */
+ new_cost += costDistance(iter, vec1, vec2, i1, i2, distance_weight);
+
+ return new_cost;
+}
+
+static int indexMemoNode(int nb_positions, int previous, int current, int joints_left)
+{
+ return joints_left * nb_positions * nb_positions + current * nb_positions + previous;
+}
+
+static void copyMemoPositions(int *positions, MemoNode *table, int nb_positions, int joints_left)
+{
+ int previous = 0, current = 0;
+ int i = 0;
+
+ for (i = 0; joints_left > 0; joints_left--, i++)
+ {
+ MemoNode *node;
+ node = table + indexMemoNode(nb_positions, previous, current, joints_left);
+
+ positions[i] = node->next;
+
+ previous = current;
+ current = node->next;
+ }
+}
+
+static MemoNode * solveJoints(MemoNode *table, BArcIterator *iter, float **vec_cache, int nb_joints, int nb_positions, int previous, int current, RigEdge *edge, int joints_left, float angle_weight, float length_weight, float distance_weight)
+{
+ MemoNode *node;
+ int index = indexMemoNode(nb_positions, previous, current, joints_left);
+
+ node = table + index;
+
+ if (node->weight != 0)
+ {
+ return node;
+ }
+ else if (joints_left == 0)
+ {
+ float *vec0 = vec_cache[previous];
+ float *vec1 = vec_cache[current];
+ float *vec2 = vec_cache[nb_positions + 1];
+
+ node->weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, iter->length, angle_weight, length_weight, distance_weight);
+
+ return node;
+ }
+ else
+ {
+ MemoNode *min_node = NULL;
+ float *vec0 = vec_cache[previous];
+ float *vec1 = vec_cache[current];
+ float min_weight;
+ int min_next;
+ int next;
+
+ for (next = current + 1; next <= nb_positions - (joints_left - 1); next++)
+ {
+ MemoNode *next_node;
+ float *vec2 = vec_cache[next];
+ float weight = 0;
+
+ /* ADD WEIGHT OF PREVIOUS - CURRENT - NEXT triple */
+ weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, next, angle_weight, length_weight, distance_weight);
+
+ if (weight >= MAX_COST)
+ {
+ continue;
+ }
+
+ /* add node weight */
+ next_node = solveJoints(table, iter, vec_cache, nb_joints, nb_positions, current, next, edge->next, joints_left - 1, angle_weight, length_weight, distance_weight);
+ weight += next_node->weight;
+
+ if (min_node == NULL || weight < min_weight)
+ {
+ min_weight = weight;
+ min_node = next_node;
+ min_next = next;
+ }
+ }
+
+ if (min_node)
+ {
+ node->weight = min_weight;
+ node->next = min_next;
+ return node;
+ }
+ else
+ {
+ node->weight = MAX_COST;
+ return node;
+ }
+ }
+
+}
+
+static int testFlipArc(RigArc *iarc, RigNode *inode_start)
+{
+ ReebArc *earc = iarc->link_mesh;
+ ReebNode *enode_start = BIF_NodeFromIndex(earc, inode_start->link_mesh);
+
+ /* no flip needed if both nodes are the same */
+ if ((enode_start == earc->head && inode_start == iarc->head) || (enode_start == earc->tail && inode_start == iarc->tail))
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
+{
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ RigEdge *edge;
+ EmbedBucket *bucket = NULL;
+ ReebNode *node_start, *node_end;
+ ReebArc *earc = iarc->link_mesh;
+ float angle_weight = 1.0; // GET FROM CONTEXT
+ float length_weight = 1.0;
+ float distance_weight = 1.0;
+ float min_cost = FLT_MAX;
+ float *vec0, *vec1;
+ int *best_positions;
+ int nb_edges = BLI_countlist(&iarc->edges);
+ int nb_joints = nb_edges - 1;
+ RetargetMethod method = METHOD_MEMOIZE;
+ int i;
+
+ if (nb_joints > earc->bcount)
+ {
+ printf("NOT ENOUGH BUCKETS!\n");
+ return;
+ }
+
+ best_positions = MEM_callocN(sizeof(int) * nb_joints, "Best positions");
+
+ if (testFlipArc(iarc, inode_start))
+ {
+ node_start = earc->tail;
+ node_end = earc->head;
+ }
+ else
+ {
+ node_start = earc->head;
+ node_end = earc->tail;
+ }
+
+ /* equal number of joints and potential position, just fill them in */
+ if (nb_joints == earc->bcount)
+ {
+ int i;
+
+ /* init with first values */
+ for (i = 0; i < nb_joints; i++)
+ {
+ best_positions[i] = i + 1;
+ }
+ }
+ if (method == METHOD_MEMOIZE)
+ {
+ int nb_positions = earc->bcount;
+ int nb_memo_nodes = nb_positions * nb_positions * (nb_joints + 1);
+ MemoNode *table = MEM_callocN(nb_memo_nodes * sizeof(MemoNode), "memoization table");
+ MemoNode *result;
+ float **positions_cache = MEM_callocN(sizeof(float*) * (nb_positions + 2), "positions cache");
+ int i;
+
+ positions_cache[0] = node_start->p;
+ positions_cache[nb_positions + 1] = node_end->p;
+
+ initArcIterator(iter, earc, node_start);
+
+ for (i = 1; i <= nb_positions; i++)
+ {
+ EmbedBucket *bucket = IT_peek(iter, i);
+ positions_cache[i] = bucket->p;
+ }
+
+ result = solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints, angle_weight, length_weight, distance_weight);
+
+ min_cost = result->weight;
+ copyMemoPositions(best_positions, table, earc->bcount, nb_joints);
+
+ MEM_freeN(table);
+ MEM_freeN(positions_cache);
+ }
+
+ vec0 = node_start->p;
+ initArcIterator(iter, earc, node_start);
+
+#ifndef USE_THREADS
+ printPositions(best_positions, nb_joints);
+ printMovesNeeded(best_positions, nb_joints);
+ printf("min_cost %f\n", min_cost);
+ printf("buckets: %i\n", earc->bcount);
+#endif
+
+ /* set joints to best position */
+ for (edge = iarc->edges.first, i = 0;
+ edge;
+ edge = edge->next, i++)
+ {
+ float *no = NULL;
+ if (i < nb_joints)
+ {
+ bucket = IT_peek(iter, best_positions[i]);
+ vec1 = bucket->p;
+ no = bucket->no;
+ }
+ else
+ {
+ vec1 = node_end->p;
+ no = node_end->no;
+ }
+
+ if (edge->bone)
+ {
+ repositionBone(C, rigg, edge, vec0, vec1, no);
+ }
+
+ vec0 = vec1;
+ }
+
+ MEM_freeN(best_positions);
+}
+
+static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
+{
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ ReebArc *earc = iarc->link_mesh;
+ ReebNode *node_start, *node_end;
+ RigEdge *edge;
+ EmbedBucket *bucket = NULL;
+ float embedding_length = 0;
+ float *vec0 = NULL;
+ float *vec1 = NULL;
+ float *previous_vec = NULL;
+
+
+ if (testFlipArc(iarc, inode_start))
+ {
+ node_start = (ReebNode*)earc->tail;
+ node_end = (ReebNode*)earc->head;
+ }
+ else
+ {
+ node_start = (ReebNode*)earc->head;
+ node_end = (ReebNode*)earc->tail;
+ }
+
+ initArcIterator(iter, earc, node_start);
+
+ bucket = IT_next(iter);
+
+ vec0 = node_start->p;
+
+ while (bucket != NULL)
+ {
+ vec1 = bucket->p;
+
+ embedding_length += VecLenf(vec0, vec1);
+
+ vec0 = vec1;
+ bucket = IT_next(iter);
+ }
+
+ embedding_length += VecLenf(node_end->p, vec1);
+
+ /* fit bones */
+ initArcIterator(iter, earc, node_start);
+
+ bucket = IT_next(iter);
+
+ vec0 = node_start->p;
+ previous_vec = vec0;
+ vec1 = bucket->p;
+
+ for (edge = iarc->edges.first; edge; edge = edge->next)
+ {
+ float new_bone_length = edge->length / iarc->length * embedding_length;
+ float *no = NULL;
+ float length = 0;
+
+ while (bucket && new_bone_length > length)
+ {
+ length += VecLenf(previous_vec, vec1);
+ bucket = IT_next(iter);
+ previous_vec = vec1;
+ vec1 = bucket->p;
+ no = bucket->no;
+ }
+
+ if (bucket == NULL)
+ {
+ vec1 = node_end->p;
+ no = node_end->no;
+ }
+
+ /* no need to move virtual edges (space between unconnected bones) */
+ if (edge->bone)
+ {
+ repositionBone(C, rigg, edge, vec0, vec1, no);
+ }
+
+ vec0 = vec1;
+ previous_vec = vec1;
+ }
+}
+
+static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start)
+{
+#ifdef USE_THREADS
+ RetargetParam *p = MEM_callocN(sizeof(RetargetParam), "RetargetParam");
+
+ p->rigg = rigg;
+ p->iarc = iarc;
+ p->inode_start = inode_start;
+ p->context = C;
+
+ BLI_insert_work(rigg->worker, p);
+#else
+ RetargetParam p;
+
+ p.rigg = rigg;
+ p.iarc = iarc;
+ p.inode_start = inode_start;
+ p.context = C;
+
+ exec_retargetArctoArc(&p);
+#endif
+}
+
+void *exec_retargetArctoArc(void *param)
+{
+ RetargetParam *p = (RetargetParam*)param;
+ RigGraph *rigg = p->rigg;
+ RigArc *iarc = p->iarc;
+ bContext *C = p->context;
+ RigNode *inode_start = p->inode_start;
+ ReebArc *earc = iarc->link_mesh;
+
+ if (BLI_countlist(&iarc->edges) == 1)
+ {
+ RigEdge *edge = iarc->edges.first;
+
+ if (testFlipArc(iarc, inode_start))
+ {
+ repositionBone(C, rigg, edge, earc->tail->p, earc->head->p, earc->head->no);
+ }
+ else
+ {
+ repositionBone(C, rigg, edge, earc->head->p, earc->tail->p, earc->tail->no);
+ }
+ }
+ else
+ {
+ RetargetMode mode = detectArcRetargetMode(iarc);
+
+ if (mode == RETARGET_AGGRESSIVE)
+ {
+ retargetArctoArcAggresive(C, rigg, iarc, inode_start);
+ }
+ else
+ {
+ retargetArctoArcLength(C, rigg, iarc, inode_start);
+ }
+ }
+
+#ifdef USE_THREADS
+ MEM_freeN(p);
+#endif
+
+ return NULL;
+}
+
+static void matchMultiResolutionNode(RigGraph *rigg, RigNode *inode, ReebNode *top_node)
+{
+ ReebNode *enode = top_node;
+ ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode);
+ int ishape, eshape;
+
+ ishape = BLI_subtreeShape((BGraph*)rigg, (BNode*)inode, NULL, 0) % SHAPE_LEVELS;
+ eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, NULL, 0) % SHAPE_LEVELS;
+
+ inode->link_mesh = enode;
+
+ while (ishape == eshape && enode->link_down)
+ {
+ inode->link_mesh = enode;
+
+ enode = enode->link_down;
+ reebg = BIF_graphForMultiNode(rigg->link_mesh, enode); /* replace with call to link_down once that exists */
+ eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, NULL, 0) % SHAPE_LEVELS;
+ }
+}
+
+static void markMultiResolutionChildArc(ReebNode *end_enode, ReebNode *enode)
+{
+ int i;
+
+ for(i = 0; i < enode->degree; i++)
+ {
+ ReebArc *earc = (ReebArc*)enode->arcs[i];
+
+ if (earc->flag == ARC_FREE)
+ {
+ earc->flag = ARC_TAKEN;
+
+ if (earc->tail->degree > 1 && earc->tail != end_enode)
+ {
+ markMultiResolutionChildArc(end_enode, earc->tail);
+ }
+ break;
+ }
+ }
+}
+
+static void markMultiResolutionArc(ReebArc *start_earc)
+{
+ if (start_earc->link_up)
+ {
+ ReebArc *earc;
+ for (earc = start_earc->link_up ; earc; earc = earc->link_up)
+ {
+ earc->flag = ARC_TAKEN;
+
+ if (earc->tail->index != start_earc->tail->index)
+ {
+ markMultiResolutionChildArc(earc->tail, earc->tail);
+ }
+ }
+ }
+}
+
+static void matchMultiResolutionArc(RigGraph *rigg, RigNode *start_node, RigArc *next_iarc, ReebArc *next_earc)
+{
+ ReebNode *enode = next_earc->head;
+ ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode);
+ int ishape, eshape;
+
+ ishape = BLI_subtreeShape((BGraph*)rigg, (BNode*)start_node, (BArc*)next_iarc, 1) % SHAPE_LEVELS;
+ eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, (BArc*)next_earc, 1) % SHAPE_LEVELS;
+
+ while (ishape != eshape && next_earc->link_up)
+ {
+ next_earc->flag = ARC_TAKEN; // mark previous as taken, to prevent backtrack on lower levels
+
+ next_earc = next_earc->link_up;
+ reebg = reebg->link_up;
+ enode = next_earc->head;
+ eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, (BArc*)next_earc, 1) % SHAPE_LEVELS;
+ }
+
+ next_earc->flag = ARC_USED;
+ next_iarc->link_mesh = next_earc;
+
+ /* mark all higher levels as taken too */
+ markMultiResolutionArc(next_earc);
+// while (next_earc->link_up)
+// {
+// next_earc = next_earc->link_up;
+// next_earc->flag = ARC_TAKEN;
+// }
+}
+
+static void matchMultiResolutionStartingNode(RigGraph *rigg, ReebGraph *reebg, RigNode *inode)
+{
+ ReebNode *enode;
+ int ishape, eshape;
+
+ enode = reebg->nodes.first;
+
+ ishape = BLI_subtreeShape((BGraph*)rigg, (BNode*)inode, NULL, 0) % SHAPE_LEVELS;
+ eshape = BLI_subtreeShape((BGraph*)rigg->link_mesh, (BNode*)enode, NULL, 0) % SHAPE_LEVELS;
+
+ while (ishape != eshape && reebg->link_up)
+ {
+ reebg = reebg->link_up;
+
+ enode = reebg->nodes.first;
+
+ eshape = BLI_subtreeShape((BGraph*)reebg, (BNode*)enode, NULL, 0) % SHAPE_LEVELS;
+ }
+
+ inode->link_mesh = enode;
+}
+
+static void findCorrespondingArc(RigGraph *rigg, RigArc *start_arc, RigNode *start_node, RigArc *next_iarc, int root)
+{
+ ReebNode *enode = start_node->link_mesh;
+ ReebArc *next_earc;
+ int symmetry_level = next_iarc->symmetry_level;
+ int symmetry_group = next_iarc->symmetry_group;
+ int symmetry_flag = next_iarc->symmetry_flag;
+ int i;
+
+ next_iarc->link_mesh = NULL;
+
+// if (root)
+// {
+// printf("-----------------------\n");
+// printf("MATCHING LIMB\n");
+// RIG_printArcBones(next_iarc);
+// }
+
+ for(i = 0; i < enode->degree; i++)
+ {
+ next_earc = (ReebArc*)enode->arcs[i];
+
+// if (next_earc->flag == ARC_FREE)
+// {
+// printf("candidate (level %i ?= %i) (flag %i ?= %i) (group %i ?= %i)\n",
+// symmetry_level, next_earc->symmetry_level,
+// symmetry_flag, next_earc->symmetry_flag,
+// symmetry_group, next_earc->symmetry_flag);
+// }
+
+ if (next_earc->flag == ARC_FREE &&
+ next_earc->symmetry_flag == symmetry_flag &&
+ next_earc->symmetry_group == symmetry_group &&
+ next_earc->symmetry_level == symmetry_level)
+ {
+// printf("CORRESPONDING ARC FOUND\n");
+// printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
+
+ matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc);
+ break;
+ }
+ }
+
+ /* not found, try at higher nodes (lower node might have filtered internal arcs, messing shape of tree */
+ if (next_iarc->link_mesh == NULL)
+ {
+// printf("NO CORRESPONDING ARC FOUND - GOING TO HIGHER LEVELS\n");
+
+ if (enode->link_up)
+ {
+ start_node->link_mesh = enode->link_up;
+ findCorrespondingArc(rigg, start_arc, start_node, next_iarc, 0);
+ }
+ }
+
+ /* still not found, print debug info */
+ if (root && next_iarc->link_mesh == NULL)
+ {
+ start_node->link_mesh = enode; /* linking back with root node */
+
+// printf("NO CORRESPONDING ARC FOUND\n");
+// RIG_printArcBones(next_iarc);
+//
+// printf("ON NODE %i, multilevel %i\n", enode->index, enode->multi_level);
+//
+// printf("LOOKING FOR\n");
+// printf("flag %i -- level %i -- flag %i -- group %i\n", ARC_FREE, symmetry_level, symmetry_flag, symmetry_group);
+//
+// printf("CANDIDATES\n");
+// for(i = 0; i < enode->degree; i++)
+// {
+// next_earc = (ReebArc*)enode->arcs[i];
+// printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
+// }
+
+ /* Emergency matching */
+ for(i = 0; i < enode->degree; i++)
+ {
+ next_earc = (ReebArc*)enode->arcs[i];
+
+ if (next_earc->flag == ARC_FREE && next_earc->symmetry_level == symmetry_level)
+ {
+// printf("USING: \n");
+// printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group);
+ matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc);
+ break;
+ }
+ }
+ }
+
+}
+
+static void retargetSubgraph(bContext *C, RigGraph *rigg, RigArc *start_arc, RigNode *start_node)
+{
+ RigNode *inode = start_node;
+ int i;
+
+ /* no start arc on first node */
+ if (start_arc)
+ {
+ ReebNode *enode = start_node->link_mesh;
+ ReebArc *earc = start_arc->link_mesh;
+
+ retargetArctoArc(C, rigg, start_arc, start_node);
+
+ enode = BIF_otherNodeFromIndex(earc, enode);
+ inode = (RigNode*)BLI_otherNode((BArc*)start_arc, (BNode*)inode);
+
+ /* match with lowest node with correct shape */
+ matchMultiResolutionNode(rigg, inode, enode);
+ }
+
+ for(i = 0; i < inode->degree; i++)
+ {
+ RigArc *next_iarc = (RigArc*)inode->arcs[i];
+
+ /* no back tracking */
+ if (next_iarc != start_arc)
+ {
+ findCorrespondingArc(rigg, start_arc, inode, next_iarc, 1);
+ if (next_iarc->link_mesh)
+ {
+ retargetSubgraph(C, rigg, next_iarc, inode);
+ }
+ }
+ }
+}
+
+static void finishRetarget(RigGraph *rigg)
+{
+#ifdef USE_THREADS
+ BLI_end_worker(rigg->worker);
+#endif
+}
+
+static void adjustGraphs(bContext *C, RigGraph *rigg)
+{
+ Scene *scene = CTX_data_scene(C);
+ bArmature *arm= rigg->ob->data;
+ RigArc *arc;
+
+ for (arc = rigg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->link_mesh)
+ {
+ retargetArctoArc(C, rigg, arc, arc->head);
+ }
+ }
+
+ finishRetarget(rigg);
+
+ /* Turn the list into an armature */
+ arm->edbo = rigg->editbones;
+ ED_armature_from_edit(scene, rigg->ob);
+
+ ED_undo_push("Retarget Skeleton");
+}
+
+static void retargetGraphs(bContext *C, RigGraph *rigg)
+{
+ Scene *scene = CTX_data_scene(C);
+ bArmature *arm= rigg->ob->data;
+ ReebGraph *reebg = rigg->link_mesh;
+ RigNode *inode;
+
+ /* flag all ReebArcs as free */
+ BIF_flagMultiArcs(reebg, ARC_FREE);
+
+ /* return to first level */
+ reebg = rigg->link_mesh;
+
+ inode = rigg->head;
+
+ matchMultiResolutionStartingNode(rigg, reebg, inode);
+
+ retargetSubgraph(C, rigg, NULL, inode);
+
+ //generateMissingArcs(rigg);
+
+ finishRetarget(rigg);
+
+ /* Turn the list into an armature */
+ arm->edbo = rigg->editbones;
+ ED_armature_from_edit(scene, rigg->ob);
+}
+
+char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index)
+{
+ RigArc *arc = BLI_findlink(&rg->arcs, arc_index);
+ RigEdge *iedge;
+
+ if (arc == NULL)
+ {
+ return "None";
+ }
+
+ if (bone_index == BLI_countlist(&arc->edges))
+ {
+ return "Last joint";
+ }
+
+ iedge = BLI_findlink(&arc->edges, bone_index);
+
+ if (iedge == NULL)
+ {
+ return "Done";
+ }
+
+ if (iedge->bone == NULL)
+ {
+ return "Bone offset";
+ }
+
+ return iedge->bone->name;
+}
+
+int RIG_nbJoints(RigGraph *rg)
+{
+ RigArc *arc;
+ int total = 0;
+
+ total += BLI_countlist(&rg->nodes);
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ total += BLI_countlist(&arc->edges) - 1; /* -1 because end nodes are already counted */
+ }
+
+ return total;
+}
+
+void BIF_freeRetarget()
+{
+ if (GLOBAL_RIGG)
+ {
+ RIG_freeRigGraph((BGraph*)GLOBAL_RIGG);
+ GLOBAL_RIGG = NULL;
+ }
+}
+
+void BIF_retargetArmature(bContext *C)
+{
+ ReebGraph *reebg;
+ double start_time, end_time;
+ double gstart_time, gend_time;
+ double reeb_time, rig_time, retarget_time, total_time;
+
+ gstart_time = start_time = PIL_check_seconds_timer();
+
+ reebg = BIF_ReebGraphMultiFromEditMesh(C);
+
+ end_time = PIL_check_seconds_timer();
+ reeb_time = end_time - start_time;
+
+ printf("Reeb Graph created\n");
+
+ CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
+ Object *ob = base->object;
+
+ if (ob->type==OB_ARMATURE)
+ {
+ RigGraph *rigg;
+ bArmature *arm;
+
+ arm = ob->data;
+
+ /* Put the armature into editmode */
+
+
+ start_time = PIL_check_seconds_timer();
+
+ rigg = RIG_graphFromArmature(C, ob, arm);
+
+ end_time = PIL_check_seconds_timer();
+ rig_time = end_time - start_time;
+
+ printf("Armature graph created\n");
+
+ //RIG_printGraph(rigg);
+
+ rigg->link_mesh = reebg;
+
+ printf("retargetting %s\n", ob->id.name);
+
+ start_time = PIL_check_seconds_timer();
+
+ retargetGraphs(C, rigg);
+
+ end_time = PIL_check_seconds_timer();
+ retarget_time = end_time - start_time;
+
+ BIF_freeRetarget();
+
+ GLOBAL_RIGG = rigg;
+
+ break; /* only one armature at a time */
+ }
+ }
+ CTX_DATA_END;
+
+
+ gend_time = PIL_check_seconds_timer();
+
+ total_time = gend_time - gstart_time;
+
+ printf("-----------\n");
+ printf("runtime: \t%.3f\n", total_time);
+ printf("reeb: \t\t%.3f (%.1f%%)\n", reeb_time, reeb_time / total_time * 100);
+ printf("rig: \t\t%.3f (%.1f%%)\n", rig_time, rig_time / total_time * 100);
+ printf("retarget: \t%.3f (%.1f%%)\n", retarget_time, retarget_time / total_time * 100);
+ printf("-----------\n");
+
+ ED_undo_push("Retarget Skeleton");
+
+ // XXX
+// allqueue(REDRAWVIEW3D, 0);
+}
+
+void BIF_retargetArc(bContext *C, ReebArc *earc, RigGraph *template_rigg)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ bArmature *armedit = obedit->data;
+ Object *ob;
+ RigGraph *rigg;
+ RigArc *iarc;
+ bArmature *arm;
+ char *side_string = scene->toolsettings->skgen_side_string;
+ char *num_string = scene->toolsettings->skgen_num_string;
+ int free_template = 0;
+
+ if (template_rigg)
+ {
+ ob = template_rigg->ob;
+ arm = ob->data;
+ }
+ else
+ {
+ free_template = 1;
+ ob = obedit;
+ arm = ob->data;
+ template_rigg = armatureSelectedToGraph(C, ob, arm);
+ }
+
+ if (template_rigg->arcs.first == NULL)
+ {
+// XXX
+// error("No Template and no deforming bones selected");
+ return;
+ }
+
+ rigg = cloneRigGraph(template_rigg, armedit->edbo, obedit, side_string, num_string);
+
+ iarc = rigg->arcs.first;
+
+ iarc->link_mesh = earc;
+ iarc->head->link_mesh = earc->head;
+ iarc->tail->link_mesh = earc->tail;
+
+ retargetArctoArc(C, rigg, iarc, iarc->head);
+
+ finishRetarget(rigg);
+
+ /* free template if it comes from the edit armature */
+ if (free_template)
+ {
+ RIG_freeRigGraph((BGraph*)template_rigg);
+ }
+ RIG_freeRigGraph((BGraph*)rigg);
+
+// XXX
+// allqueue(REDRAWVIEW3D, 0);
+}
+
+void BIF_adjustRetarget(bContext *C)
+{
+ if (GLOBAL_RIGG)
+ {
+ adjustGraphs(C, GLOBAL_RIGG);
+ }
+}
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
new file mode 100644
index 00000000000..5d0b954046c
--- /dev/null
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -0,0 +1,3368 @@
+/**
+ * $Id: $
+ *
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <string.h>
+#include <math.h>
+#include <float.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_listBase.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_armature_types.h"
+#include "DNA_userdef_types.h"
+
+#include "RNA_define.h"
+#include "RNA_access.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_graph.h"
+#include "BLI_ghash.h"
+
+#include "BKE_utildefines.h"
+#include "BKE_global.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_object.h"
+#include "BKE_anim.h"
+#include "BKE_context.h"
+
+#include "ED_view3d.h"
+#include "ED_screen.h"
+
+#include "BIF_gl.h"
+#include "UI_resources.h"
+//#include "BIF_screen.h"
+//#include "BIF_space.h"
+//#include "BIF_mywindow.h"
+#include "ED_armature.h"
+#include "armature_intern.h"
+//#include "BIF_sketch.h"
+#include "BIF_retarget.h"
+#include "BIF_generate.h"
+//#include "BIF_interface.h"
+
+#include "BIF_transform.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+//#include "blendef.h"
+//#include "mydevice.h"
+#include "reeb.h"
+
+typedef enum SK_PType
+{
+ PT_CONTINUOUS,
+ PT_EXACT,
+} SK_PType;
+
+typedef enum SK_PMode
+{
+ PT_SNAP,
+ PT_PROJECT,
+} SK_PMode;
+
+typedef struct SK_Point
+{
+ float p[3];
+ float no[3];
+ SK_PType type;
+ SK_PMode mode;
+} SK_Point;
+
+typedef struct SK_Stroke
+{
+ struct SK_Stroke *next, *prev;
+
+ SK_Point *points;
+ int nb_points;
+ int buf_size;
+ int selected;
+} SK_Stroke;
+
+#define SK_OVERDRAW_LIMIT 5
+
+typedef struct SK_Overdraw
+{
+ SK_Stroke *target;
+ int start, end;
+ int count;
+} SK_Overdraw;
+
+#define SK_Stroke_BUFFER_INIT_SIZE 20
+
+typedef struct SK_DrawData
+{
+ short mval[2];
+ short previous_mval[2];
+ SK_PType type;
+} SK_DrawData;
+
+typedef struct SK_Intersection
+{
+ struct SK_Intersection *next, *prev;
+ SK_Stroke *stroke;
+ int before;
+ int after;
+ int gesture_index;
+ float p[3];
+ float lambda; /* used for sorting intersection points */
+} SK_Intersection;
+
+typedef struct SK_Sketch
+{
+ ListBase strokes;
+ SK_Stroke *active_stroke;
+ SK_Stroke *gesture;
+ SK_Point next_point;
+ SK_Overdraw over;
+} SK_Sketch;
+
+typedef struct SK_StrokeIterator {
+ HeadFct head;
+ TailFct tail;
+ PeekFct peek;
+ NextFct next;
+ NextNFct nextN;
+ PreviousFct previous;
+ StoppedFct stopped;
+
+ float *p, *no;
+
+ int length;
+ int index;
+ /*********************************/
+ SK_Stroke *stroke;
+ int start;
+ int end;
+ int stride;
+} SK_StrokeIterator;
+
+typedef struct SK_Gesture {
+ SK_Stroke *stk;
+ SK_Stroke *segments;
+
+ ListBase intersections;
+ ListBase self_intersections;
+
+ int nb_self_intersections;
+ int nb_intersections;
+ int nb_segments;
+} SK_Gesture;
+
+typedef int (*GestureDetectFct)(bContext*, SK_Gesture*, SK_Sketch *);
+typedef void (*GestureApplyFct)(bContext*, SK_Gesture*, SK_Sketch *);
+
+typedef struct SK_GestureAction {
+ char name[64];
+ GestureDetectFct detect;
+ GestureApplyFct apply;
+} SK_GestureAction;
+
+SK_Sketch *GLOBAL_sketch = NULL;
+SK_Point boneSnap;
+int LAST_SNAP_POINT_VALID = 0;
+float LAST_SNAP_POINT[3];
+
+/******************** PROTOTYPES ******************************/
+
+void initStrokeIterator(BArcIterator *iter, SK_Stroke *stk, int start, int end);
+
+void sk_deleteSelectedStrokes(SK_Sketch *sketch);
+
+void sk_freeStroke(SK_Stroke *stk);
+void sk_freeSketch(SK_Sketch *sketch);
+
+SK_Point *sk_lastStrokePoint(SK_Stroke *stk);
+
+int sk_detectCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+int sk_detectConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+void sk_applyConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch);
+
+
+void sk_resetOverdraw(SK_Sketch *sketch);
+int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk);
+
+/******************** GESTURE ACTIONS ******************************/
+
+SK_GestureAction GESTURE_ACTIONS[] =
+ {
+ {"Cut", sk_detectCutGesture, sk_applyCutGesture},
+ {"Trim", sk_detectTrimGesture, sk_applyTrimGesture},
+ {"Command", sk_detectCommandGesture, sk_applyCommandGesture},
+ {"Delete", sk_detectDeleteGesture, sk_applyDeleteGesture},
+ {"Merge", sk_detectMergeGesture, sk_applyMergeGesture},
+ {"Reverse", sk_detectReverseGesture, sk_applyReverseGesture},
+ {"Convert", sk_detectConvertGesture, sk_applyConvertGesture},
+ {"", NULL, NULL}
+ };
+
+/******************** TEMPLATES UTILS *************************/
+
+char *TEMPLATES_MENU = NULL;
+int TEMPLATES_CURRENT = 0;
+GHash *TEMPLATES_HASH = NULL;
+RigGraph *TEMPLATE_RIGG = NULL;
+
+void BIF_makeListTemplates(bContext *C)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ Base *base;
+ int index = 0;
+
+ if (TEMPLATES_HASH != NULL)
+ {
+ BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
+ }
+
+ TEMPLATES_HASH = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
+ TEMPLATES_CURRENT = 0;
+
+ for ( base = FIRSTBASE; base; base = base->next )
+ {
+ Object *ob = base->object;
+
+ if (ob != obedit && ob->type == OB_ARMATURE)
+ {
+ index++;
+ BLI_ghash_insert(TEMPLATES_HASH, SET_INT_IN_POINTER(index), ob);
+
+ if (ob == scene->toolsettings->skgen_template)
+ {
+ TEMPLATES_CURRENT = index;
+ }
+ }
+ }
+}
+
+char *BIF_listTemplates(bContext *C)
+{
+ GHashIterator ghi;
+ char menu_header[] = "Template%t|None%x0|";
+ char *p;
+
+ if (TEMPLATES_MENU != NULL)
+ {
+ MEM_freeN(TEMPLATES_MENU);
+ }
+
+ TEMPLATES_MENU = MEM_callocN(sizeof(char) * (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30), "skeleton template menu");
+
+ p = TEMPLATES_MENU;
+
+ p += sprintf(TEMPLATES_MENU, "%s", menu_header);
+
+ BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
+
+ while (!BLI_ghashIterator_isDone(&ghi))
+ {
+ Object *ob = BLI_ghashIterator_getValue(&ghi);
+ int key = (int)BLI_ghashIterator_getKey(&ghi);
+
+ p += sprintf(p, "|%s%%x%i", ob->id.name+2, key);
+
+ BLI_ghashIterator_step(&ghi);
+ }
+
+ return TEMPLATES_MENU;
+}
+
+int BIF_currentTemplate(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ if (TEMPLATES_CURRENT == 0 && scene->toolsettings->skgen_template != NULL)
+ {
+ GHashIterator ghi;
+ BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
+
+ while (!BLI_ghashIterator_isDone(&ghi))
+ {
+ Object *ob = BLI_ghashIterator_getValue(&ghi);
+ int key = (int)BLI_ghashIterator_getKey(&ghi);
+
+ if (ob == scene->toolsettings->skgen_template)
+ {
+ TEMPLATES_CURRENT = key;
+ break;
+ }
+
+ BLI_ghashIterator_step(&ghi);
+ }
+ }
+
+ return TEMPLATES_CURRENT;
+}
+
+RigGraph* sk_makeTemplateGraph(bContext *C, Object *ob)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ if (ob == obedit)
+ {
+ return NULL;
+ }
+
+ if (ob != NULL)
+ {
+ if (TEMPLATE_RIGG && TEMPLATE_RIGG->ob != ob)
+ {
+ RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG);
+ TEMPLATE_RIGG = NULL;
+ }
+
+ if (TEMPLATE_RIGG == NULL)
+ {
+ bArmature *arm;
+
+ arm = ob->data;
+
+ TEMPLATE_RIGG = RIG_graphFromArmature(C, ob, arm);
+ }
+ }
+
+ return TEMPLATE_RIGG;
+}
+
+int BIF_nbJointsTemplate(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ RigGraph *rg = sk_makeTemplateGraph(C, scene->toolsettings->skgen_template);
+
+ if (rg)
+ {
+ return RIG_nbJoints(rg);
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+char * BIF_nameBoneTemplate(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ SK_Sketch *stk = GLOBAL_sketch;
+ RigGraph *rg;
+ int index = 0;
+
+ if (stk && stk->active_stroke != NULL)
+ {
+ index = stk->active_stroke->nb_points;
+ }
+
+ rg = sk_makeTemplateGraph(C, scene->toolsettings->skgen_template);
+
+ if (rg == NULL)
+ {
+ return "";
+ }
+
+ return RIG_nameBone(rg, 0, index);
+}
+
+void BIF_freeTemplates(bContext *C)
+{
+ if (TEMPLATES_MENU != NULL)
+ {
+ MEM_freeN(TEMPLATES_MENU);
+ TEMPLATES_MENU = NULL;
+ }
+
+ if (TEMPLATES_HASH != NULL)
+ {
+ BLI_ghash_free(TEMPLATES_HASH, NULL, NULL);
+ TEMPLATES_HASH = NULL;
+ }
+
+ if (TEMPLATE_RIGG != NULL)
+ {
+ RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG);
+ TEMPLATE_RIGG = NULL;
+ }
+}
+
+void BIF_setTemplate(bContext *C, int index)
+{
+ Scene *scene = CTX_data_scene(C);
+ if (index > 0)
+ {
+ scene->toolsettings->skgen_template = BLI_ghash_lookup(TEMPLATES_HASH, SET_INT_IN_POINTER(index));
+ }
+ else
+ {
+ scene->toolsettings->skgen_template = NULL;
+
+ if (TEMPLATE_RIGG != NULL)
+ {
+ RIG_freeRigGraph((BGraph*)TEMPLATE_RIGG);
+ }
+ TEMPLATE_RIGG = NULL;
+ }
+}
+
+/*********************** CONVERSION ***************************/
+
+void sk_autoname(bContext *C, ReebArc *arc)
+{
+ Scene *scene = CTX_data_scene(C);
+ if (scene->toolsettings->skgen_retarget_options & SK_RETARGET_AUTONAME)
+ {
+ if (arc == NULL)
+ {
+ char *num = scene->toolsettings->skgen_num_string;
+ int i = atoi(num);
+ i++;
+ BLI_snprintf(num, 8, "%i", i);
+ }
+ else
+ {
+ char *side = scene->toolsettings->skgen_side_string;
+ int valid = 0;
+ int caps = 0;
+
+ if (BLI_streq(side, ""))
+ {
+ valid = 1;
+ }
+ else if (BLI_streq(side, "R") || BLI_streq(side, "L"))
+ {
+ valid = 1;
+ caps = 1;
+ }
+ else if (BLI_streq(side, "r") || BLI_streq(side, "l"))
+ {
+ valid = 1;
+ caps = 0;
+ }
+
+ if (valid)
+ {
+ if (arc->head->p[0] < 0)
+ {
+ BLI_snprintf(side, 8, caps?"R":"r");
+ }
+ else
+ {
+ BLI_snprintf(side, 8, caps?"L":"l");
+ }
+ }
+ }
+ }
+}
+
+ReebNode *sk_pointToNode(SK_Point *pt, float imat[][4], float tmat[][3])
+{
+ ReebNode *node;
+
+ node = MEM_callocN(sizeof(ReebNode), "reeb node");
+ VECCOPY(node->p, pt->p);
+ Mat4MulVecfl(imat, node->p);
+
+ VECCOPY(node->no, pt->no);
+ Mat3MulVecfl(tmat, node->no);
+
+ return node;
+}
+
+ReebArc *sk_strokeToArc(SK_Stroke *stk, float imat[][4], float tmat[][3])
+{
+ ReebArc *arc;
+ int i;
+
+ arc = MEM_callocN(sizeof(ReebArc), "reeb arc");
+ arc->head = sk_pointToNode(stk->points, imat, tmat);
+ arc->tail = sk_pointToNode(sk_lastStrokePoint(stk), imat, tmat);
+
+ arc->bcount = stk->nb_points - 2; /* first and last are nodes, don't count */
+ arc->buckets = MEM_callocN(sizeof(EmbedBucket) * arc->bcount, "Buckets");
+
+ for (i = 0; i < arc->bcount; i++)
+ {
+ VECCOPY(arc->buckets[i].p, stk->points[i + 1].p);
+ Mat4MulVecfl(imat, arc->buckets[i].p);
+
+ VECCOPY(arc->buckets[i].no, stk->points[i + 1].no);
+ Mat3MulVecfl(tmat, arc->buckets[i].no);
+ }
+
+ return arc;
+}
+
+void sk_retargetStroke(bContext *C, SK_Stroke *stk)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ float imat[4][4];
+ float tmat[3][3];
+ ReebArc *arc;
+ RigGraph *rg;
+
+ Mat4Invert(imat, obedit->obmat);
+
+ Mat3CpyMat4(tmat, obedit->obmat);
+ Mat3Transp(tmat);
+
+ arc = sk_strokeToArc(stk, imat, tmat);
+
+ sk_autoname(C, arc);
+
+ rg = sk_makeTemplateGraph(C, scene->toolsettings->skgen_template);
+
+ BIF_retargetArc(C, arc, rg);
+
+ sk_autoname(C, NULL);
+
+ MEM_freeN(arc->head);
+ MEM_freeN(arc->tail);
+ REEB_freeArc((BArc*)arc);
+}
+
+/**************************************************************/
+
+void sk_freeSketch(SK_Sketch *sketch)
+{
+ SK_Stroke *stk, *next;
+
+ for (stk = sketch->strokes.first; stk; stk = next)
+ {
+ next = stk->next;
+
+ sk_freeStroke(stk);
+ }
+
+ MEM_freeN(sketch);
+}
+
+SK_Sketch* sk_createSketch()
+{
+ SK_Sketch *sketch;
+
+ sketch = MEM_callocN(sizeof(SK_Sketch), "SK_Sketch");
+
+ sketch->active_stroke = NULL;
+ sketch->gesture = NULL;
+
+ sketch->strokes.first = NULL;
+ sketch->strokes.last = NULL;
+
+ return sketch;
+}
+
+void sk_initPoint(bContext *C, SK_Point *pt)
+{
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+
+ VECCOPY(pt->no, rv3d->viewinv[2]);
+ Normalize(pt->no);
+ /* more init code here */
+}
+
+void sk_copyPoint(SK_Point *dst, SK_Point *src)
+{
+ memcpy(dst, src, sizeof(SK_Point));
+}
+
+void sk_allocStrokeBuffer(SK_Stroke *stk)
+{
+ stk->points = MEM_callocN(sizeof(SK_Point) * stk->buf_size, "SK_Point buffer");
+}
+
+void sk_freeStroke(SK_Stroke *stk)
+{
+ MEM_freeN(stk->points);
+ MEM_freeN(stk);
+}
+
+SK_Stroke* sk_createStroke()
+{
+ SK_Stroke *stk;
+
+ stk = MEM_callocN(sizeof(SK_Stroke), "SK_Stroke");
+
+ stk->selected = 0;
+ stk->nb_points = 0;
+ stk->buf_size = SK_Stroke_BUFFER_INIT_SIZE;
+
+ sk_allocStrokeBuffer(stk);
+
+ return stk;
+}
+
+void sk_shrinkStrokeBuffer(SK_Stroke *stk)
+{
+ if (stk->nb_points < stk->buf_size)
+ {
+ SK_Point *old_points = stk->points;
+
+ stk->buf_size = stk->nb_points;
+
+ sk_allocStrokeBuffer(stk);
+
+ memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
+
+ MEM_freeN(old_points);
+ }
+}
+
+void sk_growStrokeBuffer(SK_Stroke *stk)
+{
+ if (stk->nb_points == stk->buf_size)
+ {
+ SK_Point *old_points = stk->points;
+
+ stk->buf_size *= 2;
+
+ sk_allocStrokeBuffer(stk);
+
+ memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
+
+ MEM_freeN(old_points);
+ }
+}
+
+void sk_growStrokeBufferN(SK_Stroke *stk, int n)
+{
+ if (stk->nb_points + n > stk->buf_size)
+ {
+ SK_Point *old_points = stk->points;
+
+ while (stk->nb_points + n > stk->buf_size)
+ {
+ stk->buf_size *= 2;
+ }
+
+ sk_allocStrokeBuffer(stk);
+
+ memcpy(stk->points, old_points, sizeof(SK_Point) * stk->nb_points);
+
+ MEM_freeN(old_points);
+ }
+}
+
+
+void sk_replaceStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
+{
+ memcpy(stk->points + n, pt, sizeof(SK_Point));
+}
+
+void sk_insertStrokePoint(SK_Stroke *stk, SK_Point *pt, int n)
+{
+ int size = stk->nb_points - n;
+
+ sk_growStrokeBuffer(stk);
+
+ memmove(stk->points + n + 1, stk->points + n, size * sizeof(SK_Point));
+
+ memcpy(stk->points + n, pt, sizeof(SK_Point));
+
+ stk->nb_points++;
+}
+
+void sk_appendStrokePoint(SK_Stroke *stk, SK_Point *pt)
+{
+ sk_growStrokeBuffer(stk);
+
+ memcpy(stk->points + stk->nb_points, pt, sizeof(SK_Point));
+
+ stk->nb_points++;
+}
+
+void sk_insertStrokePoints(SK_Stroke *stk, SK_Point *pts, int len, int start, int end)
+{
+ int size = end - start + 1;
+
+ sk_growStrokeBufferN(stk, len - size);
+
+ if (len != size)
+ {
+ int tail_size = stk->nb_points - end + 1;
+
+ memmove(stk->points + start + len, stk->points + end + 1, tail_size * sizeof(SK_Point));
+ }
+
+ memcpy(stk->points + start, pts, len * sizeof(SK_Point));
+
+ stk->nb_points += len - size;
+}
+
+void sk_trimStroke(SK_Stroke *stk, int start, int end)
+{
+ int size = end - start + 1;
+
+ if (start > 0)
+ {
+ memmove(stk->points, stk->points + start, size * sizeof(SK_Point));
+ }
+
+ stk->nb_points = size;
+}
+
+void sk_straightenStroke(SK_Stroke *stk, int start, int end, float p_start[3], float p_end[3])
+{
+ SK_Point pt1, pt2;
+ SK_Point *prev, *next;
+ float delta_p[3];
+ int i, total;
+
+ total = end - start;
+
+ VecSubf(delta_p, p_end, p_start);
+
+ prev = stk->points + start;
+ next = stk->points + end;
+
+ VECCOPY(pt1.p, p_start);
+ VECCOPY(pt1.no, prev->no);
+ pt1.mode = prev->mode;
+ pt1.type = prev->type;
+
+ VECCOPY(pt2.p, p_end);
+ VECCOPY(pt2.no, next->no);
+ pt2.mode = next->mode;
+ pt2.type = next->type;
+
+ sk_insertStrokePoint(stk, &pt1, start + 1); /* insert after start */
+ sk_insertStrokePoint(stk, &pt2, end + 1); /* insert before end (since end was pushed back already) */
+
+ for (i = 1; i < total; i++)
+ {
+ float delta = (float)i / (float)total;
+ float *p = stk->points[start + 1 + i].p;
+
+ VECCOPY(p, delta_p);
+ VecMulf(p, delta);
+ VecAddf(p, p, p_start);
+ }
+}
+
+void sk_polygonizeStroke(SK_Stroke *stk, int start, int end)
+{
+ int offset;
+ int i;
+
+ /* find first exact points outside of range */
+ for (;start > 0; start--)
+ {
+ if (stk->points[start].type == PT_EXACT)
+ {
+ break;
+ }
+ }
+
+ for (;end < stk->nb_points - 1; end++)
+ {
+ if (stk->points[end].type == PT_EXACT)
+ {
+ break;
+ }
+ }
+
+ offset = start + 1;
+
+ for (i = start + 1; i < end; i++)
+ {
+ if (stk->points[i].type == PT_EXACT)
+ {
+ if (offset != i)
+ {
+ memcpy(stk->points + offset, stk->points + i, sizeof(SK_Point));
+ }
+
+ offset++;
+ }
+ }
+
+ /* some points were removes, move end of array */
+ if (offset < end)
+ {
+ int size = stk->nb_points - end;
+ memmove(stk->points + offset, stk->points + end, size * sizeof(SK_Point));
+ stk->nb_points = offset + size;
+ }
+}
+
+void sk_flattenStroke(SK_Stroke *stk, int start, int end)
+{
+ float normal[3], distance[3];
+ float limit;
+ int i, total;
+
+ total = end - start + 1;
+
+ VECCOPY(normal, stk->points[start].no);
+
+ VecSubf(distance, stk->points[end].p, stk->points[start].p);
+ Projf(normal, distance, normal);
+ limit = Normalize(normal);
+
+ for (i = 1; i < total - 1; i++)
+ {
+ float d = limit * i / total;
+ float offset[3];
+ float *p = stk->points[start + i].p;
+
+ VecSubf(distance, p, stk->points[start].p);
+ Projf(distance, distance, normal);
+
+ VECCOPY(offset, normal);
+ VecMulf(offset, d);
+
+ VecSubf(p, p, distance);
+ VecAddf(p, p, offset);
+ }
+}
+
+void sk_removeStroke(SK_Sketch *sketch, SK_Stroke *stk)
+{
+ if (sketch->active_stroke == stk)
+ {
+ sketch->active_stroke = NULL;
+ }
+
+ BLI_remlink(&sketch->strokes, stk);
+ sk_freeStroke(stk);
+}
+
+void sk_reverseStroke(SK_Stroke *stk)
+{
+ SK_Point *old_points = stk->points;
+ int i = 0;
+
+ sk_allocStrokeBuffer(stk);
+
+ for (i = 0; i < stk->nb_points; i++)
+ {
+ sk_copyPoint(stk->points + i, old_points + stk->nb_points - 1 - i);
+ }
+
+ MEM_freeN(old_points);
+}
+
+
+void sk_cancelStroke(SK_Sketch *sketch)
+{
+ if (sketch->active_stroke != NULL)
+ {
+ sk_resetOverdraw(sketch);
+ sk_removeStroke(sketch, sketch->active_stroke);
+ }
+}
+
+/* Apply reverse Chaikin filter to simplify the polyline
+ * */
+void sk_filterStroke(SK_Stroke *stk, int start, int end)
+{
+ SK_Point *old_points = stk->points;
+ int nb_points = stk->nb_points;
+ int i, j;
+
+ return;
+
+ if (start == -1)
+ {
+ start = 0;
+ end = stk->nb_points - 1;
+ }
+
+ sk_allocStrokeBuffer(stk);
+ stk->nb_points = 0;
+
+ /* adding points before range */
+ for (i = 0; i < start; i++)
+ {
+ sk_appendStrokePoint(stk, old_points + i);
+ }
+
+ for (i = start, j = start; i <= end; i++)
+ {
+ if (i - j == 3)
+ {
+ SK_Point pt;
+ float vec[3];
+
+ sk_copyPoint(&pt, &old_points[j+1]);
+
+ pt.p[0] = 0;
+ pt.p[1] = 0;
+ pt.p[2] = 0;
+
+ VECCOPY(vec, old_points[j].p);
+ VecMulf(vec, -0.25);
+ VecAddf(pt.p, pt.p, vec);
+
+ VECCOPY(vec, old_points[j+1].p);
+ VecMulf(vec, 0.75);
+ VecAddf(pt.p, pt.p, vec);
+
+ VECCOPY(vec, old_points[j+2].p);
+ VecMulf(vec, 0.75);
+ VecAddf(pt.p, pt.p, vec);
+
+ VECCOPY(vec, old_points[j+3].p);
+ VecMulf(vec, -0.25);
+ VecAddf(pt.p, pt.p, vec);
+
+ sk_appendStrokePoint(stk, &pt);
+
+ j += 2;
+ }
+
+ /* this might be uneeded when filtering last continuous stroke */
+ if (old_points[i].type == PT_EXACT)
+ {
+ sk_appendStrokePoint(stk, old_points + i);
+ j = i;
+ }
+ }
+
+ /* adding points after range */
+ for (i = end + 1; i < nb_points; i++)
+ {
+ sk_appendStrokePoint(stk, old_points + i);
+ }
+
+ MEM_freeN(old_points);
+
+ sk_shrinkStrokeBuffer(stk);
+}
+
+void sk_filterLastContinuousStroke(SK_Stroke *stk)
+{
+ int start, end;
+
+ end = stk->nb_points -1;
+
+ for (start = end - 1; start > 0 && stk->points[start].type == PT_CONTINUOUS; start--)
+ {
+ /* nothing to do here*/
+ }
+
+ if (end - start > 1)
+ {
+ sk_filterStroke(stk, start, end);
+ }
+}
+
+SK_Point *sk_lastStrokePoint(SK_Stroke *stk)
+{
+ SK_Point *pt = NULL;
+
+ if (stk->nb_points > 0)
+ {
+ pt = stk->points + (stk->nb_points - 1);
+ }
+
+ return pt;
+}
+
+void sk_drawStroke(SK_Stroke *stk, int id, float color[3], int start, int end)
+{
+ float rgb[3];
+ int i;
+
+ if (id != -1)
+ {
+ glLoadName(id);
+
+ glBegin(GL_LINE_STRIP);
+
+ for (i = 0; i < stk->nb_points; i++)
+ {
+ glVertex3fv(stk->points[i].p);
+ }
+
+ glEnd();
+
+ }
+ else
+ {
+ float d_rgb[3] = {1, 1, 1};
+
+ VECCOPY(rgb, color);
+ VecSubf(d_rgb, d_rgb, rgb);
+ VecMulf(d_rgb, 1.0f / (float)stk->nb_points);
+
+ glBegin(GL_LINE_STRIP);
+
+ for (i = 0; i < stk->nb_points; i++)
+ {
+ if (i >= start && i <= end)
+ {
+ glColor3f(0.3, 0.3, 0.3);
+ }
+ else
+ {
+ glColor3fv(rgb);
+ }
+ glVertex3fv(stk->points[i].p);
+ VecAddf(rgb, rgb, d_rgb);
+ }
+
+ glEnd();
+
+ glColor3f(0, 0, 0);
+ glBegin(GL_POINTS);
+
+ for (i = 0; i < stk->nb_points; i++)
+ {
+ if (stk->points[i].type == PT_EXACT)
+ {
+ glVertex3fv(stk->points[i].p);
+ }
+ }
+
+ glEnd();
+ }
+
+// glColor3f(1, 1, 1);
+// glBegin(GL_POINTS);
+//
+// for (i = 0; i < stk->nb_points; i++)
+// {
+// if (stk->points[i].type == PT_CONTINUOUS)
+// {
+// glVertex3fv(stk->points[i].p);
+// }
+// }
+//
+// glEnd();
+}
+
+void drawSubdividedStrokeBy(ToolSettings *toolsettings, BArcIterator *iter, NextSubdivisionFunc next_subdividion)
+{
+ float head[3], tail[3];
+ int bone_start = 0;
+ int end = iter->length;
+ int index;
+
+ iter->head(iter);
+ VECCOPY(head, iter->p);
+
+ glColor3f(0, 1, 0);
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) * 2);
+ glBegin(GL_POINTS);
+
+ index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
+ while (index != -1)
+ {
+ glVertex3fv(tail);
+
+ VECCOPY(head, tail);
+ bone_start = index; // start next bone from current index
+
+ index = next_subdividion(toolsettings, iter, bone_start, end, head, tail);
+ }
+
+ glEnd();
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+}
+
+void sk_drawStrokeSubdivision(ToolSettings *toolsettings, SK_Stroke *stk)
+{
+ int head_index = -1;
+ int i;
+
+ if (toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
+ {
+ return;
+ }
+
+
+ for (i = 0; i < stk->nb_points; i++)
+ {
+ SK_Point *pt = stk->points + i;
+
+ if (pt->type == PT_EXACT || i == stk->nb_points - 1) /* stop on exact or on last point */
+ {
+ if (head_index == -1)
+ {
+ head_index = i;
+ }
+ else
+ {
+ if (i - head_index > 1)
+ {
+ SK_StrokeIterator sk_iter;
+ BArcIterator *iter = (BArcIterator*)&sk_iter;
+
+ initStrokeIterator(iter, stk, head_index, i);
+
+ if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE)
+ {
+ drawSubdividedStrokeBy(toolsettings, iter, nextAdaptativeSubdivision);
+ }
+ else if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
+ {
+ drawSubdividedStrokeBy(toolsettings, iter, nextLengthSubdivision);
+ }
+ else if (toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
+ {
+ drawSubdividedStrokeBy(toolsettings, iter, nextFixedSubdivision);
+ }
+
+ }
+
+ head_index = i;
+ }
+ }
+ }
+}
+
+SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, short mval[2], int *dist, int *index, int all_pts)
+{
+ ARegion *ar = CTX_wm_region(C);
+ SK_Point *pt = NULL;
+ int i;
+
+ for (i = 0; i < stk->nb_points; i++)
+ {
+ if (all_pts || stk->points[i].type == PT_EXACT)
+ {
+ short pval[2];
+ int pdist;
+
+ project_short_noclip(ar, stk->points[i].p, pval);
+
+ pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
+
+ if (pdist < *dist)
+ {
+ *dist = pdist;
+ pt = stk->points + i;
+
+ if (index != NULL)
+ {
+ *index = i;
+ }
+ }
+ }
+ }
+
+ return pt;
+}
+
+SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, short mval[2], int *dist)
+{
+ ARegion *ar = CTX_wm_region(C);
+ SK_Point *pt = NULL;
+ EditBone *bone;
+
+ for (bone = ebones->first; bone; bone = bone->next)
+ {
+ float vec[3];
+ short pval[2];
+ int pdist;
+
+ if ((bone->flag & BONE_CONNECTED) == 0)
+ {
+ VECCOPY(vec, bone->head);
+ Mat4MulVecfl(ob->obmat, vec);
+ project_short_noclip(ar, vec, pval);
+
+ pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
+
+ if (pdist < *dist)
+ {
+ *dist = pdist;
+ pt = &boneSnap;
+ VECCOPY(pt->p, vec);
+ pt->type = PT_EXACT;
+ }
+ }
+
+
+ VECCOPY(vec, bone->tail);
+ Mat4MulVecfl(ob->obmat, vec);
+ project_short_noclip(ar, vec, pval);
+
+ pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]);
+
+ if (pdist < *dist)
+ {
+ *dist = pdist;
+ pt = &boneSnap;
+ VECCOPY(pt->p, vec);
+ pt->type = PT_EXACT;
+ }
+ }
+
+ return pt;
+}
+
+void sk_resetOverdraw(SK_Sketch *sketch)
+{
+ sketch->over.target = NULL;
+ sketch->over.start = -1;
+ sketch->over.end = -1;
+ sketch->over.count = 0;
+}
+
+int sk_hasOverdraw(SK_Sketch *sketch, SK_Stroke *stk)
+{
+ return sketch->over.target &&
+ sketch->over.count >= SK_OVERDRAW_LIMIT &&
+ (sketch->over.target == stk || stk == NULL) &&
+ (sketch->over.start != -1 || sketch->over.end != -1);
+}
+
+void sk_updateOverdraw(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
+{
+ if (sketch->over.target == NULL)
+ {
+ SK_Stroke *target;
+ int closest_index = -1;
+ int dist = SNAP_MIN_DISTANCE * 2;
+
+// /* If snapping, don't start overdraw */ Can't do that, snap is embed too now
+// if (sk_lastStrokePoint(stk)->mode == PT_SNAP)
+// {
+// return;
+// }
+
+ for (target = sketch->strokes.first; target; target = target->next)
+ {
+ if (target != stk)
+ {
+ int index;
+
+ SK_Point *spt = sk_snapPointStroke(C, target, dd->mval, &dist, &index, 1);
+
+ if (spt != NULL)
+ {
+ sketch->over.target = target;
+ closest_index = index;
+ }
+ }
+ }
+
+ if (sketch->over.target != NULL)
+ {
+ if (closest_index > -1)
+ {
+ if (sk_lastStrokePoint(stk)->type == PT_EXACT)
+ {
+ sketch->over.count = SK_OVERDRAW_LIMIT;
+ }
+ else
+ {
+ sketch->over.count++;
+ }
+ }
+
+ if (stk->nb_points == 1)
+ {
+ sketch->over.start = closest_index;
+ }
+ else
+ {
+ sketch->over.end = closest_index;
+ }
+ }
+ }
+ else if (sketch->over.target != NULL)
+ {
+ SK_Point *closest_pt = NULL;
+ int dist = SNAP_MIN_DISTANCE * 2;
+ int index;
+
+ closest_pt = sk_snapPointStroke(C, sketch->over.target, dd->mval, &dist, &index, 1);
+
+ if (closest_pt != NULL)
+ {
+ if (sk_lastStrokePoint(stk)->type == PT_EXACT)
+ {
+ sketch->over.count = SK_OVERDRAW_LIMIT;
+ }
+ else
+ {
+ sketch->over.count++;
+ }
+
+ sketch->over.end = index;
+ }
+ else
+ {
+ sketch->over.end = -1;
+ }
+ }
+}
+
+/* return 1 on reverse needed */
+int sk_adjustIndexes(SK_Sketch *sketch, int *start, int *end)
+{
+ int retval = 0;
+
+ *start = sketch->over.start;
+ *end = sketch->over.end;
+
+ if (*start == -1)
+ {
+ *start = 0;
+ }
+
+ if (*end == -1)
+ {
+ *end = sketch->over.target->nb_points - 1;
+ }
+
+ if (*end < *start)
+ {
+ int tmp = *start;
+ *start = *end;
+ *end = tmp;
+ retval = 1;
+ }
+
+ return retval;
+}
+
+void sk_endOverdraw(SK_Sketch *sketch)
+{
+ SK_Stroke *stk = sketch->active_stroke;
+
+ if (sk_hasOverdraw(sketch, NULL))
+ {
+ int start;
+ int end;
+
+ if (sk_adjustIndexes(sketch, &start, &end))
+ {
+ sk_reverseStroke(stk);
+ }
+
+ if (stk->nb_points > 1)
+ {
+ stk->points->type = sketch->over.target->points[start].type;
+ sk_lastStrokePoint(stk)->type = sketch->over.target->points[end].type;
+ }
+
+ sk_insertStrokePoints(sketch->over.target, stk->points, stk->nb_points, start, end);
+
+ sk_removeStroke(sketch, stk);
+
+ sk_resetOverdraw(sketch);
+ }
+}
+
+
+void sk_startStroke(SK_Sketch *sketch)
+{
+ SK_Stroke *stk = sk_createStroke();
+
+ BLI_addtail(&sketch->strokes, stk);
+ sketch->active_stroke = stk;
+
+ sk_resetOverdraw(sketch);
+}
+
+void sk_endStroke(bContext *C, SK_Sketch *sketch)
+{
+ Scene *scene = CTX_data_scene(C);
+ sk_shrinkStrokeBuffer(sketch->active_stroke);
+
+ if (scene->toolsettings->bone_sketching & BONE_SKETCHING_ADJUST)
+ {
+ sk_endOverdraw(sketch);
+ }
+
+ sketch->active_stroke = NULL;
+}
+
+void sk_updateDrawData(SK_DrawData *dd)
+{
+ dd->type = PT_CONTINUOUS;
+
+ dd->previous_mval[0] = dd->mval[0];
+ dd->previous_mval[1] = dd->mval[1];
+}
+
+float sk_distanceDepth(bContext *C, float p1[3], float p2[3])
+{
+ ARegion *ar = CTX_wm_region(C);
+ RegionView3D *rv3d = ar->regiondata;
+ float vec[3];
+ float distance;
+
+ VecSubf(vec, p1, p2);
+
+ Projf(vec, vec, rv3d->viewinv[2]);
+
+ distance = VecLength(vec);
+
+ if (Inpf(rv3d->viewinv[2], vec) > 0)
+ {
+ distance *= -1;
+ }
+
+ return distance;
+}
+
+void sk_interpolateDepth(bContext *C, SK_Stroke *stk, int start, int end, float length, float distance)
+{
+ ARegion *ar = CTX_wm_region(C);
+ ScrArea *sa = CTX_wm_area(C);
+ View3D *v3d = sa->spacedata.first;
+
+ float progress = 0;
+ int i;
+
+ progress = VecLenf(stk->points[start].p, stk->points[start - 1].p);
+
+ for (i = start; i <= end; i++)
+ {
+ float ray_start[3], ray_normal[3];
+ float delta = VecLenf(stk->points[i].p, stk->points[i + 1].p);
+ short pval[2];
+
+ project_short_noclip(ar, stk->points[i].p, pval);
+ viewray(ar, v3d, pval, ray_start, ray_normal);
+
+ VecMulf(ray_normal, distance * progress / length);
+ VecAddf(stk->points[i].p, stk->points[i].p, ray_normal);
+
+ progress += delta ;
+ }
+}
+
+void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_DrawData *dd)
+{
+ ARegion *ar = CTX_wm_region(C);
+ /* copied from grease pencil, need fixing */
+ SK_Point *last = sk_lastStrokePoint(stk);
+ short cval[2];
+ float fp[3] = {0, 0, 0};
+ float dvec[3];
+
+ if (last != NULL)
+ {
+ VECCOPY(fp, last->p);
+ }
+
+ initgrabz(ar->regiondata, fp[0], fp[1], fp[2]);
+
+ /* method taken from editview.c - mouse_cursor() */
+ project_short_noclip(ar, fp, cval);
+ window_to_3d_delta(ar, dvec, cval[0] - dd->mval[0], cval[1] - dd->mval[1]);
+ VecSubf(vec, fp, dvec);
+}
+
+int sk_getStrokeDrawPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
+{
+ pt->type = dd->type;
+ pt->mode = PT_PROJECT;
+ sk_projectDrawPoint(C, pt->p, stk, dd);
+
+ return 1;
+}
+
+int sk_addStrokeDrawPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
+{
+ SK_Point pt;
+
+ sk_initPoint(C, &pt);
+
+ sk_getStrokeDrawPoint(C, &pt, sketch, stk, dd);
+
+ sk_appendStrokePoint(stk, &pt);
+
+ return 1;
+}
+
+int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
+{
+ Scene *scene = CTX_data_scene(C);
+ int point_added = 0;
+
+ if (scene->snap_mode == SCE_SNAP_MODE_VOLUME)
+ {
+ ListBase depth_peels;
+ DepthPeel *p1, *p2;
+ float *last_p = NULL;
+ float dist = FLT_MAX;
+ float p[3];
+
+ depth_peels.first = depth_peels.last = NULL;
+
+ peelObjectsContext(C, &depth_peels, dd->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;
+ }
+
+
+ for (p1 = depth_peels.first; p1; p1 = p1->next)
+ {
+ if (p1->flag == 0)
+ {
+ float vec[3];
+ float new_dist;
+
+ p2 = NULL;
+ p1->flag = 1;
+
+ /* if peeling objects, take the first and last from each object */
+ if (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;
+ }
+ }
+ }
+
+ if (dist != FLT_MAX)
+ {
+ pt->type = dd->type;
+ pt->mode = PT_SNAP;
+ VECCOPY(pt->p, p);
+
+ point_added = 1;
+ }
+
+ BLI_freelistN(&depth_peels);
+ }
+ else
+ {
+ SK_Stroke *snap_stk;
+ float vec[3];
+ float no[3];
+ int found = 0;
+ int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
+
+ /* snap to strokes */
+ // if (scene->snap_mode == SCE_SNAP_MODE_VERTEX) /* snap all the time to strokes */
+ for (snap_stk = sketch->strokes.first; snap_stk; snap_stk = snap_stk->next)
+ {
+ SK_Point *spt = NULL;
+ if (snap_stk == stk)
+ {
+ spt = sk_snapPointStroke(C, snap_stk, dd->mval, &dist, NULL, 0);
+ }
+ else
+ {
+ spt = sk_snapPointStroke(C, snap_stk, dd->mval, &dist, NULL, 1);
+ }
+
+ if (spt != NULL)
+ {
+ VECCOPY(pt->p, spt->p);
+ point_added = 1;
+ }
+ }
+
+ /* try to snap to closer object */
+ found = snapObjectsContext(C, dd->mval, &dist, vec, no, SNAP_NOT_SELECTED);
+ if (found == 1)
+ {
+ pt->type = dd->type;
+ pt->mode = PT_SNAP;
+ VECCOPY(pt->p, vec);
+
+ point_added = 1;
+ }
+ }
+
+ return point_added;
+}
+
+int sk_addStrokeSnapPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd)
+{
+ int point_added;
+ SK_Point pt;
+
+ sk_initPoint(C, &pt);
+
+ point_added = sk_getStrokeSnapPoint(C, &pt, sketch, stk, dd);
+
+ if (point_added)
+ {
+ float final_p[3];
+ float length, distance;
+ int total;
+ int i;
+
+ VECCOPY(final_p, pt.p);
+
+ sk_projectDrawPoint(C, pt.p, stk, dd);
+ sk_appendStrokePoint(stk, &pt);
+
+ /* update all previous point to give smooth Z progresion */
+ total = 0;
+ length = 0;
+ for (i = stk->nb_points - 2; i > 0; i--)
+ {
+ length += VecLenf(stk->points[i].p, stk->points[i + 1].p);
+ total++;
+ if (stk->points[i].mode == PT_SNAP || stk->points[i].type == PT_EXACT)
+ {
+ break;
+ }
+ }
+
+ if (total > 1)
+ {
+ distance = sk_distanceDepth(C, final_p, stk->points[i].p);
+
+ sk_interpolateDepth(C, stk, i + 1, stk->nb_points - 2, length, distance);
+ }
+
+ VECCOPY(stk->points[stk->nb_points - 1].p, final_p);
+
+ point_added = 1;
+ }
+
+ return point_added;
+}
+
+void sk_addStrokePoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
+{
+ Scene *scene = CTX_data_scene(C);
+ int point_added = 0;
+
+ if (snap)
+ {
+ point_added = sk_addStrokeSnapPoint(C, sketch, stk, dd);
+ }
+
+ if (point_added == 0)
+ {
+ point_added = sk_addStrokeDrawPoint(C, sketch, stk, dd);
+ }
+
+ if (stk == sketch->active_stroke && scene->toolsettings->bone_sketching & BONE_SKETCHING_ADJUST)
+ {
+ sk_updateOverdraw(C, sketch, stk, dd);
+ }
+}
+
+void sk_getStrokePoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
+{
+ int point_added = 0;
+
+ if (snap)
+ {
+ point_added = sk_getStrokeSnapPoint(C, pt, sketch, stk, dd);
+ LAST_SNAP_POINT_VALID = 1;
+ VECCOPY(LAST_SNAP_POINT, pt->p);
+ }
+ else
+ {
+ LAST_SNAP_POINT_VALID = 0;
+ }
+
+ if (point_added == 0)
+ {
+ point_added = sk_getStrokeDrawPoint(C, pt, sketch, stk, dd);
+ }
+}
+
+void sk_endContinuousStroke(SK_Stroke *stk)
+{
+ stk->points[stk->nb_points - 1].type = PT_EXACT;
+}
+
+void sk_updateNextPoint(SK_Sketch *sketch, SK_Stroke *stk)
+{
+ if (stk)
+ {
+ memcpy(&sketch->next_point, stk->points[stk->nb_points - 1].p, sizeof(SK_Point));
+ }
+}
+
+int sk_stroke_filtermval(SK_DrawData *dd)
+{
+ int retval = 0;
+ if (ABS(dd->mval[0] - dd->previous_mval[0]) + ABS(dd->mval[1] - dd->previous_mval[1]) > U.gp_manhattendist)
+ {
+ retval = 1;
+ }
+
+ return retval;
+}
+
+void sk_initDrawData(SK_DrawData *dd, short mval[2])
+{
+ dd->mval[0] = mval[0];
+ dd->mval[1] = mval[1];
+ dd->previous_mval[0] = -1;
+ dd->previous_mval[1] = -1;
+ dd->type = PT_EXACT;
+}
+/********************************************/
+
+static void* headPoint(void *arg);
+static void* tailPoint(void *arg);
+static void* nextPoint(void *arg);
+static void* nextNPoint(void *arg, int n);
+static void* peekPoint(void *arg, int n);
+static void* previousPoint(void *arg);
+static int iteratorStopped(void *arg);
+
+static void initIteratorFct(SK_StrokeIterator *iter)
+{
+ iter->head = headPoint;
+ iter->tail = tailPoint;
+ iter->peek = peekPoint;
+ iter->next = nextPoint;
+ iter->nextN = nextNPoint;
+ iter->previous = previousPoint;
+ iter->stopped = iteratorStopped;
+}
+
+static SK_Point* setIteratorValues(SK_StrokeIterator *iter, int index)
+{
+ SK_Point *pt = NULL;
+
+ if (index >= 0 && index < iter->length)
+ {
+ pt = &(iter->stroke->points[iter->start + (iter->stride * index)]);
+ iter->p = pt->p;
+ iter->no = pt->no;
+ }
+ else
+ {
+ iter->p = NULL;
+ iter->no = NULL;
+ }
+
+ return pt;
+}
+
+void initStrokeIterator(BArcIterator *arg, SK_Stroke *stk, int start, int end)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+
+ initIteratorFct(iter);
+ iter->stroke = stk;
+
+ if (start < end)
+ {
+ iter->start = start + 1;
+ iter->end = end - 1;
+ iter->stride = 1;
+ }
+ else
+ {
+ iter->start = start - 1;
+ iter->end = end + 1;
+ iter->stride = -1;
+ }
+
+ iter->length = iter->stride * (iter->end - iter->start + 1);
+
+ iter->index = -1;
+}
+
+
+static void* headPoint(void *arg)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
+
+ result = &(iter->stroke->points[iter->start - iter->stride]);
+ iter->p = result->p;
+ iter->no = result->no;
+
+ return result;
+}
+
+static void* tailPoint(void *arg)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
+
+ result = &(iter->stroke->points[iter->end + iter->stride]);
+ iter->p = result->p;
+ iter->no = result->no;
+
+ return result;
+}
+
+static void* nextPoint(void *arg)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
+
+ iter->index++;
+ if (iter->index < iter->length)
+ {
+ result = setIteratorValues(iter, iter->index);
+ }
+
+ return result;
+}
+
+static void* nextNPoint(void *arg, int n)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
+
+ iter->index += n;
+
+ /* check if passed end */
+ if (iter->index < iter->length)
+ {
+ result = setIteratorValues(iter, iter->index);
+ }
+
+ return result;
+}
+
+static void* peekPoint(void *arg, int n)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
+ int index = iter->index + n;
+
+ /* check if passed end */
+ if (index < iter->length)
+ {
+ result = setIteratorValues(iter, index);
+ }
+
+ return result;
+}
+
+static void* previousPoint(void *arg)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+ SK_Point *result = NULL;
+
+ if (iter->index > 0)
+ {
+ iter->index--;
+ result = setIteratorValues(iter, iter->index);
+ }
+
+ return result;
+}
+
+static int iteratorStopped(void *arg)
+{
+ SK_StrokeIterator *iter = (SK_StrokeIterator*)arg;
+
+ if (iter->index >= iter->length)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void sk_convertStroke(bContext *C, SK_Stroke *stk)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ bArmature *arm = obedit->data;
+ SK_Point *head;
+ EditBone *parent = NULL;
+ float invmat[4][4]; /* move in caller function */
+ float tmat[3][3];
+ int head_index = 0;
+ int i;
+
+ head = NULL;
+
+ Mat4Invert(invmat, obedit->obmat);
+
+ Mat3CpyMat4(tmat, obedit->obmat);
+ Mat3Transp(tmat);
+
+ for (i = 0; i < stk->nb_points; i++)
+ {
+ SK_Point *pt = stk->points + i;
+
+ if (pt->type == PT_EXACT)
+ {
+ if (head == NULL)
+ {
+ head_index = i;
+ head = pt;
+ }
+ else
+ {
+ EditBone *bone = NULL;
+ EditBone *new_parent;
+
+ if (i - head_index > 1)
+ {
+ SK_StrokeIterator sk_iter;
+ BArcIterator *iter = (BArcIterator*)&sk_iter;
+
+ initStrokeIterator(iter, stk, head_index, i);
+
+ if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_ADAPTATIVE)
+ {
+ bone = subdivideArcBy(scene->toolsettings, arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
+ }
+ else if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_LENGTH)
+ {
+ bone = subdivideArcBy(scene->toolsettings, arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
+ }
+ else if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_CUT_FIXED)
+ {
+ bone = subdivideArcBy(scene->toolsettings, arm, arm->edbo, iter, invmat, tmat, nextFixedSubdivision);
+ }
+ }
+
+ if (bone == NULL)
+ {
+ bone = addEditBone(arm, "Bone");
+
+ VECCOPY(bone->head, head->p);
+ VECCOPY(bone->tail, pt->p);
+
+ Mat4MulVecfl(invmat, bone->head);
+ Mat4MulVecfl(invmat, bone->tail);
+ setBoneRollFromNormal(bone, pt->no, invmat, tmat);
+ }
+
+ new_parent = bone;
+ bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+
+ /* move to end of chain */
+ while (bone->parent != NULL)
+ {
+ bone = bone->parent;
+ bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
+ }
+
+ if (parent != NULL)
+ {
+ bone->parent = parent;
+ bone->flag |= BONE_CONNECTED;
+ }
+
+ parent = new_parent;
+ head_index = i;
+ head = pt;
+ }
+ }
+ }
+}
+
+void sk_convert(bContext *C, SK_Sketch *sketch)
+{
+ Scene *scene = CTX_data_scene(C);
+ SK_Stroke *stk;
+
+ for (stk = sketch->strokes.first; stk; stk = stk->next)
+ {
+ if (stk->selected == 1)
+ {
+ if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
+ {
+ sk_retargetStroke(C, stk);
+ }
+ else
+ {
+ sk_convertStroke(C, stk);
+ }
+// XXX
+// allqueue(REDRAWBUTSEDIT, 0);
+ }
+ }
+}
+/******************* GESTURE *************************/
+
+
+/* returns the number of self intersections */
+int sk_getSelfIntersections(bContext *C, ListBase *list, SK_Stroke *gesture)
+{
+ ARegion *ar = CTX_wm_region(C);
+ int added = 0;
+ int s_i;
+
+ for (s_i = 0; s_i < gesture->nb_points - 1; s_i++)
+ {
+ float s_p1[3] = {0, 0, 0};
+ float s_p2[3] = {0, 0, 0};
+ int g_i;
+
+ project_float(ar, gesture->points[s_i].p, s_p1);
+ project_float(ar, gesture->points[s_i + 1].p, s_p2);
+
+ /* start checking from second next, because two consecutive cannot intersect */
+ for (g_i = s_i + 2; g_i < gesture->nb_points - 1; g_i++)
+ {
+ float g_p1[3] = {0, 0, 0};
+ float g_p2[3] = {0, 0, 0};
+ float vi[3];
+ float lambda;
+
+ project_float(ar, gesture->points[g_i].p, g_p1);
+ project_float(ar, gesture->points[g_i + 1].p, g_p2);
+
+ if (LineIntersectLineStrict(s_p1, s_p2, g_p1, g_p2, vi, &lambda))
+ {
+ SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
+
+ isect->gesture_index = g_i;
+ isect->before = s_i;
+ isect->after = s_i + 1;
+ isect->stroke = gesture;
+
+ VecSubf(isect->p, gesture->points[s_i + 1].p, gesture->points[s_i].p);
+ VecMulf(isect->p, lambda);
+ VecAddf(isect->p, isect->p, gesture->points[s_i].p);
+
+ BLI_addtail(list, isect);
+
+ added++;
+ }
+ }
+ }
+
+ return added;
+}
+
+int cmpIntersections(void *i1, void *i2)
+{
+ SK_Intersection *isect1 = i1, *isect2 = i2;
+
+ if (isect1->stroke == isect2->stroke)
+ {
+ if (isect1->before < isect2->before)
+ {
+ return -1;
+ }
+ else if (isect1->before > isect2->before)
+ {
+ return 1;
+ }
+ else
+ {
+ if (isect1->lambda < isect2->lambda)
+ {
+ return -1;
+ }
+ else if (isect1->lambda > isect2->lambda)
+ {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/* returns the maximum number of intersections per stroke */
+int sk_getIntersections(bContext *C, ListBase *list, SK_Sketch *sketch, SK_Stroke *gesture)
+{
+ ARegion *ar = CTX_wm_region(C);
+ ScrArea *sa = CTX_wm_area(C);
+ View3D *v3d = sa->spacedata.first;
+ SK_Stroke *stk;
+ int added = 0;
+
+ for (stk = sketch->strokes.first; stk; stk = stk->next)
+ {
+ int s_added = 0;
+ int s_i;
+
+ for (s_i = 0; s_i < stk->nb_points - 1; s_i++)
+ {
+ float s_p1[3] = {0, 0, 0};
+ float s_p2[3] = {0, 0, 0};
+ int g_i;
+
+ project_float(ar, stk->points[s_i].p, s_p1);
+ project_float(ar, stk->points[s_i + 1].p, s_p2);
+
+ for (g_i = 0; g_i < gesture->nb_points - 1; g_i++)
+ {
+ float g_p1[3] = {0, 0, 0};
+ float g_p2[3] = {0, 0, 0};
+ float vi[3];
+ float lambda;
+
+ project_float(ar, gesture->points[g_i].p, g_p1);
+ project_float(ar, gesture->points[g_i + 1].p, g_p2);
+
+ if (LineIntersectLineStrict(s_p1, s_p2, g_p1, g_p2, vi, &lambda))
+ {
+ SK_Intersection *isect = MEM_callocN(sizeof(SK_Intersection), "Intersection");
+ float ray_start[3], ray_end[3];
+ short mval[2];
+
+ isect->gesture_index = g_i;
+ isect->before = s_i;
+ isect->after = s_i + 1;
+ isect->stroke = stk;
+ isect->lambda = lambda;
+
+ mval[0] = (short)(vi[0]);
+ mval[1] = (short)(vi[1]);
+ viewline(ar, v3d, mval, ray_start, ray_end);
+
+ LineIntersectLine( stk->points[s_i].p,
+ stk->points[s_i + 1].p,
+ ray_start,
+ ray_end,
+ isect->p,
+ vi);
+
+ BLI_addtail(list, isect);
+
+ s_added++;
+ }
+ }
+ }
+
+ added = MAX2(s_added, added);
+ }
+
+ BLI_sortlist(list, cmpIntersections);
+
+ return added;
+}
+
+int sk_getSegments(SK_Stroke *segments, SK_Stroke *gesture)
+{
+ SK_StrokeIterator sk_iter;
+ BArcIterator *iter = (BArcIterator*)&sk_iter;
+
+ float CORRELATION_THRESHOLD = 0.99f;
+ float *vec;
+ int i, j;
+
+ sk_appendStrokePoint(segments, &gesture->points[0]);
+ vec = segments->points[segments->nb_points - 1].p;
+
+ initStrokeIterator(iter, gesture, 0, gesture->nb_points - 1);
+
+ for (i = 1, j = 0; i < gesture->nb_points; i++)
+ {
+ float n[3];
+
+ /* Calculate normal */
+ VecSubf(n, gesture->points[i].p, vec);
+
+ if (calcArcCorrelation(iter, j, i, vec, n) < CORRELATION_THRESHOLD)
+ {
+ j = i - 1;
+ sk_appendStrokePoint(segments, &gesture->points[j]);
+ vec = segments->points[segments->nb_points - 1].p;
+ segments->points[segments->nb_points - 1].type = PT_EXACT;
+ }
+ }
+
+ sk_appendStrokePoint(segments, &gesture->points[gesture->nb_points - 1]);
+
+ return segments->nb_points - 1;
+}
+
+int sk_detectCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ if (gest->nb_segments == 1 && gest->nb_intersections == 1)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+void sk_applyCutGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ SK_Intersection *isect;
+
+ for (isect = gest->intersections.first; isect; isect = isect->next)
+ {
+ SK_Point pt;
+
+ pt.type = PT_EXACT;
+ pt.mode = PT_PROJECT; /* take mode from neighbouring points */
+ VECCOPY(pt.p, isect->p);
+
+ sk_insertStrokePoint(isect->stroke, &pt, isect->after);
+ }
+}
+
+int sk_detectTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ if (gest->nb_segments == 2 && gest->nb_intersections == 1 && gest->nb_self_intersections == 0)
+ {
+ float s1[3], s2[3];
+ float angle;
+
+ VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p);
+ VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p);
+
+ angle = VecAngle2(s1, s2);
+
+ if (angle > 60 && angle < 120)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void sk_applyTrimGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ SK_Intersection *isect;
+ float trim_dir[3];
+
+ VecSubf(trim_dir, gest->segments->points[2].p, gest->segments->points[1].p);
+
+ for (isect = gest->intersections.first; isect; isect = isect->next)
+ {
+ SK_Point pt;
+ float stroke_dir[3];
+
+ pt.type = PT_EXACT;
+ pt.mode = PT_PROJECT; /* take mode from neighbouring points */
+ VECCOPY(pt.p, isect->p);
+
+ VecSubf(stroke_dir, isect->stroke->points[isect->after].p, isect->stroke->points[isect->before].p);
+
+ /* same direction, trim end */
+ if (Inpf(stroke_dir, trim_dir) > 0)
+ {
+ sk_replaceStrokePoint(isect->stroke, &pt, isect->after);
+ sk_trimStroke(isect->stroke, 0, isect->after);
+ }
+ /* else, trim start */
+ else
+ {
+ sk_replaceStrokePoint(isect->stroke, &pt, isect->before);
+ sk_trimStroke(isect->stroke, isect->before, isect->stroke->nb_points - 1);
+ }
+
+ }
+}
+
+int sk_detectCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 1)
+ {
+ SK_Intersection *isect, *self_isect;
+
+ /* get the the last intersection of the first pair */
+ for( isect = gest->intersections.first; isect; isect = isect->next )
+ {
+ if (isect->stroke == isect->next->stroke)
+ {
+ isect = isect->next;
+ break;
+ }
+ }
+
+ self_isect = gest->self_intersections.first;
+
+ if (isect && isect->gesture_index < self_isect->gesture_index)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void sk_applyCommandGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ SK_Intersection *isect;
+ int command = 1;
+
+// XXX
+// command = pupmenu("Action %t|Flatten %x1|Straighten %x2|Polygonize %x3");
+ if(command < 1) return;
+
+ for (isect = gest->intersections.first; isect; isect = isect->next)
+ {
+ SK_Intersection *i2;
+
+ i2 = isect->next;
+
+ if (i2 && i2->stroke == isect->stroke)
+ {
+ switch (command)
+ {
+ case 1:
+ sk_flattenStroke(isect->stroke, isect->before, i2->after);
+ break;
+ case 2:
+ sk_straightenStroke(isect->stroke, isect->before, i2->after, isect->p, i2->p);
+ break;
+ case 3:
+ sk_polygonizeStroke(isect->stroke, isect->before, i2->after);
+ break;
+ }
+
+ isect = i2;
+ }
+ }
+}
+
+int sk_detectDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ if (gest->nb_segments == 2 && gest->nb_intersections == 2)
+ {
+ float s1[3], s2[3];
+ float angle;
+
+ VecSubf(s1, gest->segments->points[1].p, gest->segments->points[0].p);
+ VecSubf(s2, gest->segments->points[2].p, gest->segments->points[1].p);
+
+ angle = VecAngle2(s1, s2);
+
+ if (angle > 120)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void sk_applyDeleteGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ SK_Intersection *isect;
+
+ for (isect = gest->intersections.first; isect; isect = isect->next)
+ {
+ /* only delete strokes that are crossed twice */
+ if (isect->next && isect->next->stroke == isect->stroke)
+ {
+ isect = isect->next;
+
+ sk_removeStroke(sketch, isect->stroke);
+ }
+ }
+}
+
+int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ ARegion *ar = CTX_wm_region(C);
+ if (gest->nb_segments > 2 && gest->nb_intersections == 2)
+ {
+ short start_val[2], end_val[2];
+ short dist;
+
+ project_short_noclip(ar, gest->stk->points[0].p, start_val);
+ project_short_noclip(ar, sk_lastStrokePoint(gest->stk)->p, end_val);
+
+ dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1]));
+
+ /* if gesture is a circle */
+ if ( dist <= 20 )
+ {
+ SK_Intersection *isect;
+
+ /* check if it circled around an exact point */
+ for (isect = gest->intersections.first; isect; isect = isect->next)
+ {
+ /* only delete strokes that are crossed twice */
+ if (isect->next && isect->next->stroke == isect->stroke)
+ {
+ int start_index, end_index;
+ int i;
+
+ start_index = MIN2(isect->after, isect->next->after);
+ end_index = MAX2(isect->before, isect->next->before);
+
+ for (i = start_index; i <= end_index; i++)
+ {
+ if (isect->stroke->points[i].type == PT_EXACT)
+ {
+ return 1; /* at least one exact point found, stop detect here */
+ }
+ }
+
+ /* skip next */
+ isect = isect->next;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+void sk_applyMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ SK_Intersection *isect;
+
+ /* check if it circled around an exact point */
+ for (isect = gest->intersections.first; isect; isect = isect->next)
+ {
+ /* only merge strokes that are crossed twice */
+ if (isect->next && isect->next->stroke == isect->stroke)
+ {
+ int start_index, end_index;
+ int i;
+
+ start_index = MIN2(isect->after, isect->next->after);
+ end_index = MAX2(isect->before, isect->next->before);
+
+ for (i = start_index; i <= end_index; i++)
+ {
+ /* if exact, switch to continuous */
+ if (isect->stroke->points[i].type == PT_EXACT)
+ {
+ isect->stroke->points[i].type = PT_CONTINUOUS;
+ }
+ }
+
+ /* skip next */
+ isect = isect->next;
+ }
+ }
+}
+
+int sk_detectReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ if (gest->nb_segments > 2 && gest->nb_intersections == 2 && gest->nb_self_intersections == 0)
+ {
+ SK_Intersection *isect;
+
+ /* check if it circled around an exact point */
+ for (isect = gest->intersections.first; isect; isect = isect->next)
+ {
+ /* only delete strokes that are crossed twice */
+ if (isect->next && isect->next->stroke == isect->stroke)
+ {
+ float start_v[3], end_v[3];
+ float angle;
+
+ if (isect->gesture_index < isect->next->gesture_index)
+ {
+ VecSubf(start_v, isect->p, gest->stk->points[0].p);
+ VecSubf(end_v, sk_lastStrokePoint(gest->stk)->p, isect->next->p);
+ }
+ else
+ {
+ VecSubf(start_v, isect->next->p, gest->stk->points[0].p);
+ VecSubf(end_v, sk_lastStrokePoint(gest->stk)->p, isect->p);
+ }
+
+ angle = VecAngle2(start_v, end_v);
+
+ if (angle > 120)
+ {
+ return 1;
+ }
+
+ /* skip next */
+ isect = isect->next;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void sk_applyReverseGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ SK_Intersection *isect;
+
+ for (isect = gest->intersections.first; isect; isect = isect->next)
+ {
+ /* only reverse strokes that are crossed twice */
+ if (isect->next && isect->next->stroke == isect->stroke)
+ {
+ sk_reverseStroke(isect->stroke);
+
+ /* skip next */
+ isect = isect->next;
+ }
+ }
+}
+
+int sk_detectConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ if (gest->nb_segments == 3 && gest->nb_self_intersections == 1)
+ {
+ return 1;
+ }
+ return 0;
+}
+
+void sk_applyConvertGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ sk_convert(C, sketch);
+}
+
+static void sk_initGesture(bContext *C, SK_Gesture *gest, SK_Sketch *sketch)
+{
+ gest->intersections.first = gest->intersections.last = NULL;
+ gest->self_intersections.first = gest->self_intersections.last = NULL;
+
+ gest->segments = sk_createStroke();
+ gest->stk = sketch->gesture;
+
+ gest->nb_self_intersections = sk_getSelfIntersections(C, &gest->self_intersections, gest->stk);
+ gest->nb_intersections = sk_getIntersections(C, &gest->intersections, sketch, gest->stk);
+ gest->nb_segments = sk_getSegments(gest->segments, gest->stk);
+}
+
+static void sk_freeGesture(SK_Gesture *gest)
+{
+ sk_freeStroke(gest->segments);
+ BLI_freelistN(&gest->intersections);
+ BLI_freelistN(&gest->self_intersections);
+}
+
+void sk_applyGesture(bContext *C, SK_Sketch *sketch)
+{
+ SK_Gesture gest;
+ SK_GestureAction *act;
+
+ sk_initGesture(C, &gest, sketch);
+
+ /* detect and apply */
+ for (act = GESTURE_ACTIONS; act->apply != NULL; act++)
+ {
+ if (act->detect(C, &gest, sketch))
+ {
+ act->apply(C, &gest, sketch);
+ break;
+ }
+ }
+
+ sk_freeGesture(&gest);
+}
+
+/********************************************/
+
+void sk_deleteSelectedStrokes(SK_Sketch *sketch)
+{
+ SK_Stroke *stk, *next;
+
+ for (stk = sketch->strokes.first; stk; stk = next)
+ {
+ next = stk->next;
+
+ if (stk->selected == 1)
+ {
+ sk_removeStroke(sketch, stk);
+ }
+ }
+}
+
+void sk_selectAllSketch(SK_Sketch *sketch, int mode)
+{
+ SK_Stroke *stk = NULL;
+
+ if (mode == -1)
+ {
+ for (stk = sketch->strokes.first; stk; stk = stk->next)
+ {
+ stk->selected = 0;
+ }
+ }
+ else if (mode == 0)
+ {
+ for (stk = sketch->strokes.first; stk; stk = stk->next)
+ {
+ stk->selected = 1;
+ }
+ }
+ else if (mode == 1)
+ {
+ int selected = 1;
+
+ for (stk = sketch->strokes.first; stk; stk = stk->next)
+ {
+ selected &= stk->selected;
+ }
+
+ selected ^= 1;
+
+ for (stk = sketch->strokes.first; stk; stk = stk->next)
+ {
+ stk->selected = selected;
+ }
+ }
+}
+
+void sk_selectStroke(bContext *C, SK_Sketch *sketch, short mval[2], int extend)
+{
+ ViewContext vc;
+ rcti rect;
+ unsigned int buffer[MAXPICKBUF];
+ short hits;
+
+ view3d_set_viewcontext(C, &vc);
+
+ rect.xmin= mval[0]-5;
+ rect.xmax= mval[0]+5;
+ rect.ymin= mval[1]-5;
+ rect.ymax= mval[1]+5;
+
+ hits= view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect);
+
+ if (hits>0)
+ {
+ int besthitresult = -1;
+
+ if(hits == 1) {
+ besthitresult = buffer[3];
+ }
+ else {
+ besthitresult = buffer[3];
+ /* loop and get best hit */
+ }
+
+ if (besthitresult > 0)
+ {
+ SK_Stroke *selected_stk = BLI_findlink(&sketch->strokes, besthitresult - 1);
+
+ if (extend == 0)
+ {
+ sk_selectAllSketch(sketch, -1);
+
+ selected_stk->selected = 1;
+ }
+ else
+ {
+ selected_stk->selected ^= 1;
+ }
+
+
+ }
+ }
+}
+
+void sk_queueRedrawSketch(SK_Sketch *sketch)
+{
+ if (sketch->active_stroke != NULL)
+ {
+ SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
+
+ if (last != NULL)
+ {
+// XXX
+// allqueue(REDRAWVIEW3D, 0);
+ }
+ }
+}
+
+void sk_drawSketch(Scene *scene, SK_Sketch *sketch, int with_names)
+{
+ SK_Stroke *stk;
+
+ glDisable(GL_DEPTH_TEST);
+
+ glLineWidth(UI_GetThemeValuef(TH_VERTEX_SIZE));
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+
+ if (with_names)
+ {
+ int id;
+ for (id = 1, stk = sketch->strokes.first; stk; id++, stk = stk->next)
+ {
+ sk_drawStroke(stk, id, NULL, -1, -1);
+ }
+
+ glLoadName(-1);
+ }
+ else
+ {
+ float selected_rgb[3] = {1, 0, 0};
+ float unselected_rgb[3] = {1, 0.5, 0};
+
+ for (stk = sketch->strokes.first; stk; stk = stk->next)
+ {
+ int start = -1;
+ int end = -1;
+
+ if (sk_hasOverdraw(sketch, stk))
+ {
+ sk_adjustIndexes(sketch, &start, &end);
+ }
+
+ sk_drawStroke(stk, -1, (stk->selected==1?selected_rgb:unselected_rgb), start, end);
+
+ if (stk->selected == 1)
+ {
+ sk_drawStrokeSubdivision(scene->toolsettings, stk);
+ }
+ }
+
+ /* only draw gesture in active area */
+ if (sketch->gesture != NULL /*&& area_is_active_area(G.vd->area)*/)
+ {
+ float gesture_rgb[3] = {0, 0.5, 1};
+ sk_drawStroke(sketch->gesture, -1, gesture_rgb, -1, -1);
+ }
+
+ if (sketch->active_stroke != NULL)
+ {
+ SK_Point *last = sk_lastStrokePoint(sketch->active_stroke);
+
+ if (scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK)
+ {
+ sk_drawStrokeSubdivision(scene->toolsettings, sketch->active_stroke);
+ }
+
+ if (last != NULL)
+ {
+ glEnable(GL_LINE_STIPPLE);
+ glColor3fv(selected_rgb);
+ glBegin(GL_LINE_STRIP);
+
+ glVertex3fv(last->p);
+ glVertex3fv(sketch->next_point.p);
+
+ glEnd();
+
+ glDisable(GL_LINE_STIPPLE);
+
+ switch (sketch->next_point.mode)
+ {
+ case PT_SNAP:
+ glColor3f(0, 1, 0);
+ break;
+ case PT_PROJECT:
+ glColor3f(0, 0, 0);
+ break;
+ }
+
+ glBegin(GL_POINTS);
+
+ glVertex3fv(sketch->next_point.p);
+
+ glEnd();
+ }
+ }
+ }
+
+ glLineWidth(1.0);
+ glPointSize(1.0);
+
+ glEnable(GL_DEPTH_TEST);
+}
+
+int sk_finish_stroke(bContext *C, SK_Sketch *sketch)
+{
+ Scene *scene = CTX_data_scene(C);
+
+ if (sketch->active_stroke != NULL)
+ {
+ SK_Stroke *stk = sketch->active_stroke;
+
+ sk_endStroke(C, sketch);
+
+ if (scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK)
+ {
+ if (scene->toolsettings->bone_sketching_convert == SK_CONVERT_RETARGET)
+ {
+ sk_retargetStroke(C, stk);
+ }
+ else
+ {
+ sk_convertStroke(C, stk);
+ }
+// XXX
+// BIF_undo_push("Convert Sketch");
+ sk_removeStroke(sketch, stk);
+// XXX
+// allqueue(REDRAWBUTSEDIT, 0);
+ }
+
+// XXX
+// allqueue(REDRAWVIEW3D, 0);
+ return 1;
+ }
+
+ return 0;
+}
+
+void sk_start_draw_stroke(SK_Sketch *sketch)
+{
+ if (sketch->active_stroke == NULL)
+ {
+ sk_startStroke(sketch);
+ sk_selectAllSketch(sketch, -1);
+
+ sketch->active_stroke->selected = 1;
+ }
+}
+
+void sk_start_draw_gesture(SK_Sketch *sketch)
+{
+ sketch->gesture = sk_createStroke();
+}
+
+int sk_draw_stroke(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, SK_DrawData *dd, short snap)
+{
+ if (sk_stroke_filtermval(dd))
+ {
+ sk_addStrokePoint(C, sketch, stk, dd, snap);
+ sk_updateDrawData(dd);
+ sk_updateNextPoint(sketch, stk);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int ValidSketchViewContext(ViewContext *vc)
+{
+ Object *obedit = vc->obedit;
+ Scene *scene= vc->scene;
+
+ if (obedit &&
+ obedit->type == OB_ARMATURE &&
+ scene->toolsettings->bone_sketching & BONE_SKETCHING)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int BDR_drawSketchNames(ViewContext *vc)
+{
+ if (ValidSketchViewContext(vc))
+ {
+ if (GLOBAL_sketch != NULL)
+ {
+ sk_drawSketch(vc->scene, GLOBAL_sketch, 1);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+void BDR_drawSketch(bContext *C)
+{
+ if (ED_operator_sketch_mode(C))
+ {
+ if (GLOBAL_sketch != NULL)
+ {
+ sk_drawSketch(CTX_data_scene(C), GLOBAL_sketch, 0);
+ }
+ }
+}
+
+static int sketch_delete(bContext *C, wmOperator *op, wmEvent *event)
+{
+ if (GLOBAL_sketch != NULL)
+ {
+ sk_deleteSelectedStrokes(GLOBAL_sketch);
+// allqueue(REDRAWVIEW3D, 0);
+ }
+ return OPERATOR_FINISHED;
+}
+
+void BIF_sk_selectStroke(bContext *C, short mval[2], short extend)
+{
+ if (GLOBAL_sketch != NULL)
+ {
+ sk_selectStroke(C, GLOBAL_sketch, mval, extend);
+ }
+}
+
+void BIF_convertSketch(bContext *C)
+{
+ if (ED_operator_sketch_full_mode(C))
+ {
+ if (GLOBAL_sketch != NULL)
+ {
+ sk_convert(C, GLOBAL_sketch);
+// BIF_undo_push("Convert Sketch");
+// allqueue(REDRAWVIEW3D, 0);
+// allqueue(REDRAWBUTSEDIT, 0);
+ }
+ }
+}
+
+void BIF_deleteSketch(bContext *C)
+{
+ if (ED_operator_sketch_full_mode(C))
+ {
+ if (GLOBAL_sketch != NULL)
+ {
+ sk_deleteSelectedStrokes(GLOBAL_sketch);
+// BIF_undo_push("Convert Sketch");
+// allqueue(REDRAWVIEW3D, 0);
+ }
+ }
+}
+
+//void BIF_selectAllSketch(bContext *C, int mode)
+//{
+// if (BIF_validSketchMode(C))
+// {
+// if (GLOBAL_sketch != NULL)
+// {
+// sk_selectAllSketch(GLOBAL_sketch, mode);
+//// XXX
+//// allqueue(REDRAWVIEW3D, 0);
+// }
+// }
+//}
+
+void BIF_freeSketch(bContext *C)
+{
+ if (GLOBAL_sketch != NULL)
+ {
+ sk_freeSketch(GLOBAL_sketch);
+ GLOBAL_sketch = NULL;
+ }
+}
+
+static int sketch_cancel(bContext *C, wmOperator *op, wmEvent *event)
+{
+ if (GLOBAL_sketch != NULL)
+ {
+ sk_cancelStroke(GLOBAL_sketch);
+ ED_area_tag_redraw(CTX_wm_area(C));
+ return OPERATOR_FINISHED;
+ }
+ return OPERATOR_PASS_THROUGH;
+}
+
+static int sketch_finish(bContext *C, wmOperator *op, wmEvent *event)
+{
+ if (GLOBAL_sketch != NULL)
+ {
+ if (sk_finish_stroke(C, GLOBAL_sketch))
+ {
+ ED_area_tag_redraw(CTX_wm_area(C));
+ return OPERATOR_FINISHED;
+ }
+ }
+ return OPERATOR_PASS_THROUGH;
+}
+
+static int sketch_select(bContext *C, wmOperator *op, wmEvent *event)
+{
+ if (GLOBAL_sketch != NULL)
+ {
+ short extend = 0;
+ sk_selectStroke(C, GLOBAL_sketch, event->mval, extend);
+ ED_area_tag_redraw(CTX_wm_area(C));
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static int sketch_draw_stroke_cancel(bContext *C, wmOperator *op)
+{
+ sk_cancelStroke(GLOBAL_sketch);
+ MEM_freeN(op->customdata);
+ return OPERATOR_CANCELLED;
+}
+
+static int sketch_draw_stroke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ short snap = RNA_boolean_get(op->ptr, "snap");
+ SK_DrawData *dd;
+
+ if (GLOBAL_sketch == NULL)
+ {
+ GLOBAL_sketch = sk_createSketch();
+ }
+
+ op->customdata = dd = MEM_callocN(sizeof("SK_DrawData"), "SketchDrawData");
+ sk_initDrawData(dd, event->mval);
+
+ sk_start_draw_stroke(GLOBAL_sketch);
+
+ sk_draw_stroke(C, GLOBAL_sketch, GLOBAL_sketch->active_stroke, dd, snap);
+
+ WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int sketch_draw_gesture_cancel(bContext *C, wmOperator *op)
+{
+ sk_cancelStroke(GLOBAL_sketch);
+ MEM_freeN(op->customdata);
+ return OPERATOR_CANCELLED;
+}
+
+static int sketch_draw_gesture(bContext *C, wmOperator *op, wmEvent *event)
+{
+ short snap = RNA_boolean_get(op->ptr, "snap");
+ SK_DrawData *dd;
+
+ if (GLOBAL_sketch == NULL)
+ {
+ GLOBAL_sketch = sk_createSketch();
+ }
+
+ op->customdata = dd = MEM_callocN(sizeof("SK_DrawData"), "SketchDrawData");
+ sk_initDrawData(dd, event->mval);
+
+ sk_start_draw_gesture(GLOBAL_sketch);
+ sk_draw_stroke(C, GLOBAL_sketch, GLOBAL_sketch->gesture, dd, snap);
+
+ WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short gesture, SK_Stroke *stk)
+{
+ short snap = RNA_boolean_get(op->ptr, "snap");
+ SK_DrawData *dd = op->customdata;
+ int retval = OPERATOR_RUNNING_MODAL;
+
+ switch (event->type)
+ {
+ case LEFTCTRLKEY:
+ case RIGHTCTRLKEY:
+ snap = event->ctrl;
+ RNA_boolean_set(op->ptr, "snap", snap);
+ break;
+ case MOUSEMOVE:
+ dd->mval[0] = event->mval[0];
+ dd->mval[1] = event->mval[1];
+ sk_draw_stroke(C, GLOBAL_sketch, stk, dd, snap);
+ ED_area_tag_redraw(CTX_wm_area(C));
+ break;
+ case ESCKEY:
+ op->type->cancel(C, op);
+ ED_area_tag_redraw(CTX_wm_area(C));
+ retval = OPERATOR_CANCELLED;
+ break;
+ case LEFTMOUSE:
+ if (event->val == 0)
+ {
+ if (gesture == 0)
+ {
+ sk_endContinuousStroke(stk);
+ sk_filterLastContinuousStroke(stk);
+ sk_updateNextPoint(GLOBAL_sketch, stk);
+ ED_area_tag_redraw(CTX_wm_area(C));
+ MEM_freeN(op->customdata);
+ retval = OPERATOR_FINISHED;
+ }
+ else
+ {
+ sk_endContinuousStroke(stk);
+ sk_filterLastContinuousStroke(stk);
+
+ if (stk->nb_points > 1)
+ {
+ /* apply gesture here */
+ sk_applyGesture(C, GLOBAL_sketch);
+ }
+
+ sk_freeStroke(stk);
+ GLOBAL_sketch->gesture = NULL;
+
+ ED_area_tag_redraw(CTX_wm_area(C));
+ MEM_freeN(op->customdata);
+ retval = OPERATOR_FINISHED;
+ }
+ }
+ break;
+ }
+
+ return retval;
+}
+
+static int sketch_draw_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return sketch_draw_modal(C, op, event, 0, GLOBAL_sketch->active_stroke);
+}
+
+static int sketch_draw_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return sketch_draw_modal(C, op, event, 1, GLOBAL_sketch->gesture);
+}
+
+static int sketch_draw_preview(bContext *C, wmOperator *op, wmEvent *event)
+{
+ short snap = RNA_boolean_get(op->ptr, "snap");
+
+ if (GLOBAL_sketch != NULL)
+ {
+ SK_Sketch *sketch = GLOBAL_sketch;
+ SK_DrawData dd;
+
+ sk_initDrawData(&dd, event->mval);
+ sk_getStrokePoint(C, &sketch->next_point, sketch, sketch->active_stroke, &dd, snap);
+ ED_area_tag_redraw(CTX_wm_area(C));
+ }
+
+ return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
+}
+
+/* ============================================== Poll Functions ============================================= */
+
+int ED_operator_sketch_mode_active_stroke(bContext *C)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+
+ if (obedit &&
+ obedit->type == OB_ARMATURE &&
+ scene->toolsettings->bone_sketching & BONE_SKETCHING &&
+ GLOBAL_sketch != NULL &&
+ GLOBAL_sketch->active_stroke != NULL)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int ED_operator_sketch_mode_gesture(bContext *C)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+
+ if (obedit &&
+ obedit->type == OB_ARMATURE &&
+ scene->toolsettings->bone_sketching & BONE_SKETCHING &&
+ (scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) == 0 &&
+ GLOBAL_sketch != NULL &&
+ GLOBAL_sketch->active_stroke == NULL)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int ED_operator_sketch_full_mode(bContext *C)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+
+ if (obedit &&
+ obedit->type == OB_ARMATURE &&
+ scene->toolsettings->bone_sketching & BONE_SKETCHING &&
+ (scene->toolsettings->bone_sketching & BONE_SKETCHING_QUICK) == 0)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int ED_operator_sketch_mode(bContext *C)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+
+ if (obedit &&
+ obedit->type == OB_ARMATURE &&
+ scene->toolsettings->bone_sketching & BONE_SKETCHING)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/* ================================================ Operators ================================================ */
+
+void SKETCH_OT_delete(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "delete";
+ ot->idname= "SKETCH_OT_delete";
+
+ /* api callbacks */
+ ot->invoke= sketch_delete;
+
+ ot->poll= ED_operator_sketch_full_mode;
+
+ /* flags */
+// ot->flag= OPTYPE_UNDO;
+}
+
+void SKETCH_OT_select(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "select";
+ ot->idname= "SKETCH_OT_select";
+
+ /* api callbacks */
+ ot->invoke= sketch_select;
+
+ ot->poll= ED_operator_sketch_full_mode;
+
+ /* flags */
+// ot->flag= OPTYPE_UNDO;
+}
+
+void SKETCH_OT_cancel_stroke(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "cancel stroke";
+ ot->idname= "SKETCH_OT_cancel_stroke";
+
+ /* api callbacks */
+ ot->invoke= sketch_cancel;
+
+ ot->poll= ED_operator_sketch_mode_active_stroke;
+
+ /* flags */
+// ot->flag= OPTYPE_UNDO;
+}
+
+void SKETCH_OT_finish_stroke(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "end stroke";
+ ot->idname= "SKETCH_OT_finish_stroke";
+
+ /* api callbacks */
+ ot->invoke= sketch_finish;
+
+ ot->poll= ED_operator_sketch_mode_active_stroke;
+
+ /* flags */
+// ot->flag= OPTYPE_UNDO;
+}
+
+void SKETCH_OT_draw_preview(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "draw preview";
+ ot->idname= "SKETCH_OT_draw_preview";
+
+ /* api callbacks */
+ ot->invoke= sketch_draw_preview;
+
+ ot->poll= ED_operator_sketch_mode_active_stroke;
+
+ RNA_def_boolean(ot->srna, "snap", 0, "Snap", "");
+
+ /* flags */
+// ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+void SKETCH_OT_draw_stroke(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "draw stroke";
+ ot->idname= "SKETCH_OT_draw_stroke";
+
+ /* api callbacks */
+ ot->invoke = sketch_draw_stroke;
+ ot->modal = sketch_draw_stroke_modal;
+ ot->cancel = sketch_draw_stroke_cancel;
+
+ ot->poll= ED_operator_sketch_mode;
+
+ RNA_def_boolean(ot->srna, "snap", 0, "Snap", "");
+
+ /* flags */
+// ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+void SKETCH_OT_gesture(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "gesture";
+ ot->idname= "SKETCH_OT_gesture";
+
+ /* api callbacks */
+ ot->invoke = sketch_draw_gesture;
+ ot->modal = sketch_draw_gesture_modal;
+ ot->cancel = sketch_draw_gesture_cancel;
+
+ ot->poll= ED_operator_sketch_mode_gesture;
+
+ RNA_def_boolean(ot->srna, "snap", 0, "Snap", "");
+
+ /* flags */
+// ot->flag= OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index b951829d9d1..ae82c063435 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -452,7 +452,7 @@ static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
bPoseChannel *pchan;
Bone *curbone, *pabone, *chbone;
int direction = RNA_enum_get(op->ptr, "direction");
- int add_to_sel = RNA_boolean_get(op->ptr, "add_to_sel");
+ int add_to_sel = RNA_boolean_get(op->ptr, "extend");
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
curbone= pchan->bone;
@@ -519,7 +519,7 @@ void POSE_OT_select_hierarchy(wmOperatorType *ot)
/* props */
RNA_def_enum(ot->srna, "direction", direction_items,
BONE_SELECT_PARENT, "Direction", "");
- RNA_def_boolean(ot->srna, "add_to_sel", 0, "Add to Selection", "");
+ RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
}
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
new file mode 100644
index 00000000000..a38b4de4657
--- /dev/null
+++ b/source/blender/editors/armature/reeb.c
@@ -0,0 +1,3725 @@
+/**
+ * $Id:
+ *
+ * ***** 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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.
+ *
+ * Contributor(s): Martin Poirier
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+#include <string.h> // for memcpy
+#include <stdio.h>
+#include <stdlib.h> // for qsort
+#include <float.h>
+
+#include "PIL_time.h"
+
+#include "DNA_listBase.h"
+#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+#include "DNA_object_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_armature_types.h"
+
+#include "BKE_context.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+#include "BLI_editVert.h"
+#include "BLI_edgehash.h"
+#include "BLI_ghash.h"
+#include "BLI_heap.h"
+
+//#include "BDR_editobject.h"
+
+#include "BMF_Api.h"
+
+#include "ED_mesh.h"
+#include "ED_armature.h"
+//#include "BIF_interface.h"
+//#include "BIF_toolbox.h"
+//#include "BIF_graphics.h"
+#include "BIF_gl.h"
+#include "UI_resources.h"
+
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+#include "BKE_customdata.h"
+
+//#include "blendef.h"
+
+#include "ONL_opennl.h"
+
+#include "reeb.h"
+
+
+ReebGraph *GLOBAL_RG = NULL;
+ReebGraph *FILTERED_RG = NULL;
+
+/*
+ * Skeleton generation algorithm based on:
+ * "Harmonic Skeleton for Realistic Character Animation"
+ * Gregoire Aujay, Franck Hetroy, Francis Lazarus and Christine Depraz
+ * SIGGRAPH 2007
+ *
+ * Reeb graph generation algorithm based on:
+ * "Robust On-line Computation of Reeb Graphs: Simplicity and Speed"
+ * Valerio Pascucci, Giorgio Scorzelli, Peer-Timo Bremer and Ajith Mascarenhas
+ * SIGGRAPH 2007
+ *
+ * */
+
+#define DEBUG_REEB
+#define DEBUG_REEB_NODE
+
+typedef struct VertexData
+{
+ float w; /* weight */
+ int i; /* index */
+ ReebNode *n;
+} VertexData;
+
+typedef struct EdgeIndex
+{
+ EditEdge **edges;
+ int *offset;
+} EdgeIndex;
+
+typedef enum {
+ MERGE_LOWER,
+ MERGE_HIGHER,
+ MERGE_APPEND
+} MergeDirection;
+
+int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1);
+void mergeArcEdges(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc, MergeDirection direction);
+int mergeConnectedArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1);
+EditEdge * NextEdgeForVert(EdgeIndex *indexed_edges, int index);
+void mergeArcFaces(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc);
+void addFacetoArc(ReebArc *arc, EditFace *efa);
+
+void REEB_RadialSymmetry(BNode* root_node, RadialArc* ring, int count);
+void REEB_AxialSymmetry(BNode* root_node, BNode* node1, BNode* node2, struct BArc* barc1, BArc* barc2);
+
+void flipArcBuckets(ReebArc *arc);
+
+
+/***************************************** UTILS **********************************************/
+
+VertexData *allocVertexData(EditMesh *em)
+{
+ VertexData *data;
+ EditVert *eve;
+ int totvert, index;
+
+ totvert = BLI_countlist(&em->verts);
+
+ data = MEM_callocN(sizeof(VertexData) * totvert, "VertexData");
+
+ for(index = 0, eve = em->verts.first; eve; index++, eve = eve->next)
+ {
+ data[index].i = index;
+ data[index].w = 0;
+ eve->tmp.p = data + index;
+ }
+
+ return data;
+}
+
+int indexData(EditVert *eve)
+{
+ return ((VertexData*)eve->tmp.p)->i;
+}
+
+float weightData(EditVert *eve)
+{
+ return ((VertexData*)eve->tmp.p)->w;
+}
+
+void weightSetData(EditVert *eve, float w)
+{
+ ((VertexData*)eve->tmp.p)->w = w;
+}
+
+ReebNode* nodeData(EditVert *eve)
+{
+ return ((VertexData*)eve->tmp.p)->n;
+}
+
+void nodeSetData(EditVert *eve, ReebNode *n)
+{
+ ((VertexData*)eve->tmp.p)->n = n;
+}
+
+void REEB_freeArc(BArc *barc)
+{
+ ReebArc *arc = (ReebArc*)barc;
+ BLI_freelistN(&arc->edges);
+
+ if (arc->buckets)
+ MEM_freeN(arc->buckets);
+
+ if (arc->faces)
+ BLI_ghash_free(arc->faces, NULL, NULL);
+
+ MEM_freeN(arc);
+}
+
+void REEB_freeGraph(ReebGraph *rg)
+{
+ ReebArc *arc;
+ ReebNode *node;
+
+ // free nodes
+ for( node = rg->nodes.first; node; node = node->next )
+ {
+ BLI_freeNode((BGraph*)rg, (BNode*)node);
+ }
+ BLI_freelistN(&rg->nodes);
+
+ // free arcs
+ arc = rg->arcs.first;
+ while( arc )
+ {
+ ReebArc *next = arc->next;
+ REEB_freeArc((BArc*)arc);
+ arc = next;
+ }
+
+ // free edge map
+ BLI_edgehash_free(rg->emap, NULL);
+
+ /* free linked graph */
+ if (rg->link_up)
+ {
+ REEB_freeGraph(rg->link_up);
+ }
+
+ MEM_freeN(rg);
+}
+
+ReebGraph * newReebGraph()
+{
+ ReebGraph *rg;
+ rg = MEM_callocN(sizeof(ReebGraph), "reeb graph");
+
+ rg->totnodes = 0;
+ rg->emap = BLI_edgehash_new();
+
+
+ rg->free_arc = REEB_freeArc;
+ rg->free_node = NULL;
+ rg->radial_symmetry = REEB_RadialSymmetry;
+ rg->axial_symmetry = REEB_AxialSymmetry;
+
+ return rg;
+}
+
+void BIF_flagMultiArcs(ReebGraph *rg, int flag)
+{
+ for ( ; rg; rg = rg->link_up)
+ {
+ BLI_flagArcs((BGraph*)rg, flag);
+ }
+}
+
+ReebNode * addNode(ReebGraph *rg, EditVert *eve)
+{
+ float weight;
+ ReebNode *node = NULL;
+
+ weight = weightData(eve);
+
+ node = MEM_callocN(sizeof(ReebNode), "reeb node");
+
+ node->flag = 0; // clear flag on init
+ node->symmetry_level = 0;
+ node->arcs = NULL;
+ node->degree = 0;
+ node->weight = weight;
+ node->index = rg->totnodes;
+ VECCOPY(node->p, eve->co);
+
+ BLI_addtail(&rg->nodes, node);
+ rg->totnodes++;
+
+ nodeSetData(eve, node);
+
+ return node;
+}
+
+ReebNode * copyNode(ReebGraph *rg, ReebNode *node)
+{
+ ReebNode *cp_node = NULL;
+
+ cp_node = MEM_callocN(sizeof(ReebNode), "reeb node copy");
+
+ memcpy(cp_node, node, sizeof(ReebNode));
+
+ cp_node->prev = NULL;
+ cp_node->next = NULL;
+ cp_node->arcs = NULL;
+
+ cp_node->link_up = NULL;
+ cp_node->link_down = NULL;
+
+ BLI_addtail(&rg->nodes, cp_node);
+ rg->totnodes++;
+
+ return cp_node;
+}
+
+void relinkNodes(ReebGraph *low_rg, ReebGraph *high_rg)
+{
+ ReebNode *low_node, *high_node;
+
+ if (low_rg == NULL || high_rg == NULL)
+ {
+ return;
+ }
+
+ for (low_node = low_rg->nodes.first; low_node; low_node = low_node->next)
+ {
+ for (high_node = high_rg->nodes.first; high_node; high_node = high_node->next)
+ {
+ if (low_node->index == high_node->index)
+ {
+ high_node->link_down = low_node;
+ low_node->link_up = high_node;
+ break;
+ }
+ }
+ }
+}
+
+ReebNode *BIF_otherNodeFromIndex(ReebArc *arc, ReebNode *node)
+{
+ return (arc->head->index == node->index) ? arc->tail : arc->head;
+}
+
+ReebNode *BIF_NodeFromIndex(ReebArc *arc, ReebNode *node)
+{
+ return (arc->head->index == node->index) ? arc->head : arc->tail;
+}
+
+ReebNode *BIF_lowestLevelNode(ReebNode *node)
+{
+ while (node->link_down)
+ {
+ node = node->link_down;
+ }
+
+ return node;
+}
+
+ReebArc * copyArc(ReebGraph *rg, ReebArc *arc)
+{
+ ReebArc *cp_arc;
+ ReebNode *node;
+
+ cp_arc = MEM_callocN(sizeof(ReebArc), "reeb arc copy");
+
+ memcpy(cp_arc, arc, sizeof(ReebArc));
+
+ cp_arc->link_up = arc;
+
+ cp_arc->head = NULL;
+ cp_arc->tail = NULL;
+
+ cp_arc->prev = NULL;
+ cp_arc->next = NULL;
+
+ cp_arc->edges.first = NULL;
+ cp_arc->edges.last = NULL;
+
+ /* copy buckets */
+ cp_arc->buckets = MEM_callocN(sizeof(EmbedBucket) * cp_arc->bcount, "embed bucket");
+ memcpy(cp_arc->buckets, arc->buckets, sizeof(EmbedBucket) * cp_arc->bcount);
+
+ /* copy faces map */
+ cp_arc->faces = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ mergeArcFaces(rg, cp_arc, arc);
+
+ /* find corresponding head and tail */
+ for (node = rg->nodes.first; node && (cp_arc->head == NULL || cp_arc->tail == NULL); node = node->next)
+ {
+ if (node->index == arc->head->index)
+ {
+ cp_arc->head = node;
+ }
+ else if (node->index == arc->tail->index)
+ {
+ cp_arc->tail = node;
+ }
+ }
+
+ BLI_addtail(&rg->arcs, cp_arc);
+
+ return cp_arc;
+}
+
+ReebGraph * copyReebGraph(ReebGraph *rg, int level)
+{
+ ReebNode *node;
+ ReebArc *arc;
+ ReebGraph *cp_rg = newReebGraph();
+
+ cp_rg->resolution = rg->resolution;
+ cp_rg->length = rg->length;
+ cp_rg->link_up = rg;
+ cp_rg->multi_level = level;
+
+ /* Copy nodes */
+ for (node = rg->nodes.first; node; node = node->next)
+ {
+ ReebNode *cp_node = copyNode(cp_rg, node);
+ cp_node->multi_level = level;
+ }
+
+ /* Copy arcs */
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ copyArc(cp_rg, arc);
+ }
+
+ BLI_buildAdjacencyList((BGraph*)cp_rg);
+
+ return cp_rg;
+}
+
+ReebGraph *BIF_graphForMultiNode(ReebGraph *rg, ReebNode *node)
+{
+ ReebGraph *multi_rg = rg;
+
+ while(multi_rg && multi_rg->multi_level != node->multi_level)
+ {
+ multi_rg = multi_rg->link_up;
+ }
+
+ return multi_rg;
+}
+
+ReebEdge * copyEdge(ReebEdge *edge)
+{
+ ReebEdge *newEdge = NULL;
+
+ newEdge = MEM_callocN(sizeof(ReebEdge), "reeb edge");
+ memcpy(newEdge, edge, sizeof(ReebEdge));
+
+ newEdge->next = NULL;
+ newEdge->prev = NULL;
+
+ return newEdge;
+}
+
+void printArc(ReebArc *arc)
+{
+ ReebEdge *edge;
+ ReebNode *head = (ReebNode*)arc->head;
+ ReebNode *tail = (ReebNode*)arc->tail;
+ printf("arc: (%i) %f -> (%i) %f\n", head->index, head->weight, tail->index, tail->weight);
+
+ for(edge = arc->edges.first; edge ; edge = edge->next)
+ {
+ printf("\tedge (%i, %i)\n", edge->v1->index, edge->v2->index);
+ }
+}
+
+void flipArc(ReebArc *arc)
+{
+ ReebNode *tmp;
+ tmp = arc->head;
+ arc->head = arc->tail;
+ arc->tail = tmp;
+
+ flipArcBuckets(arc);
+}
+
+#ifdef DEBUG_REEB_NODE
+void NodeDegreeDecrement(ReebGraph *rg, ReebNode *node)
+{
+ node->degree--;
+
+// if (node->degree == 0)
+// {
+// printf("would remove node %i\n", node->index);
+// }
+}
+
+void NodeDegreeIncrement(ReebGraph *rg, ReebNode *node)
+{
+// if (node->degree == 0)
+// {
+// printf("first connect node %i\n", node->index);
+// }
+
+ node->degree++;
+}
+
+#else
+#define NodeDegreeDecrement(rg, node) {node->degree--;}
+#define NodeDegreeIncrement(rg, node) {node->degree++;}
+#endif
+
+void repositionNodes(ReebGraph *rg)
+{
+ BArc *arc = NULL;
+ BNode *node = NULL;
+
+ // Reset node positions
+ for(node = rg->nodes.first; node; node = node->next)
+ {
+ node->p[0] = node->p[1] = node->p[2] = 0;
+ }
+
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (((ReebArc*)arc)->bcount > 0)
+ {
+ float p[3];
+
+ VECCOPY(p, ((ReebArc*)arc)->buckets[0].p);
+ VecMulf(p, 1.0f / arc->head->degree);
+ VecAddf(arc->head->p, arc->head->p, p);
+
+ VECCOPY(p, ((ReebArc*)arc)->buckets[((ReebArc*)arc)->bcount - 1].p);
+ VecMulf(p, 1.0f / arc->tail->degree);
+ VecAddf(arc->tail->p, arc->tail->p, p);
+ }
+ }
+}
+
+void verifyNodeDegree(ReebGraph *rg)
+{
+#ifdef DEBUG_REEB
+ ReebNode *node = NULL;
+ ReebArc *arc = NULL;
+
+ for(node = rg->nodes.first; node; node = node->next)
+ {
+ int count = 0;
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->head == node || arc->tail == node)
+ {
+ count++;
+ }
+ }
+ if (count != node->degree)
+ {
+ printf("degree error in node %i: expected %i got %i\n", node->index, count, node->degree);
+ }
+ if (node->degree == 0)
+ {
+ printf("zero degree node %i with weight %f\n", node->index, node->weight);
+ }
+ }
+#endif
+}
+
+void verifyBucketsArc(ReebGraph *rg, ReebArc *arc)
+{
+ ReebNode *head = (ReebNode*)arc->head;
+ ReebNode *tail = (ReebNode*)arc->tail;
+
+ if (arc->bcount > 0)
+ {
+ int i;
+ for(i = 0; i < arc->bcount; i++)
+ {
+ if (arc->buckets[i].nv == 0)
+ {
+ printArc(arc);
+ printf("count error in bucket %i/%i\n", i+1, arc->bcount);
+ }
+ }
+
+ if (ceil(head->weight) != arc->buckets[0].val)
+ {
+ printArc(arc);
+ printf("alloc error in first bucket: %f should be %f \n", arc->buckets[0].val, ceil(head->weight));
+ }
+ if (floor(tail->weight) != arc->buckets[arc->bcount - 1].val)
+ {
+ printArc(arc);
+ printf("alloc error in last bucket: %f should be %f \n", arc->buckets[arc->bcount - 1].val, floor(tail->weight));
+ }
+ }
+}
+
+void verifyBuckets(ReebGraph *rg)
+{
+#ifdef DEBUG_REEB
+ ReebArc *arc = NULL;
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ verifyBucketsArc(rg, arc);
+ }
+#endif
+}
+
+void verifyFaces(ReebGraph *rg)
+{
+#ifdef DEBUG_REEB
+ int total = 0;
+ ReebArc *arc = NULL;
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ total += BLI_ghash_size(arc->faces);
+ }
+
+#endif
+}
+
+void verifyArcs(ReebGraph *rg)
+{
+ ReebArc *arc;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->head->weight > arc->tail->weight)
+ {
+ printf("FLIPPED ARC!\n");
+ }
+ }
+}
+
+void verifyMultiResolutionLinks(ReebGraph *rg, int level)
+{
+#ifdef DEBUG_REEB
+ ReebGraph *lower_rg = rg->link_up;
+
+ if (lower_rg)
+ {
+ ReebArc *arc;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (BLI_findindex(&lower_rg->arcs, arc->link_up) == -1)
+ {
+ printf("missing arc %p for level %i\n", arc->link_up, level);
+ printf("Source arc was ---\n");
+ printArc(arc);
+
+ arc->link_up = NULL;
+ }
+ }
+
+
+ verifyMultiResolutionLinks(lower_rg, level + 1);
+ }
+#endif
+}
+/***************************************** BUCKET UTILS **********************************************/
+
+void addVertToBucket(EmbedBucket *b, float co[3])
+{
+ b->nv++;
+ VecLerpf(b->p, b->p, co, 1.0f / b->nv);
+}
+
+void removeVertFromBucket(EmbedBucket *b, float co[3])
+{
+ VecMulf(b->p, (float)b->nv);
+ VecSubf(b->p, b->p, co);
+ b->nv--;
+ VecMulf(b->p, 1.0f / (float)b->nv);
+}
+
+void mergeBuckets(EmbedBucket *bDst, EmbedBucket *bSrc)
+{
+ if (bDst->nv > 0 && bSrc->nv > 0)
+ {
+ bDst->nv += bSrc->nv;
+ VecLerpf(bDst->p, bDst->p, bSrc->p, (float)bSrc->nv / (float)(bDst->nv));
+ }
+ else if (bSrc->nv > 0)
+ {
+ bDst->nv = bSrc->nv;
+ VECCOPY(bDst->p, bSrc->p);
+ }
+}
+
+void mergeArcBuckets(ReebArc *aDst, ReebArc *aSrc, float start, float end)
+{
+ if (aDst->bcount > 0 && aSrc->bcount > 0)
+ {
+ int indexDst = 0, indexSrc = 0;
+
+ start = MAX3(start, aDst->buckets[0].val, aSrc->buckets[0].val);
+
+ while(indexDst < aDst->bcount && aDst->buckets[indexDst].val < start)
+ {
+ indexDst++;
+ }
+
+ while(indexSrc < aSrc->bcount && aSrc->buckets[indexSrc].val < start)
+ {
+ indexSrc++;
+ }
+
+ for( ; indexDst < aDst->bcount &&
+ indexSrc < aSrc->bcount &&
+ aDst->buckets[indexDst].val <= end &&
+ aSrc->buckets[indexSrc].val <= end
+
+ ; indexDst++, indexSrc++)
+ {
+ mergeBuckets(aDst->buckets + indexDst, aSrc->buckets + indexSrc);
+ }
+ }
+}
+
+void flipArcBuckets(ReebArc *arc)
+{
+ int i, j;
+
+ for (i = 0, j = arc->bcount - 1; i < j; i++, j--)
+ {
+ EmbedBucket tmp;
+
+ tmp = arc->buckets[i];
+ arc->buckets[i] = arc->buckets[j];
+ arc->buckets[j] = tmp;
+ }
+}
+
+int countArcBuckets(ReebArc *arc)
+{
+ return (int)(floor(arc->tail->weight) - ceil(arc->head->weight)) + 1;
+}
+
+void allocArcBuckets(ReebArc *arc)
+{
+ int i;
+ float start = ceil(arc->head->weight);
+ arc->bcount = countArcBuckets(arc);
+
+ if (arc->bcount > 0)
+ {
+ arc->buckets = MEM_callocN(sizeof(EmbedBucket) * arc->bcount, "embed bucket");
+
+ for(i = 0; i < arc->bcount; i++)
+ {
+ arc->buckets[i].val = start + i;
+ }
+ }
+ else
+ {
+ arc->buckets = NULL;
+ }
+
+}
+
+void resizeArcBuckets(ReebArc *arc)
+{
+ EmbedBucket *oldBuckets = arc->buckets;
+ int oldBCount = arc->bcount;
+
+ if (countArcBuckets(arc) == oldBCount)
+ {
+ return;
+ }
+
+ allocArcBuckets(arc);
+
+ if (oldBCount != 0 && arc->bcount != 0)
+ {
+ int oldStart = (int)oldBuckets[0].val;
+ int oldEnd = (int)oldBuckets[oldBCount - 1].val;
+ int newStart = (int)arc->buckets[0].val;
+ int newEnd = (int)arc->buckets[arc->bcount - 1].val;
+ int oldOffset = 0;
+ int newOffset = 0;
+ int len;
+
+ if (oldStart < newStart)
+ {
+ oldOffset = newStart - oldStart;
+ }
+ else
+ {
+ newOffset = oldStart - newStart;
+ }
+
+ len = MIN2(oldEnd - (oldStart + oldOffset) + 1, newEnd - (newStart - newOffset) + 1);
+
+ memcpy(arc->buckets + newOffset, oldBuckets + oldOffset, len * sizeof(EmbedBucket));
+ }
+
+ if (oldBuckets != NULL)
+ {
+ MEM_freeN(oldBuckets);
+ }
+}
+
+void reweightBuckets(ReebArc *arc)
+{
+ int i;
+ float start = ceil((arc->head)->weight);
+
+ if (arc->bcount > 0)
+ {
+ for(i = 0; i < arc->bcount; i++)
+ {
+ arc->buckets[i].val = start + i;
+ }
+ }
+}
+
+static void interpolateBuckets(ReebArc *arc, float *start_p, float *end_p, int start_index, int end_index)
+{
+ int total;
+ int j;
+
+ total = end_index - start_index + 2;
+
+ for (j = start_index; j <= end_index; j++)
+ {
+ EmbedBucket *empty = arc->buckets + j;
+ empty->nv = 1;
+ VecLerpf(empty->p, start_p, end_p, (float)(j - start_index + 1) / total);
+ }
+}
+
+void fillArcEmptyBuckets(ReebArc *arc)
+{
+ float *start_p, *end_p;
+ int start_index = 0, end_index = 0;
+ int missing = 0;
+ int i;
+
+ start_p = arc->head->p;
+
+ for(i = 0; i < arc->bcount; i++)
+ {
+ EmbedBucket *bucket = arc->buckets + i;
+
+ if (missing)
+ {
+ if (bucket->nv > 0)
+ {
+ missing = 0;
+
+ end_p = bucket->p;
+ end_index = i - 1;
+
+ interpolateBuckets(arc, start_p, end_p, start_index, end_index);
+ }
+ }
+ else
+ {
+ if (bucket->nv == 0)
+ {
+ missing = 1;
+
+ if (i > 0)
+ {
+ start_p = arc->buckets[i - 1].p;
+ }
+ start_index = i;
+ }
+ }
+ }
+
+ if (missing)
+ {
+ end_p = arc->tail->p;
+ end_index = arc->bcount - 1;
+
+ interpolateBuckets(arc, start_p, end_p, start_index, end_index);
+ }
+}
+
+static void ExtendArcBuckets(ReebArc *arc)
+{
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ EmbedBucket *last_bucket, *first_bucket;
+ float *previous = NULL;
+ float average_length = 0, length;
+ int padding_head = 0, padding_tail = 0;
+
+ if (arc->bcount == 0)
+ {
+ return; /* failsafe, shouldn't happen */
+ }
+
+ initArcIterator(iter, arc, arc->head);
+ IT_next(iter);
+ previous = iter->p;
+
+ for ( IT_next(iter);
+ IT_stopped(iter) == 0;
+ previous = iter->p, IT_next(iter)
+ )
+ {
+ average_length += VecLenf(previous, iter->p);
+ }
+ average_length /= (arc->bcount - 1);
+
+ first_bucket = arc->buckets;
+ last_bucket = arc->buckets + (arc->bcount - 1);
+
+ length = VecLenf(first_bucket->p, arc->head->p);
+ if (length > 2 * average_length)
+ {
+ padding_head = (int)floor(length / average_length);
+ }
+
+ length = VecLenf(last_bucket->p, arc->tail->p);
+ if (length > 2 * average_length)
+ {
+ padding_tail = (int)floor(length / average_length);
+ }
+
+ if (padding_head + padding_tail > 0)
+ {
+ EmbedBucket *old_buckets = arc->buckets;
+
+ arc->buckets = MEM_callocN(sizeof(EmbedBucket) * (padding_head + arc->bcount + padding_tail), "embed bucket");
+ memcpy(arc->buckets + padding_head, old_buckets, arc->bcount * sizeof(EmbedBucket));
+
+ arc->bcount = padding_head + arc->bcount + padding_tail;
+
+ MEM_freeN(old_buckets);
+ }
+
+ if (padding_head > 0)
+ {
+ interpolateBuckets(arc, arc->head->p, first_bucket->p, 0, padding_head);
+ }
+
+ if (padding_tail > 0)
+ {
+ interpolateBuckets(arc, last_bucket->p, arc->tail->p, arc->bcount - padding_tail, arc->bcount - 1);
+ }
+}
+
+/* CALL THIS ONLY AFTER FILTERING, SINCE IT MESSES UP WEIGHT DISTRIBUTION */
+void extendGraphBuckets(ReebGraph *rg)
+{
+ ReebArc *arc;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ ExtendArcBuckets(arc);
+ }
+}
+
+/**************************************** LENGTH CALCULATIONS ****************************************/
+
+void calculateArcLength(ReebArc *arc)
+{
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ float *vec0, *vec1;
+
+ arc->length = 0;
+
+ initArcIterator(iter, arc, arc->head);
+
+ vec0 = arc->head->p;
+ vec1 = arc->head->p; /* in case there's no embedding */
+
+ while (IT_next(iter))
+ {
+ vec1 = iter->p;
+
+ arc->length += VecLenf(vec0, vec1);
+
+ vec0 = vec1;
+ }
+
+ arc->length += VecLenf(arc->tail->p, vec1);
+}
+
+void calculateGraphLength(ReebGraph *rg)
+{
+ ReebArc *arc;
+
+ for (arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ calculateArcLength(arc);
+ }
+}
+
+/**************************************** SYMMETRY HANDLING ******************************************/
+
+void REEB_RadialSymmetry(BNode* root_node, RadialArc* ring, int count)
+{
+ ReebNode *node = (ReebNode*)root_node;
+ float axis[3];
+ int i;
+
+ VECCOPY(axis, root_node->symmetry_axis);
+
+ /* first pass, merge incrementally */
+ for (i = 0; i < count - 1; i++)
+ {
+ ReebNode *node1, *node2;
+ ReebArc *arc1, *arc2;
+ float tangent[3];
+ float normal[3];
+ int j = i + 1;
+
+ VecAddf(tangent, ring[i].n, ring[j].n);
+ Crossf(normal, tangent, axis);
+
+ node1 = (ReebNode*)BLI_otherNode(ring[i].arc, root_node);
+ node2 = (ReebNode*)BLI_otherNode(ring[j].arc, root_node);
+
+ arc1 = (ReebArc*)ring[i].arc;
+ arc2 = (ReebArc*)ring[j].arc;
+
+ /* mirror first node and mix with the second */
+ BLI_mirrorAlongAxis(node1->p, root_node->p, normal);
+ VecLerpf(node2->p, node2->p, node1->p, 1.0f / (j + 1));
+
+ /* Merge buckets
+ * there shouldn't be any null arcs here, but just to be safe
+ * */
+ if (arc1->bcount > 0 && arc2->bcount > 0)
+ {
+ ReebArcIterator arc_iter1, arc_iter2;
+ BArcIterator *iter1 = (BArcIterator*)&arc_iter1;
+ BArcIterator *iter2 = (BArcIterator*)&arc_iter2;
+ EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
+
+ initArcIterator(iter1, arc1, (ReebNode*)root_node);
+ initArcIterator(iter2, arc2, (ReebNode*)root_node);
+
+ bucket1 = IT_next(iter1);
+ bucket2 = IT_next(iter2);
+
+ /* Make sure they both start at the same value */
+ while(bucket1 && bucket2 && bucket1->val < bucket2->val)
+ {
+ bucket1 = IT_next(iter1);
+ }
+
+ while(bucket1 && bucket2 && bucket2->val < bucket1->val)
+ {
+ bucket2 = IT_next(iter2);
+ }
+
+
+ for ( ;bucket1 && bucket2; bucket1 = IT_next(iter1), bucket2 = IT_next(iter2))
+ {
+ bucket2->nv += bucket1->nv; /* add counts */
+
+ /* mirror on axis */
+ BLI_mirrorAlongAxis(bucket1->p, root_node->p, normal);
+ /* add bucket2 in bucket1 */
+ VecLerpf(bucket2->p, bucket2->p, bucket1->p, (float)bucket1->nv / (float)(bucket2->nv));
+ }
+ }
+ }
+
+ /* second pass, mirror back on previous arcs */
+ for (i = count - 1; i > 0; i--)
+ {
+ ReebNode *node1, *node2;
+ ReebArc *arc1, *arc2;
+ float tangent[3];
+ float normal[3];
+ int j = i - 1;
+
+ VecAddf(tangent, ring[i].n, ring[j].n);
+ Crossf(normal, tangent, axis);
+
+ node1 = (ReebNode*)BLI_otherNode(ring[i].arc, root_node);
+ node2 = (ReebNode*)BLI_otherNode(ring[j].arc, root_node);
+
+ arc1 = (ReebArc*)ring[i].arc;
+ arc2 = (ReebArc*)ring[j].arc;
+
+ /* copy first node than mirror */
+ VECCOPY(node2->p, node1->p);
+ BLI_mirrorAlongAxis(node2->p, root_node->p, normal);
+
+ /* Copy buckets
+ * there shouldn't be any null arcs here, but just to be safe
+ * */
+ if (arc1->bcount > 0 && arc2->bcount > 0)
+ {
+ ReebArcIterator arc_iter1, arc_iter2;
+ BArcIterator *iter1 = (BArcIterator*)&arc_iter1;
+ BArcIterator *iter2 = (BArcIterator*)&arc_iter2;
+ EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
+
+ initArcIterator(iter1, arc1, node);
+ initArcIterator(iter2, arc2, node);
+
+ bucket1 = IT_next(iter1);
+ bucket2 = IT_next(iter2);
+
+ /* Make sure they both start at the same value */
+ while(bucket1 && bucket1->val < bucket2->val)
+ {
+ bucket1 = IT_next(iter1);
+ }
+
+ while(bucket2 && bucket2->val < bucket1->val)
+ {
+ bucket2 = IT_next(iter2);
+ }
+
+
+ for ( ;bucket1 && bucket2; bucket1 = IT_next(iter1), bucket2 = IT_next(iter2))
+ {
+ /* copy and mirror back to bucket2 */
+ bucket2->nv = bucket1->nv;
+ VECCOPY(bucket2->p, bucket1->p);
+ BLI_mirrorAlongAxis(bucket2->p, node->p, normal);
+ }
+ }
+ }
+}
+
+void REEB_AxialSymmetry(BNode* root_node, BNode* node1, BNode* node2, struct BArc* barc1, BArc* barc2)
+{
+ ReebArc *arc1, *arc2;
+ float nor[3], p[3];
+
+ arc1 = (ReebArc*)barc1;
+ arc2 = (ReebArc*)barc2;
+
+ VECCOPY(nor, root_node->symmetry_axis);
+
+ /* mirror node2 along axis */
+ VECCOPY(p, node2->p);
+ BLI_mirrorAlongAxis(p, root_node->p, nor);
+
+ /* average with node1 */
+ VecAddf(node1->p, node1->p, p);
+ VecMulf(node1->p, 0.5f);
+
+ /* mirror back on node2 */
+ VECCOPY(node2->p, node1->p);
+ BLI_mirrorAlongAxis(node2->p, root_node->p, nor);
+
+ /* Merge buckets
+ * there shouldn't be any null arcs here, but just to be safe
+ * */
+ if (arc1->bcount > 0 && arc2->bcount > 0)
+ {
+ ReebArcIterator arc_iter1, arc_iter2;
+ BArcIterator *iter1 = (BArcIterator*)&arc_iter1;
+ BArcIterator *iter2 = (BArcIterator*)&arc_iter2;
+ EmbedBucket *bucket1 = NULL, *bucket2 = NULL;
+
+ initArcIterator(iter1, arc1, (ReebNode*)root_node);
+ initArcIterator(iter2, arc2, (ReebNode*)root_node);
+
+ bucket1 = IT_next(iter1);
+ bucket2 = IT_next(iter2);
+
+ /* Make sure they both start at the same value */
+ while(bucket1 && bucket1->val < bucket2->val)
+ {
+ bucket1 = IT_next(iter1);
+ }
+
+ while(bucket2 && bucket2->val < bucket1->val)
+ {
+ bucket2 = IT_next(iter2);
+ }
+
+
+ for ( ;bucket1 && bucket2; bucket1 = IT_next(iter1), bucket2 = IT_next(iter2))
+ {
+ bucket1->nv += bucket2->nv; /* add counts */
+
+ /* mirror on axis */
+ BLI_mirrorAlongAxis(bucket2->p, root_node->p, nor);
+ /* add bucket2 in bucket1 */
+ VecLerpf(bucket1->p, bucket1->p, bucket2->p, (float)bucket2->nv / (float)(bucket1->nv));
+
+ /* copy and mirror back to bucket2 */
+ bucket2->nv = bucket1->nv;
+ VECCOPY(bucket2->p, bucket1->p);
+ BLI_mirrorAlongAxis(bucket2->p, root_node->p, nor);
+ }
+ }
+}
+
+/************************************** ADJACENCY LIST *************************************************/
+
+
+/****************************************** SMOOTHING **************************************************/
+
+void postprocessGraph(ReebGraph *rg, char mode)
+{
+ ReebArc *arc;
+ float fac1 = 0, fac2 = 1, fac3 = 0;
+
+ switch(mode)
+ {
+ case SKGEN_AVERAGE:
+ fac1 = fac2 = fac3 = 1.0f / 3.0f;
+ break;
+ case SKGEN_SMOOTH:
+ fac1 = fac3 = 0.25f;
+ fac2 = 0.5f;
+ break;
+ case SKGEN_SHARPEN:
+ fac1 = fac2 = -0.25f;
+ fac2 = 1.5f;
+ break;
+ default:
+// XXX
+// error("Unknown post processing mode");
+ return;
+ }
+
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ EmbedBucket *buckets = arc->buckets;
+ int bcount = arc->bcount;
+ int index;
+
+ for(index = 1; index < bcount - 1; index++)
+ {
+ VecLerpf(buckets[index].p, buckets[index].p, buckets[index - 1].p, fac1 / (fac1 + fac2));
+ VecLerpf(buckets[index].p, buckets[index].p, buckets[index + 1].p, fac3 / (fac1 + fac2 + fac3));
+ }
+ }
+}
+
+/********************************************SORTING****************************************************/
+
+int compareNodesWeight(void *vnode1, void *vnode2)
+{
+ ReebNode *node1 = (ReebNode*)vnode1;
+ ReebNode *node2 = (ReebNode*)vnode2;
+
+ if (node1->weight < node2->weight)
+ {
+ return -1;
+ }
+ if (node1->weight > node2->weight)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void sortNodes(ReebGraph *rg)
+{
+ BLI_sortlist(&rg->nodes, compareNodesWeight);
+}
+
+int compareArcsWeight(void *varc1, void *varc2)
+{
+ ReebArc *arc1 = (ReebArc*)varc1;
+ ReebArc *arc2 = (ReebArc*)varc2;
+ ReebNode *node1 = (ReebNode*)arc1->head;
+ ReebNode *node2 = (ReebNode*)arc2->head;
+
+ if (node1->weight < node2->weight)
+ {
+ return -1;
+ }
+ if (node1->weight > node2->weight)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void sortArcs(ReebGraph *rg)
+{
+ BLI_sortlist(&rg->arcs, compareArcsWeight);
+}
+/******************************************* JOINING ***************************************************/
+
+void reweightArc(ReebGraph *rg, ReebArc *arc, ReebNode *start_node, float start_weight)
+{
+ ReebNode *node;
+ float old_weight;
+ float end_weight = start_weight + ABS(arc->tail->weight - arc->head->weight);
+ int i;
+
+ node = (ReebNode*)BLI_otherNode((BArc*)arc, (BNode*)start_node);
+
+ /* prevent backtracking */
+ if (node->flag == 1)
+ {
+ return;
+ }
+
+ if (arc->tail == start_node)
+ {
+ flipArc(arc);
+ }
+
+ start_node->flag = 1;
+
+ for (i = 0; i < node->degree; i++)
+ {
+ ReebArc *next_arc = node->arcs[i];
+
+ reweightArc(rg, next_arc, node, end_weight);
+ }
+
+ /* update only if needed */
+ if (arc->head->weight != start_weight || arc->tail->weight != end_weight)
+ {
+ old_weight = arc->head->weight; /* backup head weight, other arcs need it intact, it will be fixed by the source arc */
+
+ arc->head->weight = start_weight;
+ arc->tail->weight = end_weight;
+
+ reweightBuckets(arc);
+ resizeArcBuckets(arc);
+ fillArcEmptyBuckets(arc);
+
+ arc->head->weight = old_weight;
+ }
+}
+
+void reweightSubgraph(ReebGraph *rg, ReebNode *start_node, float start_weight)
+{
+ int i;
+
+ BLI_flagNodes((BGraph*)rg, 0);
+
+ for (i = 0; i < start_node->degree; i++)
+ {
+ ReebArc *next_arc = start_node->arcs[i];
+
+ reweightArc(rg, next_arc, start_node, start_weight);
+ }
+ start_node->weight = start_weight;
+}
+
+int joinSubgraphsEnds(ReebGraph *rg, float threshold, int nb_subgraphs)
+{
+ int joined = 0;
+ int subgraph;
+
+ for (subgraph = 1; subgraph <= nb_subgraphs; subgraph++)
+ {
+ ReebNode *start_node, *end_node;
+ ReebNode *min_node_start = NULL, *min_node_end = NULL;
+ float min_distance = FLT_MAX;
+
+ for (start_node = rg->nodes.first; start_node; start_node = start_node->next)
+ {
+ if (start_node->subgraph_index == subgraph && start_node->degree == 1)
+ {
+
+ for (end_node = rg->nodes.first; end_node; end_node = end_node->next)
+ {
+ if (end_node->subgraph_index != subgraph)
+ {
+ float distance = VecLenf(start_node->p, end_node->p);
+
+ if (distance < threshold && distance < min_distance)
+ {
+ min_distance = distance;
+ min_node_end = end_node;
+ min_node_start = start_node;
+ }
+ }
+ }
+ }
+ }
+
+ end_node = min_node_end;
+ start_node = min_node_start;
+
+ if (end_node && start_node)
+ {
+ ReebArc *start_arc, *end_arc;
+ int merging = 0;
+
+ start_arc = start_node->arcs[0];
+ end_arc = end_node->arcs[0];
+
+ if (start_arc->tail == start_node)
+ {
+ reweightSubgraph(rg, end_node, start_node->weight);
+
+ start_arc->tail = end_node;
+
+ merging = 1;
+ }
+ else if (start_arc->head == start_node)
+ {
+ reweightSubgraph(rg, start_node, end_node->weight);
+
+ start_arc->head = end_node;
+
+ merging = 2;
+ }
+
+ if (merging)
+ {
+ BLI_ReflagSubgraph((BGraph*)rg, end_node->flag, subgraph);
+
+ resizeArcBuckets(start_arc);
+ fillArcEmptyBuckets(start_arc);
+
+ NodeDegreeIncrement(rg, end_node);
+ BLI_rebuildAdjacencyListForNode((BGraph*)rg, (BNode*)end_node);
+
+ BLI_removeNode((BGraph*)rg, (BNode*)start_node);
+ }
+
+ joined = 1;
+ }
+ }
+
+ return joined;
+}
+
+/* Reweight graph from smallest node, fix fliped arcs */
+void fixSubgraphsOrientation(ReebGraph *rg, int nb_subgraphs)
+{
+ int subgraph;
+
+ for (subgraph = 1; subgraph <= nb_subgraphs; subgraph++)
+ {
+ ReebNode *node;
+ ReebNode *start_node = NULL;
+
+ for (node = rg->nodes.first; node; node = node->next)
+ {
+ if (node->subgraph_index == subgraph)
+ {
+ if (start_node == NULL || node->weight < start_node->weight)
+ {
+ start_node = node;
+ }
+ }
+ }
+
+ if (start_node)
+ {
+ reweightSubgraph(rg, start_node, start_node->weight);
+ }
+ }
+}
+
+int joinSubgraphs(ReebGraph *rg, float threshold)
+{
+ int nb_subgraphs;
+ int joined = 0;
+
+ BLI_buildAdjacencyList((BGraph*)rg);
+
+ if (BLI_isGraphCyclic((BGraph*)rg))
+ {
+ /* don't deal with cyclic graphs YET */
+ return 0;
+ }
+
+ /* sort nodes before flagging subgraphs to make sure root node is subgraph 0 */
+ sortNodes(rg);
+
+ nb_subgraphs = BLI_FlagSubgraphs((BGraph*)rg);
+
+ /* Harmonic function can create flipped arcs, take the occasion to fix them */
+// XXX
+// if (G.scene->toolsettings->skgen_options & SKGEN_HARMONIC)
+// {
+ fixSubgraphsOrientation(rg, nb_subgraphs);
+// }
+
+ if (nb_subgraphs > 1)
+ {
+ joined |= joinSubgraphsEnds(rg, threshold, nb_subgraphs);
+
+ if (joined)
+ {
+ removeNormalNodes(rg);
+ BLI_buildAdjacencyList((BGraph*)rg);
+ }
+ }
+
+ return joined;
+}
+
+/****************************************** FILTERING **************************************************/
+
+float lengthArc(ReebArc *arc)
+{
+#if 0
+ ReebNode *head = (ReebNode*)arc->head;
+ ReebNode *tail = (ReebNode*)arc->tail;
+
+ return tail->weight - head->weight;
+#else
+ return arc->length;
+#endif
+}
+
+int compareArcs(void *varc1, void *varc2)
+{
+ ReebArc *arc1 = (ReebArc*)varc1;
+ ReebArc *arc2 = (ReebArc*)varc2;
+ float len1 = lengthArc(arc1);
+ float len2 = lengthArc(arc2);
+
+ if (len1 < len2)
+ {
+ return -1;
+ }
+ if (len1 > len2)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+void filterArc(ReebGraph *rg, ReebNode *newNode, ReebNode *removedNode, ReebArc * srcArc, int merging)
+{
+ ReebArc *arc = NULL, *nextArc = NULL;
+
+ if (merging)
+ {
+ /* first pass, merge buckets for arcs that spawned the two nodes into the source arc*/
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ if (arc->head == srcArc->head && arc->tail == srcArc->tail && arc != srcArc)
+ {
+ ReebNode *head = srcArc->head;
+ ReebNode *tail = srcArc->tail;
+ mergeArcBuckets(srcArc, arc, head->weight, tail->weight);
+ }
+ }
+ }
+
+ /* second pass, replace removedNode by newNode, remove arcs that are collapsed in a loop */
+ arc = rg->arcs.first;
+ while(arc)
+ {
+ nextArc = arc->next;
+
+ if (arc->head == removedNode || arc->tail == removedNode)
+ {
+ if (arc->head == removedNode)
+ {
+ arc->head = newNode;
+ }
+ else
+ {
+ arc->tail = newNode;
+ }
+
+ // Remove looped arcs
+ if (arc->head == arc->tail)
+ {
+ // v1 or v2 was already newNode, since we're removing an arc, decrement degree
+ NodeDegreeDecrement(rg, newNode);
+
+ // If it's srcArc, it'll be removed later, so keep it for now
+ if (arc != srcArc)
+ {
+ BLI_remlink(&rg->arcs, arc);
+ REEB_freeArc((BArc*)arc);
+ }
+ }
+ else
+ {
+ /* flip arcs that flipped, can happen on diamond shapes, mostly on null arcs */
+ if (arc->head->weight > arc->tail->weight)
+ {
+ flipArc(arc);
+ }
+ //newNode->degree++; // incrementing degree since we're adding an arc
+ NodeDegreeIncrement(rg, newNode);
+ mergeArcFaces(rg, arc, srcArc);
+
+ if (merging)
+ {
+ ReebNode *head = arc->head;
+ ReebNode *tail = arc->tail;
+
+ // resize bucket list
+ resizeArcBuckets(arc);
+ mergeArcBuckets(arc, srcArc, head->weight, tail->weight);
+
+ /* update length */
+ arc->length += srcArc->length;
+ }
+ }
+ }
+
+ arc = nextArc;
+ }
+}
+
+void filterNullReebGraph(ReebGraph *rg)
+{
+ ReebArc *arc = NULL, *nextArc = NULL;
+
+ arc = rg->arcs.first;
+ while(arc)
+ {
+ nextArc = arc->next;
+ // Only collapse arcs too short to have any embed bucket
+ if (arc->bcount == 0)
+ {
+ ReebNode *newNode = (ReebNode*)arc->head;
+ ReebNode *removedNode = (ReebNode*)arc->tail;
+ float blend;
+
+ blend = (float)newNode->degree / (float)(newNode->degree + removedNode->degree); // blending factors
+
+ VecLerpf(newNode->p, removedNode->p, newNode->p, blend);
+
+ filterArc(rg, newNode, removedNode, arc, 0);
+
+ // Reset nextArc, it might have changed
+ nextArc = arc->next;
+
+ BLI_remlink(&rg->arcs, arc);
+ REEB_freeArc((BArc*)arc);
+
+ BLI_removeNode((BGraph*)rg, (BNode*)removedNode);
+ }
+
+ arc = nextArc;
+ }
+}
+
+int filterInternalExternalReebGraph(ReebGraph *rg, float threshold_internal, float threshold_external)
+{
+ ReebArc *arc = NULL, *nextArc = NULL;
+ int value = 0;
+
+ BLI_sortlist(&rg->arcs, compareArcs);
+
+ for (arc = rg->arcs.first; arc; arc = nextArc)
+ {
+ nextArc = arc->next;
+
+ // Only collapse non-terminal arcs that are shorter than threshold
+ if (threshold_internal > 0 && arc->head->degree > 1 && arc->tail->degree > 1 && (lengthArc(arc) < threshold_internal))
+ {
+ ReebNode *newNode = NULL;
+ ReebNode *removedNode = NULL;
+
+ /* Always remove lower node, so arcs don't flip */
+ newNode = arc->head;
+ removedNode = arc->tail;
+
+ filterArc(rg, newNode, removedNode, arc, 1);
+
+ // Reset nextArc, it might have changed
+ nextArc = arc->next;
+
+ BLI_remlink(&rg->arcs, arc);
+ REEB_freeArc((BArc*)arc);
+
+ BLI_removeNode((BGraph*)rg, (BNode*)removedNode);
+ value = 1;
+ }
+
+ // Only collapse terminal arcs that are shorter than threshold
+ else if (threshold_external > 0 && (arc->head->degree == 1 || arc->tail->degree == 1) && (lengthArc(arc) < threshold_external))
+ {
+ ReebNode *terminalNode = NULL;
+ ReebNode *middleNode = NULL;
+ ReebNode *removedNode = NULL;
+
+ // Assign terminal and middle nodes
+ if (arc->head->degree == 1)
+ {
+ terminalNode = arc->head;
+ middleNode = arc->tail;
+ }
+ else
+ {
+ terminalNode = arc->tail;
+ middleNode = arc->head;
+ }
+
+ if (middleNode->degree == 2 && middleNode != rg->nodes.first)
+ {
+#if 1
+ // If middle node is a normal node, it will be removed later
+ // Only if middle node is not the root node
+ /* USE THIS IF YOU WANT TO PROLONG ARCS TO THEIR TERMINAL NODES
+ * FOR HANDS, THIS IS NOT THE BEST RESULT
+ * */
+ continue;
+#else
+ removedNode = terminalNode;
+
+ // removing arc, so we need to decrease the degree of the remaining node
+ NodeDegreeDecrement(rg, middleNode);
+#endif
+ }
+ // Otherwise, just plain remove of the arc
+ else
+ {
+ removedNode = terminalNode;
+
+ // removing arc, so we need to decrease the degree of the remaining node
+ NodeDegreeDecrement(rg, middleNode);
+ }
+
+ // Reset nextArc, it might have changed
+ nextArc = arc->next;
+
+ BLI_remlink(&rg->arcs, arc);
+ REEB_freeArc((BArc*)arc);
+
+ BLI_removeNode((BGraph*)rg, (BNode*)removedNode);
+ value = 1;
+ }
+ }
+
+ return value;
+}
+
+int filterCyclesReebGraph(ReebGraph *rg, float distance_threshold)
+{
+ ReebArc *arc1, *arc2;
+ ReebArc *next2;
+ int filtered = 0;
+
+ for (arc1 = rg->arcs.first; arc1; arc1 = arc1->next)
+ {
+ for (arc2 = arc1->next; arc2; arc2 = next2)
+ {
+ next2 = arc2->next;
+ if (arc1 != arc2 && arc1->head == arc2->head && arc1->tail == arc2->tail)
+ {
+ mergeArcEdges(rg, arc1, arc2, MERGE_APPEND);
+ mergeArcFaces(rg, arc1, arc2);
+ mergeArcBuckets(arc1, arc2, arc1->head->weight, arc1->tail->weight);
+
+ NodeDegreeDecrement(rg, arc1->head);
+ NodeDegreeDecrement(rg, arc1->tail);
+
+ BLI_remlink(&rg->arcs, arc2);
+ REEB_freeArc((BArc*)arc2);
+
+ filtered = 1;
+ }
+ }
+ }
+
+ return filtered;
+}
+
+int filterSmartReebGraph(ReebGraph *rg, float threshold)
+{
+ ReebArc *arc = NULL, *nextArc = NULL;
+ int value = 0;
+
+ #if 0 //XXX
+ BLI_sortlist(&rg->arcs, compareArcs);
+
+#ifdef DEBUG_REEB
+ {
+ EditFace *efa;
+ for(efa=G.editMesh->faces.first; efa; efa=efa->next) {
+ efa->tmp.fp = -1;
+ }
+ }
+#endif
+
+ arc = rg->arcs.first;
+ while(arc)
+ {
+ nextArc = arc->next;
+
+ /* need correct normals and center */
+ recalc_editnormals();
+
+ // Only test terminal arcs
+ if (arc->head->degree == 1 || arc->tail->degree == 1)
+ {
+ GHashIterator ghi;
+ int merging = 0;
+ int total = BLI_ghash_size(arc->faces);
+ float avg_angle = 0;
+ float avg_vec[3] = {0,0,0};
+
+ for(BLI_ghashIterator_init(&ghi, arc->faces);
+ !BLI_ghashIterator_isDone(&ghi);
+ BLI_ghashIterator_step(&ghi))
+ {
+ EditFace *efa = BLI_ghashIterator_getValue(&ghi);
+
+#if 0
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ EmbedBucket *bucket = NULL;
+ EmbedBucket *previous = NULL;
+ float min_distance = -1;
+ float angle = 0;
+
+ initArcIterator(iter, arc, arc->head);
+
+ bucket = nextBucket(iter);
+
+ while (bucket != NULL)
+ {
+ float *vec0 = NULL;
+ float *vec1 = bucket->p;
+ float midpoint[3], tangent[3];
+ float distance;
+
+ /* first bucket. Previous is head */
+ if (previous == NULL)
+ {
+ vec0 = arc->head->p;
+ }
+ /* Previous is a valid bucket */
+ else
+ {
+ vec0 = previous->p;
+ }
+
+ VECCOPY(midpoint, vec1);
+
+ distance = VecLenf(midpoint, efa->cent);
+
+ if (min_distance == -1 || distance < min_distance)
+ {
+ min_distance = distance;
+
+ VecSubf(tangent, vec1, vec0);
+ Normalize(tangent);
+
+ angle = Inpf(tangent, efa->n);
+ }
+
+ previous = bucket;
+ bucket = nextBucket(iter);
+ }
+
+ avg_angle += saacos(fabs(angle));
+#ifdef DEBUG_REEB
+ efa->tmp.fp = saacos(fabs(angle));
+#endif
+#else
+ VecAddf(avg_vec, avg_vec, efa->n);
+#endif
+ }
+
+
+#if 0
+ avg_angle /= total;
+#else
+ VecMulf(avg_vec, 1.0 / total);
+ avg_angle = Inpf(avg_vec, avg_vec);
+#endif
+
+ arc->angle = avg_angle;
+
+ if (avg_angle > threshold)
+ merging = 1;
+
+ if (merging)
+ {
+ ReebNode *terminalNode = NULL;
+ ReebNode *middleNode = NULL;
+ ReebNode *newNode = NULL;
+ ReebNode *removedNode = NULL;
+ int merging = 0;
+
+ // Assign terminal and middle nodes
+ if (arc->head->degree == 1)
+ {
+ terminalNode = arc->head;
+ middleNode = arc->tail;
+ }
+ else
+ {
+ terminalNode = arc->tail;
+ middleNode = arc->head;
+ }
+
+ // If middle node is a normal node, merge to terminal node
+ if (middleNode->degree == 2)
+ {
+ merging = 1;
+ newNode = terminalNode;
+ removedNode = middleNode;
+ }
+ // Otherwise, just plain remove of the arc
+ else
+ {
+ merging = 0;
+ newNode = middleNode;
+ removedNode = terminalNode;
+ }
+
+ // Merging arc
+ if (merging)
+ {
+ filterArc(rg, newNode, removedNode, arc, 1);
+ }
+ else
+ {
+ // removing arc, so we need to decrease the degree of the remaining node
+ //newNode->degree--;
+ NodeDegreeDecrement(rg, newNode);
+ }
+
+ // Reset nextArc, it might have changed
+ nextArc = arc->next;
+
+ BLI_remlink(&rg->arcs, arc);
+ REEB_freeArc((BArc*)arc);
+
+ BLI_freelinkN(&rg->nodes, removedNode);
+ value = 1;
+ }
+ }
+
+ arc = nextArc;
+ }
+
+ #endif
+
+ return value;
+}
+
+void filterGraph(ReebGraph *rg, short options, float threshold_internal, float threshold_external)
+{
+ int done = 1;
+
+ calculateGraphLength(rg);
+
+ if ((options & SKGEN_FILTER_EXTERNAL) == 0)
+ {
+ threshold_external = 0;
+ }
+
+ if ((options & SKGEN_FILTER_INTERNAL) == 0)
+ {
+ threshold_internal = 0;
+ }
+
+ if (threshold_internal > 0 || threshold_external > 0)
+ {
+ /* filter until there's nothing more to do */
+ while (done == 1)
+ {
+ done = 0; /* no work done yet */
+
+ done = filterInternalExternalReebGraph(rg, threshold_internal, threshold_external);
+ }
+ }
+
+ if (options & SKGEN_FILTER_SMART)
+ {
+ filterSmartReebGraph(rg, 0.5);
+ filterCyclesReebGraph(rg, 0.5);
+ }
+
+ repositionNodes(rg);
+
+ /* Filtering might have created degree 2 nodes, so remove them */
+ removeNormalNodes(rg);
+}
+
+void finalizeGraph(ReebGraph *rg, char passes, char method)
+{
+ int i;
+
+ BLI_buildAdjacencyList((BGraph*)rg);
+
+ sortNodes(rg);
+
+ sortArcs(rg);
+
+ for(i = 0; i < passes; i++)
+ {
+ postprocessGraph(rg, method);
+ }
+
+ extendGraphBuckets(rg);
+}
+
+/************************************** WEIGHT SPREADING ***********************************************/
+
+int compareVerts( const void* a, const void* b )
+{
+ EditVert *va = *(EditVert**)a;
+ EditVert *vb = *(EditVert**)b;
+ int value = 0;
+
+ if (weightData(va) < weightData(vb))
+ {
+ value = -1;
+ }
+ else if (weightData(va) > weightData(vb))
+ {
+ value = 1;
+ }
+
+ return value;
+}
+
+void spreadWeight(EditMesh *em)
+{
+ EditVert **verts, *eve;
+ float lastWeight = 0.0f;
+ int totvert = BLI_countlist(&em->verts);
+ int i;
+ int work_needed = 1;
+
+ verts = MEM_callocN(sizeof(EditVert*) * totvert, "verts array");
+
+ for(eve = em->verts.first, i = 0; eve; eve = eve->next, i++)
+ {
+ verts[i] = eve;
+ }
+
+ while(work_needed == 1)
+ {
+ work_needed = 0;
+ qsort(verts, totvert, sizeof(EditVert*), compareVerts);
+
+ for(i = 0; i < totvert; i++)
+ {
+ eve = verts[i];
+
+ if (i == 0 || (weightData(eve) - lastWeight) > FLT_EPSILON)
+ {
+ lastWeight = weightData(eve);
+ }
+ else
+ {
+ work_needed = 1;
+ weightSetData(eve, lastWeight + FLT_EPSILON * 2);
+ lastWeight = weightData(eve);
+ }
+ }
+ }
+
+ MEM_freeN(verts);
+}
+
+/******************************************** EXPORT ***************************************************/
+
+void exportNode(FILE *f, char *text, ReebNode *node)
+{
+ fprintf(f, "%s i:%i w:%f d:%i %f %f %f\n", text, node->index, node->weight, node->degree, node->p[0], node->p[1], node->p[2]);
+}
+
+void REEB_exportGraph(ReebGraph *rg, int count)
+{
+ ReebArc *arc;
+ char filename[128];
+ FILE *f;
+
+ if (count == -1)
+ {
+ sprintf(filename, "test.txt");
+ }
+ else
+ {
+ sprintf(filename, "test%05i.txt", count);
+ }
+ f = fopen(filename, "w");
+
+ for(arc = rg->arcs.first; arc; arc = arc->next)
+ {
+ int i;
+ float p[3];
+
+ exportNode(f, "v1", arc->head);
+
+ for(i = 0; i < arc->bcount; i++)
+ {
+ fprintf(f, "b nv:%i %f %f %f\n", arc->buckets[i].nv, arc->buckets[i].p[0], arc->buckets[i].p[1], arc->buckets[i].p[2]);
+ }
+
+ VecAddf(p, arc->tail->p, arc->head->p);
+ VecMulf(p, 0.5f);
+
+ fprintf(f, "angle %0.3f %0.3f %0.3f %0.3f %i\n", p[0], p[1], p[2], arc->angle, BLI_ghash_size(arc->faces));
+ exportNode(f, "v2", arc->tail);
+ }
+
+ fclose(f);
+}
+
+/***************************************** MAIN ALGORITHM **********************************************/
+
+/* edges alone will create zero degree nodes, use this function to remove them */
+void removeZeroNodes(ReebGraph *rg)
+{
+ ReebNode *node, *next_node;
+
+ for (node = rg->nodes.first; node; node = next_node)
+ {
+ next_node = node->next;
+
+ if (node->degree == 0)
+ {
+ BLI_removeNode((BGraph*)rg, (BNode*)node);
+ }
+ }
+}
+
+void removeNormalNodes(ReebGraph *rg)
+{
+ ReebArc *arc, *nextArc;
+
+ // Merge degree 2 nodes
+ for(arc = rg->arcs.first; arc; arc = nextArc)
+ {
+ nextArc = arc->next;
+
+ while (arc->head->degree == 2 || arc->tail->degree == 2)
+ {
+ // merge at v1
+ if (arc->head->degree == 2)
+ {
+ ReebArc *connectedArc = (ReebArc*)BLI_findConnectedArc((BGraph*)rg, (BArc*)arc, (BNode*)arc->head);
+
+ /* If arcs are one after the other */
+ if (arc->head == connectedArc->tail)
+ {
+ /* remove furthest arc */
+ if (arc->tail->weight < connectedArc->head->weight)
+ {
+ mergeConnectedArcs(rg, arc, connectedArc);
+ nextArc = arc->next;
+ }
+ else
+ {
+ mergeConnectedArcs(rg, connectedArc, arc);
+ break; /* arc was removed, move to next */
+ }
+ }
+ /* Otherwise, arcs are side by side */
+ else
+ {
+ /* Don't do anything, we need to keep the lowest node, even if degree 2 */
+ break;
+ }
+ }
+
+ // merge at v2
+ if (arc->tail->degree == 2)
+ {
+ ReebArc *connectedArc = (ReebArc*)BLI_findConnectedArc((BGraph*)rg, (BArc*)arc, (BNode*)arc->tail);
+
+ /* If arcs are one after the other */
+ if (arc->tail == connectedArc->head)
+ {
+ /* remove furthest arc */
+ if (arc->head->weight < connectedArc->tail->weight)
+ {
+ mergeConnectedArcs(rg, arc, connectedArc);
+ nextArc = arc->next;
+ }
+ else
+ {
+ mergeConnectedArcs(rg, connectedArc, arc);
+ break; /* arc was removed, move to next */
+ }
+ }
+ /* Otherwise, arcs are side by side */
+ else
+ {
+ /* Don't do anything, we need to keep the lowest node, even if degree 2 */
+ break;
+ }
+ }
+ }
+ }
+
+}
+
+int edgeEquals(ReebEdge *e1, ReebEdge *e2)
+{
+ return (e1->v1 == e2->v1 && e1->v2 == e2->v2);
+}
+
+ReebArc *nextArcMappedToEdge(ReebArc *arc, ReebEdge *e)
+{
+ ReebEdge *nextEdge = NULL;
+ ReebEdge *edge = NULL;
+ ReebArc *result = NULL;
+
+ /* Find the ReebEdge in the edge list */
+ for(edge = arc->edges.first; edge && !edgeEquals(edge, e); edge = edge->next)
+ { }
+
+ nextEdge = edge->nextEdge;
+
+ if (nextEdge != NULL)
+ {
+ result = nextEdge->arc;
+ }
+
+ return result;
+}
+
+void addFacetoArc(ReebArc *arc, EditFace *efa)
+{
+ BLI_ghash_insert(arc->faces, efa, efa);
+}
+
+void mergeArcFaces(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc)
+{
+ GHashIterator ghi;
+
+ for(BLI_ghashIterator_init(&ghi, aSrc->faces);
+ !BLI_ghashIterator_isDone(&ghi);
+ BLI_ghashIterator_step(&ghi))
+ {
+ EditFace *efa = BLI_ghashIterator_getValue(&ghi);
+ BLI_ghash_insert(aDst->faces, efa, efa);
+ }
+}
+
+void mergeArcEdges(ReebGraph *rg, ReebArc *aDst, ReebArc *aSrc, MergeDirection direction)
+{
+ ReebEdge *e = NULL;
+
+ if (direction == MERGE_APPEND)
+ {
+ for(e = aSrc->edges.first; e; e = e->next)
+ {
+ e->arc = aDst; // Edge is stolen by new arc
+ }
+
+ addlisttolist(&aDst->edges , &aSrc->edges);
+ }
+ else
+ {
+ for(e = aSrc->edges.first; e; e = e->next)
+ {
+ ReebEdge *newEdge = copyEdge(e);
+
+ newEdge->arc = aDst;
+
+ BLI_addtail(&aDst->edges, newEdge);
+
+ if (direction == MERGE_LOWER)
+ {
+ void **p = BLI_edgehash_lookup_p(rg->emap, e->v1->index, e->v2->index);
+
+ newEdge->nextEdge = e;
+
+ // if edge was the first in the list, point the edit edge to the new reeb edge instead.
+ if (*p == e)
+ {
+ *p = (void*)newEdge;
+ }
+ // otherwise, advance in the list until the predecessor is found then insert it there
+ else
+ {
+ ReebEdge *previous = (ReebEdge*)*p;
+
+ while(previous->nextEdge != e)
+ {
+ previous = previous->nextEdge;
+ }
+
+ previous->nextEdge = newEdge;
+ }
+ }
+ else
+ {
+ newEdge->nextEdge = e->nextEdge;
+ e->nextEdge = newEdge;
+ }
+ }
+ }
+}
+
+// return 1 on full merge
+int mergeConnectedArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1)
+{
+ int result = 0;
+ ReebNode *removedNode = NULL;
+
+ a0->length += a1->length;
+
+ mergeArcEdges(rg, a0, a1, MERGE_APPEND);
+ mergeArcFaces(rg, a0, a1);
+
+ // Bring a0 to the combine length of both arcs
+ if (a0->tail == a1->head)
+ {
+ removedNode = a0->tail;
+ a0->tail = a1->tail;
+ }
+ else if (a0->head == a1->tail)
+ {
+ removedNode = a0->head;
+ a0->head = a1->head;
+ }
+
+ resizeArcBuckets(a0);
+ // Merge a1 in a0
+ mergeArcBuckets(a0, a1, a0->head->weight, a0->tail->weight);
+
+ // remove a1 from graph
+ BLI_remlink(&rg->arcs, a1);
+ REEB_freeArc((BArc*)a1);
+
+ BLI_removeNode((BGraph*)rg, (BNode*)removedNode);
+ result = 1;
+
+ return result;
+}
+// return 1 on full merge
+int mergeArcs(ReebGraph *rg, ReebArc *a0, ReebArc *a1)
+{
+ int result = 0;
+ // TRIANGLE POINTS DOWN
+ if (a0->head->weight == a1->head->weight) // heads are the same
+ {
+ if (a0->tail->weight == a1->tail->weight) // tails also the same, arcs can be totally merge together
+ {
+ mergeArcEdges(rg, a0, a1, MERGE_APPEND);
+ mergeArcFaces(rg, a0, a1);
+
+ mergeArcBuckets(a0, a1, a0->head->weight, a0->tail->weight);
+
+ // Adjust node degree
+ //a1->head->degree--;
+ NodeDegreeDecrement(rg, a1->head);
+ //a1->tail->degree--;
+ NodeDegreeDecrement(rg, a1->tail);
+
+ // remove a1 from graph
+ BLI_remlink(&rg->arcs, a1);
+
+ REEB_freeArc((BArc*)a1);
+ result = 1;
+ }
+ else if (a0->tail->weight > a1->tail->weight) // a1->tail->weight is in the middle
+ {
+ mergeArcEdges(rg, a1, a0, MERGE_LOWER);
+ mergeArcFaces(rg, a1, a0);
+
+ // Adjust node degree
+ //a0->head->degree--;
+ NodeDegreeDecrement(rg, a0->head);
+ //a1->tail->degree++;
+ NodeDegreeIncrement(rg, a1->tail);
+
+ mergeArcBuckets(a1, a0, a1->head->weight, a1->tail->weight);
+ a0->head = a1->tail;
+ resizeArcBuckets(a0);
+ }
+ else // a0>n2 is in the middle
+ {
+ mergeArcEdges(rg, a0, a1, MERGE_LOWER);
+ mergeArcFaces(rg, a0, a1);
+
+ // Adjust node degree
+ //a1->head->degree--;
+ NodeDegreeDecrement(rg, a1->head);
+ //a0->tail->degree++;
+ NodeDegreeIncrement(rg, a0->tail);
+
+ mergeArcBuckets(a0, a1, a0->head->weight, a0->tail->weight);
+ a1->head = a0->tail;
+ resizeArcBuckets(a1);
+ }
+ }
+ // TRIANGLE POINTS UP
+ else if (a0->tail->weight == a1->tail->weight) // tails are the same
+ {
+ if (a0->head->weight > a1->head->weight) // a0->head->weight is in the middle
+ {
+ mergeArcEdges(rg, a0, a1, MERGE_HIGHER);
+ mergeArcFaces(rg, a0, a1);
+
+ // Adjust node degree
+ //a1->tail->degree--;
+ NodeDegreeDecrement(rg, a1->tail);
+ //a0->head->degree++;
+ NodeDegreeIncrement(rg, a0->head);
+
+ mergeArcBuckets(a0, a1, a0->head->weight, a0->tail->weight);
+ a1->tail = a0->head;
+ resizeArcBuckets(a1);
+ }
+ else // a1->head->weight is in the middle
+ {
+ mergeArcEdges(rg, a1, a0, MERGE_HIGHER);
+ mergeArcFaces(rg, a1, a0);
+
+ // Adjust node degree
+ //a0->tail->degree--;
+ NodeDegreeDecrement(rg, a0->tail);
+ //a1->head->degree++;
+ NodeDegreeIncrement(rg, a1->head);
+
+ mergeArcBuckets(a1, a0, a1->head->weight, a1->tail->weight);
+ a0->tail = a1->head;
+ resizeArcBuckets(a0);
+ }
+ }
+ else
+ {
+ // Need something here (OR NOT)
+ }
+
+ return result;
+}
+
+void glueByMergeSort(ReebGraph *rg, ReebArc *a0, ReebArc *a1, ReebEdge *e0, ReebEdge *e1)
+{
+ int total = 0;
+ while (total == 0 && a0 != a1 && a0 != NULL && a1 != NULL)
+ {
+ total = mergeArcs(rg, a0, a1);
+
+ if (total == 0) // if it wasn't a total merge, go forward
+ {
+ if (a0->tail->weight < a1->tail->weight)
+ {
+ a0 = nextArcMappedToEdge(a0, e0);
+ }
+ else
+ {
+ a1 = nextArcMappedToEdge(a1, e1);
+ }
+ }
+ }
+}
+
+void mergePaths(ReebGraph *rg, ReebEdge *e0, ReebEdge *e1, ReebEdge *e2)
+{
+ ReebArc *a0, *a1, *a2;
+ a0 = e0->arc;
+ a1 = e1->arc;
+ a2 = e2->arc;
+
+ glueByMergeSort(rg, a0, a1, e0, e1);
+ glueByMergeSort(rg, a0, a2, e0, e2);
+}
+
+ReebEdge * createArc(ReebGraph *rg, ReebNode *node1, ReebNode *node2)
+{
+ ReebEdge *edge;
+
+ edge = BLI_edgehash_lookup(rg->emap, node1->index, node2->index);
+
+ // Only add existing edges that haven't been added yet
+ if (edge == NULL)
+ {
+ ReebArc *arc;
+ ReebNode *v1, *v2;
+ float len, offset;
+ int i;
+
+ arc = MEM_callocN(sizeof(ReebArc), "reeb arc");
+ edge = MEM_callocN(sizeof(ReebEdge), "reeb edge");
+
+ arc->flag = 0; // clear flag on init
+ arc->symmetry_level = 0;
+ arc->faces = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+ if (node1->weight <= node2->weight)
+ {
+ v1 = node1;
+ v2 = node2;
+ }
+ else
+ {
+ v1 = node2;
+ v2 = node1;
+ }
+
+ arc->head = v1;
+ arc->tail = v2;
+
+ // increase node degree
+ //v1->degree++;
+ NodeDegreeIncrement(rg, v1);
+ //v2->degree++;
+ NodeDegreeIncrement(rg, v2);
+
+ BLI_edgehash_insert(rg->emap, node1->index, node2->index, edge);
+
+ edge->arc = arc;
+ edge->nextEdge = NULL;
+ edge->v1 = v1;
+ edge->v2 = v2;
+
+ BLI_addtail(&rg->arcs, arc);
+ BLI_addtail(&arc->edges, edge);
+
+ /* adding buckets for embedding */
+ allocArcBuckets(arc);
+
+ offset = arc->head->weight;
+ len = arc->tail->weight - arc->head->weight;
+
+#if 0
+ /* This is the actual embedding filling described in the paper
+ * the problem is that it only works with really dense meshes
+ */
+ if (arc->bcount > 0)
+ {
+ addVertToBucket(&(arc->buckets[0]), arc->head->co);
+ addVertToBucket(&(arc->buckets[arc->bcount - 1]), arc->tail->co);
+ }
+#else
+ for(i = 0; i < arc->bcount; i++)
+ {
+ float co[3];
+ float f = (arc->buckets[i].val - offset) / len;
+
+ VecLerpf(co, v1->p, v2->p, f);
+ addVertToBucket(&(arc->buckets[i]), co);
+ }
+#endif
+
+ }
+
+ return edge;
+}
+
+void addTriangleToGraph(ReebGraph *rg, ReebNode * n1, ReebNode * n2, ReebNode * n3, EditFace *efa)
+{
+ ReebEdge *re1, *re2, *re3;
+ ReebEdge *e1, *e2, *e3;
+ float len1, len2, len3;
+
+ re1 = createArc(rg, n1, n2);
+ re2 = createArc(rg, n2, n3);
+ re3 = createArc(rg, n3, n1);
+
+ addFacetoArc(re1->arc, efa);
+ addFacetoArc(re2->arc, efa);
+ addFacetoArc(re3->arc, efa);
+
+ len1 = (float)fabs(n1->weight - n2->weight);
+ len2 = (float)fabs(n2->weight - n3->weight);
+ len3 = (float)fabs(n3->weight - n1->weight);
+
+ /* The rest of the algorithm assumes that e1 is the longest edge */
+
+ if (len1 >= len2 && len1 >= len3)
+ {
+ e1 = re1;
+ e2 = re2;
+ e3 = re3;
+ }
+ else if (len2 >= len1 && len2 >= len3)
+ {
+ e1 = re2;
+ e2 = re1;
+ e3 = re3;
+ }
+ else
+ {
+ e1 = re3;
+ e2 = re2;
+ e3 = re1;
+ }
+
+ /* And e2 is the lowest edge
+ * If e3 is lower than e2, swap them
+ */
+ if (e3->v1->weight < e2->v1->weight)
+ {
+ ReebEdge *etmp = e2;
+ e2 = e3;
+ e3 = etmp;
+ }
+
+
+ mergePaths(rg, e1, e2, e3);
+}
+
+ReebGraph * generateReebGraph(EditMesh *em, int subdivisions)
+{
+ ReebGraph *rg;
+ EditVert *eve;
+ EditFace *efa;
+ int index;
+ int totvert;
+ int totfaces;
+
+#ifdef DEBUG_REEB
+ int countfaces = 0;
+#endif
+
+ rg = newReebGraph();
+
+ rg->resolution = subdivisions;
+
+ totvert = BLI_countlist(&em->verts);
+ totfaces = BLI_countlist(&em->faces);
+
+ renormalizeWeight(em, 1.0f);
+
+ /* Spread weight to minimize errors */
+ spreadWeight(em);
+
+ renormalizeWeight(em, (float)rg->resolution);
+
+ /* Adding vertice */
+ for(index = 0, eve = em->verts.first; eve; eve = eve->next)
+ {
+ if (eve->h == 0)
+ {
+ addNode(rg, eve);
+ eve->f2 = 0;
+ index++;
+ }
+ }
+
+ /* Adding face, edge per edge */
+ for(efa = em->faces.first; efa; efa = efa->next)
+ {
+ if (efa->h == 0)
+ {
+ ReebNode *n1, *n2, *n3;
+
+ n1 = nodeData(efa->v1);
+ n2 = nodeData(efa->v2);
+ n3 = nodeData(efa->v3);
+
+ addTriangleToGraph(rg, n1, n2, n3, efa);
+
+ if (efa->v4)
+ {
+ ReebNode *n4 = nodeData(efa->v4);
+ addTriangleToGraph(rg, n1, n3, n4, efa);
+ }
+#ifdef DEBUG_REEB
+ countfaces++;
+ if (countfaces % 100 == 0)
+ {
+ printf("\rface %i of %i", countfaces, totfaces);
+ }
+#endif
+ }
+ }
+
+ printf("\n");
+
+ removeZeroNodes(rg);
+
+ removeNormalNodes(rg);
+
+ return rg;
+}
+
+/***************************************** WEIGHT UTILS **********************************************/
+
+void renormalizeWeight(EditMesh *em, float newmax)
+{
+ EditVert *eve;
+ float minimum, maximum, range;
+
+ if (em == NULL || BLI_countlist(&em->verts) == 0)
+ return;
+
+ /* First pass, determine maximum and minimum */
+ eve = em->verts.first;
+ minimum = weightData(eve);
+ maximum = minimum;
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ maximum = MAX2(maximum, weightData(eve));
+ minimum = MIN2(minimum, weightData(eve));
+ }
+
+ range = maximum - minimum;
+
+ /* Normalize weights */
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ float weight = (weightData(eve) - minimum) / range * newmax;
+ weightSetData(eve, weight);
+ }
+}
+
+
+int weightFromLoc(EditMesh *em, int axis)
+{
+ EditVert *eve;
+
+ if (em == NULL || BLI_countlist(&em->verts) == 0 || axis < 0 || axis > 2)
+ return 0;
+
+ /* Copy coordinate in weight */
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ weightSetData(eve, eve->co[axis]);
+ }
+
+ return 1;
+}
+
+static float cotan_weight(float *v1, float *v2, float *v3)
+{
+ float a[3], b[3], c[3], clen;
+
+ VecSubf(a, v2, v1);
+ VecSubf(b, v3, v1);
+ Crossf(c, a, b);
+
+ clen = VecLength(c);
+
+ if (clen == 0.0f)
+ return 0.0f;
+
+ return Inpf(a, b)/clen;
+}
+
+void addTriangle(EditVert *v1, EditVert *v2, EditVert *v3, long e1, long e2, long e3)
+{
+ /* Angle opposite e1 */
+ float t1= cotan_weight(v1->co, v2->co, v3->co) / e2;
+
+ /* Angle opposite e2 */
+ float t2 = cotan_weight(v2->co, v3->co, v1->co) / e3;
+
+ /* Angle opposite e3 */
+ float t3 = cotan_weight(v3->co, v1->co, v2->co) / e1;
+
+ int i1 = indexData(v1);
+ int i2 = indexData(v2);
+ int i3 = indexData(v3);
+
+ nlMatrixAdd(i1, i1, t2+t3);
+ nlMatrixAdd(i2, i2, t1+t3);
+ nlMatrixAdd(i3, i3, t1+t2);
+
+ nlMatrixAdd(i1, i2, -t3);
+ nlMatrixAdd(i2, i1, -t3);
+
+ nlMatrixAdd(i2, i3, -t1);
+ nlMatrixAdd(i3, i2, -t1);
+
+ nlMatrixAdd(i3, i1, -t2);
+ nlMatrixAdd(i1, i3, -t2);
+}
+
+int weightToHarmonic(EditMesh *em, EdgeIndex *indexed_edges)
+{
+ NLboolean success;
+ EditVert *eve;
+ EditEdge *eed;
+ EditFace *efa;
+ int totvert = 0;
+ int index;
+ int rval;
+
+ /* Find local extrema */
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ totvert++;
+ }
+
+ /* Solve with openNL */
+
+ nlNewContext();
+
+ nlSolverParameteri(NL_NB_VARIABLES, totvert);
+
+ nlBegin(NL_SYSTEM);
+
+ /* Find local extrema */
+ for(index = 0, eve = em->verts.first; eve; index++, eve = eve->next)
+ {
+ if (eve->h == 0)
+ {
+ EditEdge *eed;
+ int maximum = 1;
+ int minimum = 1;
+
+ NextEdgeForVert(indexed_edges, -1); /* Reset next edge */
+ for(eed = NextEdgeForVert(indexed_edges, index); eed && (maximum || minimum); eed = NextEdgeForVert(indexed_edges, index))
+ {
+ EditVert *eve2;
+
+ if (eed->v1 == eve)
+ {
+ eve2 = eed->v2;
+ }
+ else
+ {
+ eve2 = eed->v1;
+ }
+
+ if (eve2->h == 0)
+ {
+ /* Adjacent vertex is bigger, not a local maximum */
+ if (weightData(eve2) > weightData(eve))
+ {
+ maximum = 0;
+ }
+ /* Adjacent vertex is smaller, not a local minimum */
+ else if (weightData(eve2) < weightData(eve))
+ {
+ minimum = 0;
+ }
+ }
+ }
+
+ if (maximum || minimum)
+ {
+ float w = weightData(eve);
+ eve->f1 = 0;
+ nlSetVariable(0, index, w);
+ nlLockVariable(index);
+ }
+ else
+ {
+ eve->f1 = 1;
+ }
+ }
+ }
+
+ nlBegin(NL_MATRIX);
+
+ /* Zero edge weight */
+ for(eed = em->edges.first; eed; eed = eed->next)
+ {
+ eed->tmp.l = 0;
+ }
+
+ /* Add faces count to the edge weight */
+ for(efa = em->faces.first; efa; efa = efa->next)
+ {
+ if (efa->h == 0)
+ {
+ efa->e1->tmp.l++;
+ efa->e2->tmp.l++;
+ efa->e3->tmp.l++;
+
+ if (efa->e4)
+ {
+ efa->e4->tmp.l++;
+ }
+ }
+ }
+
+ /* Add faces angle to the edge weight */
+ for(efa = em->faces.first; efa; efa = efa->next)
+ {
+ if (efa->h == 0)
+ {
+ if (efa->v4 == NULL)
+ {
+ addTriangle(efa->v1, efa->v2, efa->v3, efa->e1->tmp.l, efa->e2->tmp.l, efa->e3->tmp.l);
+ }
+ else
+ {
+ addTriangle(efa->v1, efa->v2, efa->v3, efa->e1->tmp.l, efa->e2->tmp.l, 2);
+ addTriangle(efa->v3, efa->v4, efa->v1, efa->e3->tmp.l, efa->e4->tmp.l, 2);
+ }
+ }
+ }
+
+ nlEnd(NL_MATRIX);
+
+ nlEnd(NL_SYSTEM);
+
+ success = nlSolveAdvanced(NULL, NL_TRUE);
+
+ if (success)
+ {
+ rval = 1;
+ for(index = 0, eve = em->verts.first; eve; index++, eve = eve->next)
+ {
+ weightSetData(eve, nlGetVariable(0, index));
+ }
+ }
+ else
+ {
+ rval = 0;
+ }
+
+ nlDeleteContext(nlGetCurrent());
+
+ return rval;
+}
+
+
+EditEdge * NextEdgeForVert(EdgeIndex *indexed_edges, int index)
+{
+ static int offset = -1;
+
+ /* Reset method, call with NULL mesh pointer */
+ if (index == -1)
+ {
+ offset = -1;
+ return NULL;
+ }
+
+ /* first pass, start at the head of the list */
+ if (offset == -1)
+ {
+ offset = indexed_edges->offset[index];
+ }
+ /* subsequent passes, start on the next edge */
+ else
+ {
+ offset++;
+ }
+
+ return indexed_edges->edges[offset];
+}
+
+void shortestPathsFromVert(EditMesh *em, EditVert *starting_vert, EdgeIndex *indexed_edges)
+{
+ Heap *edge_heap;
+ EditVert *current_eve = NULL;
+ EditEdge *eed = NULL;
+ EditEdge *select_eed = NULL;
+
+ edge_heap = BLI_heap_new();
+
+ current_eve = starting_vert;
+
+ /* insert guard in heap, when that is returned, no more edges */
+ BLI_heap_insert(edge_heap, FLT_MAX, NULL);
+
+ /* Initialize edge flag */
+ for(eed= em->edges.first; eed; eed= eed->next)
+ {
+ eed->f1 = 0;
+ }
+
+ while (BLI_heap_size(edge_heap) > 0)
+ {
+ float current_weight;
+
+ current_eve->f1 = 1; /* mark vertex as selected */
+
+ /* Add all new edges connected to current_eve to the list */
+ NextEdgeForVert(indexed_edges, -1); // Reset next edge
+ for(eed = NextEdgeForVert(indexed_edges, indexData(current_eve)); eed; eed = NextEdgeForVert(indexed_edges, indexData(current_eve)))
+ {
+ if (eed->f1 == 0)
+ {
+ BLI_heap_insert(edge_heap, weightData(current_eve) + eed->tmp.fp, eed);
+ eed->f1 = 1;
+ }
+ }
+
+ /* Find next shortest edge with unselected verts */
+ do
+ {
+ current_weight = BLI_heap_node_value(BLI_heap_top(edge_heap));
+ select_eed = BLI_heap_popmin(edge_heap);
+ } while (select_eed != NULL && select_eed->v1->f1 != 0 && select_eed->v2->f1);
+
+ if (select_eed != NULL)
+ {
+ select_eed->f1 = 2;
+
+ if (select_eed->v1->f1 == 0) /* v1 is the new vertex */
+ {
+ current_eve = select_eed->v1;
+ }
+ else /* otherwise, it's v2 */
+ {
+ current_eve = select_eed->v2;
+ }
+
+ weightSetData(current_eve, current_weight);
+ }
+ }
+
+ BLI_heap_free(edge_heap, NULL);
+}
+
+void freeEdgeIndex(EdgeIndex *indexed_edges)
+{
+ MEM_freeN(indexed_edges->offset);
+ MEM_freeN(indexed_edges->edges);
+}
+
+void buildIndexedEdges(EditMesh *em, EdgeIndex *indexed_edges)
+{
+ EditVert *eve;
+ EditEdge *eed;
+ int totvert = 0;
+ int tot_indexed = 0;
+ int offset = 0;
+
+ totvert = BLI_countlist(&em->verts);
+
+ indexed_edges->offset = MEM_callocN(totvert * sizeof(int), "EdgeIndex offset");
+
+ for(eed = em->edges.first; eed; eed = eed->next)
+ {
+ if (eed->v1->h == 0 && eed->v2->h == 0)
+ {
+ tot_indexed += 2;
+ indexed_edges->offset[indexData(eed->v1)]++;
+ indexed_edges->offset[indexData(eed->v2)]++;
+ }
+ }
+
+ tot_indexed += totvert;
+
+ indexed_edges->edges = MEM_callocN(tot_indexed * sizeof(EditEdge*), "EdgeIndex edges");
+
+ /* setting vert offsets */
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ if (eve->h == 0)
+ {
+ int d = indexed_edges->offset[indexData(eve)];
+ indexed_edges->offset[indexData(eve)] = offset;
+ offset += d + 1;
+ }
+ }
+
+ /* adding edges in array */
+ for(eed = em->edges.first; eed; eed= eed->next)
+ {
+ if (eed->v1->h == 0 && eed->v2->h == 0)
+ {
+ int i;
+ for (i = indexed_edges->offset[indexData(eed->v1)]; i < tot_indexed; i++)
+ {
+ if (indexed_edges->edges[i] == NULL)
+ {
+ indexed_edges->edges[i] = eed;
+ break;
+ }
+ }
+
+ for (i = indexed_edges->offset[indexData(eed->v2)]; i < tot_indexed; i++)
+ {
+ if (indexed_edges->edges[i] == NULL)
+ {
+ indexed_edges->edges[i] = eed;
+ break;
+ }
+ }
+ }
+ }
+}
+
+int weightFromDistance(EditMesh *em, EdgeIndex *indexed_edges)
+{
+ EditVert *eve;
+ int totedge = 0;
+ int totvert = 0;
+ int vCount = 0;
+
+ totvert = BLI_countlist(&em->verts);
+
+ if (em == NULL || totvert == 0)
+ {
+ return 0;
+ }
+
+ totedge = BLI_countlist(&em->edges);
+
+ if (totedge == 0)
+ {
+ return 0;
+ }
+
+ /* Initialize vertice flag and find at least one selected vertex */
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ eve->f1 = 0;
+ if (eve->f & SELECT)
+ {
+ vCount = 1;
+ }
+ }
+
+ if (vCount == 0)
+ {
+ return 0; /* no selected vert, failure */
+ }
+ else
+ {
+ EditEdge *eed;
+ int allDone = 0;
+
+ /* Calculate edge weight */
+ for(eed = em->edges.first; eed; eed= eed->next)
+ {
+ if (eed->v1->h == 0 && eed->v2->h == 0)
+ {
+ eed->tmp.fp = VecLenf(eed->v1->co, eed->v2->co);
+ }
+ }
+
+ /* Apply dijkstra spf for each selected vert */
+ for(eve = em->verts.first; eve; eve = eve->next)
+ {
+ if (eve->f & SELECT)
+ {
+ shortestPathsFromVert(em, eve, indexed_edges);
+ }
+ }
+
+ /* connect unselected islands */
+ while (allDone == 0)
+ {
+ EditVert *selected_eve = NULL;
+ float selected_weight = 0;
+ float min_distance = FLT_MAX;
+
+ allDone = 1;
+
+ for (eve = em->verts.first; eve; eve = eve->next)
+ {
+ /* for every vertex visible that hasn't been processed yet */
+ if (eve->h == 0 && eve->f1 != 1)
+ {
+ EditVert *closest_eve;
+
+ /* find the closest processed vertex */
+ for (closest_eve = em->verts.first; closest_eve; closest_eve = closest_eve->next)
+ {
+ /* vertex is already processed and distance is smaller than current minimum */
+ if (closest_eve->f1 == 1)
+ {
+ float distance = VecLenf(closest_eve->co, eve->co);
+ if (distance < min_distance)
+ {
+ min_distance = distance;
+ selected_eve = eve;
+ selected_weight = weightData(closest_eve);
+ }
+ }
+ }
+ }
+ }
+
+ if (selected_eve)
+ {
+ allDone = 0;
+
+ weightSetData(selected_eve, selected_weight + min_distance);
+ shortestPathsFromVert(em, selected_eve, indexed_edges);
+ }
+ }
+ }
+
+ for(eve = em->verts.first; eve && vCount == 0; eve = eve->next)
+ {
+ if (eve->f1 == 0)
+ {
+ printf("vertex not reached\n");
+ break;
+ }
+ }
+
+ return 1;
+}
+
+/****************************************** BUCKET ITERATOR **************************************************/
+
+static void* headNode(void *arg);
+static void* tailNode(void *arg);
+static void* nextBucket(void *arg);
+static void* nextNBucket(void *arg, int n);
+static void* peekBucket(void *arg, int n);
+static void* previousBucket(void *arg);
+static int iteratorStopped(void *arg);
+
+static void initIteratorFct(ReebArcIterator *iter)
+{
+ iter->head = headNode;
+ iter->tail = tailNode;
+ iter->peek = peekBucket;
+ iter->next = nextBucket;
+ iter->nextN = nextNBucket;
+ iter->previous = previousBucket;
+ iter->stopped = iteratorStopped;
+}
+
+static void setIteratorValues(ReebArcIterator *iter, EmbedBucket *bucket)
+{
+ if (bucket)
+ {
+ iter->p = bucket->p;
+ iter->no = bucket->no;
+ }
+ else
+ {
+ iter->p = NULL;
+ iter->no = NULL;
+ }
+}
+
+void initArcIterator(BArcIterator *arg, ReebArc *arc, ReebNode *head)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+
+ initIteratorFct(iter);
+ iter->arc = arc;
+
+ if (head == arc->head)
+ {
+ iter->start = 0;
+ iter->end = arc->bcount - 1;
+ iter->stride = 1;
+ }
+ else
+ {
+ iter->start = arc->bcount - 1;
+ iter->end = 0;
+ iter->stride = -1;
+ }
+
+ iter->length = arc->bcount;
+
+ iter->index = -1;
+}
+
+void initArcIteratorStart(BArcIterator *arg, struct ReebArc *arc, struct ReebNode *head, int start)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+
+ initIteratorFct(iter);
+ iter->arc = arc;
+
+ if (head == arc->head)
+ {
+ iter->start = start;
+ iter->end = arc->bcount - 1;
+ iter->stride = 1;
+ }
+ else
+ {
+ iter->start = arc->bcount - 1 - start;
+ iter->end = 0;
+ iter->stride = -1;
+ }
+
+ iter->index = -1;
+
+ iter->length = arc->bcount - start;
+
+ if (start >= arc->bcount)
+ {
+ iter->start = iter->end; /* stop iterator since it's past its end */
+ }
+}
+
+void initArcIterator2(BArcIterator *arg, ReebArc *arc, int start, int end)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+
+ initIteratorFct(iter);
+ iter->arc = arc;
+
+ iter->start = start;
+ iter->end = end;
+
+ if (end > start)
+ {
+ iter->stride = 1;
+ }
+ else
+ {
+ iter->stride = -1;
+ }
+
+ iter->index = -1;
+
+ iter->length = abs(iter->end - iter->start) + 1;
+}
+
+static void* headNode(void *arg)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+ ReebNode *node;
+
+ if (iter->start < iter->end)
+ {
+ node = iter->arc->head;
+ }
+ else
+ {
+ node = iter->arc->tail;
+ }
+
+ iter->p = node->p;
+ iter->no = node->no;
+
+ return node;
+}
+
+static void* tailNode(void *arg)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+ ReebNode *node;
+
+ if (iter->start < iter->end)
+ {
+ node = iter->arc->tail;
+ }
+ else
+ {
+ node = iter->arc->head;
+ }
+
+ iter->p = node->p;
+ iter->no = node->no;
+
+ return node;
+}
+
+static void* nextBucket(void *arg)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+ EmbedBucket *result = NULL;
+
+ iter->index++;
+
+ if (iter->index < iter->length)
+ {
+ result = &(iter->arc->buckets[iter->start + (iter->stride * iter->index)]);
+ }
+
+ setIteratorValues(iter, result);
+ return result;
+}
+
+static void* nextNBucket(void *arg, int n)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+ EmbedBucket *result = NULL;
+
+ iter->index += n;
+
+ /* check if passed end */
+ if (iter->index < iter->length)
+ {
+ result = &(iter->arc->buckets[iter->start + (iter->stride * iter->index)]);
+ }
+
+ setIteratorValues(iter, result);
+ return result;
+}
+
+static void* peekBucket(void *arg, int n)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+ EmbedBucket *result = NULL;
+ int index = iter->index + n;
+
+ /* check if passed end */
+ if (index < iter->length)
+ {
+ result = &(iter->arc->buckets[iter->start + (iter->stride * index)]);
+ }
+
+ setIteratorValues(iter, result);
+ return result;
+}
+
+static void* previousBucket(void *arg)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+ EmbedBucket *result = NULL;
+
+ if (iter->index > 0)
+ {
+ iter->index--;
+ result = &(iter->arc->buckets[iter->start + (iter->stride * iter->index)]);
+ }
+
+ setIteratorValues(iter, result);
+ return result;
+}
+
+static int iteratorStopped(void *arg)
+{
+ ReebArcIterator *iter = (ReebArcIterator*)arg;
+
+ if (iter->index >= iter->length)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/************************ PUBLIC FUNCTIONS *********************************************/
+
+ReebGraph *BIF_ReebGraphMultiFromEditMesh(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ EditMesh *em =( (Mesh*)obedit->data)->edit_mesh;
+ EdgeIndex indexed_edges;
+ VertexData *data;
+ ReebGraph *rg = NULL;
+ ReebGraph *rgi, *previous;
+ int i, nb_levels = REEB_MAX_MULTI_LEVEL;
+
+ if (em == NULL)
+ return NULL;
+
+ data = allocVertexData(em);
+
+ buildIndexedEdges(em, &indexed_edges);
+
+ if (weightFromDistance(em, &indexed_edges) == 0)
+ {
+ error("No selected vertex\n");
+ freeEdgeIndex(&indexed_edges);
+ return NULL;
+ }
+
+ renormalizeWeight(em, 1.0f);
+
+ if (scene->toolsettings->skgen_options & SKGEN_HARMONIC)
+ {
+ weightToHarmonic(em, &indexed_edges);
+ }
+
+ freeEdgeIndex(&indexed_edges);
+
+ rg = generateReebGraph(em, scene->toolsettings->skgen_resolution);
+
+ /* Remove arcs without embedding */
+ filterNullReebGraph(rg);
+
+ /* smart filter and loop filter on basic level */
+ filterGraph(rg, SKGEN_FILTER_SMART, 0, 0);
+
+ repositionNodes(rg);
+
+ /* Filtering might have created degree 2 nodes, so remove them */
+ removeNormalNodes(rg);
+
+ joinSubgraphs(rg, 1.0);
+
+ BLI_buildAdjacencyList((BGraph*)rg);
+
+ /* calc length before copy, so we have same length on all levels */
+ BLI_calcGraphLength((BGraph*)rg);
+
+ previous = NULL;
+ for (i = 0; i <= nb_levels; i++)
+ {
+ rgi = rg;
+
+ /* don't filter last level */
+ if (i > 0)
+ {
+ float internal_threshold;
+ float external_threshold;
+
+ /* filter internal progressively in second half only*/
+ if (i > nb_levels / 2)
+ {
+ internal_threshold = rg->length * scene->toolsettings->skgen_threshold_internal;
+ }
+ else
+ {
+ internal_threshold = rg->length * scene->toolsettings->skgen_threshold_internal * (2 * i / (float)nb_levels);
+ }
+
+ external_threshold = rg->length * scene->toolsettings->skgen_threshold_external * (i / (float)nb_levels);
+
+ filterGraph(rgi, scene->toolsettings->skgen_options, internal_threshold, external_threshold);
+ }
+
+ if (i < nb_levels)
+ {
+ rg = copyReebGraph(rgi, i + 1);
+ }
+
+ finalizeGraph(rgi, scene->toolsettings->skgen_postpro_passes, scene->toolsettings->skgen_postpro);
+
+ BLI_markdownSymmetry((BGraph*)rgi, rgi->nodes.first, scene->toolsettings->skgen_symmetry_limit);
+
+ if (previous != NULL)
+ {
+ relinkNodes(rgi, previous);
+ }
+ previous = rgi;
+ }
+
+ verifyMultiResolutionLinks(rg, 0);
+
+ MEM_freeN(data);
+
+ return rg;
+}
+
+#if 0
+
+ReebGraph *BIF_ReebGraphFromEditMesh(void)
+{
+ EditMesh *em = G.editMesh;
+ EdgeIndex indexed_edges;
+ VertexData *data;
+ ReebGraph *rg = NULL;
+
+ if (em == NULL)
+ return NULL;
+
+ data = allocVertexData(em);
+
+ buildIndexedEdges(em, &indexed_edges);
+
+ if (weightFromDistance(em, &indexed_edges) == 0)
+ {
+ error("No selected vertex\n");
+ freeEdgeIndex(&indexed_edges);
+ freeEdgeIndex(&indexed_edges);
+ return NULL;
+ }
+
+ renormalizeWeight(em, 1.0f);
+
+ if (G.scene->toolsettings->skgen_options & SKGEN_HARMONIC)
+ {
+ weightToHarmonic(em, &indexed_edges);
+ }
+
+ freeEdgeIndex(&indexed_edges);
+
+#ifdef DEBUG_REEB
+ weightToVCol(em, 1);
+#endif
+
+ rg = generateReebGraph(em, G.scene->toolsettings->skgen_resolution);
+
+
+ /* Remove arcs without embedding */
+ filterNullReebGraph(rg);
+
+ /* smart filter and loop filter on basic level */
+ filterGraph(rg, SKGEN_FILTER_SMART, 0, 0);
+
+ repositionNodes(rg);
+
+ /* Filtering might have created degree 2 nodes, so remove them */
+ removeNormalNodes(rg);
+
+ joinSubgraphs(rg, 1.0);
+
+ BLI_buildAdjacencyList((BGraph*)rg);
+
+ /* calc length before copy, so we have same length on all levels */
+ BLI_calcGraphLength((BGraph*)rg);
+
+ filterGraph(rg, G.scene->toolsettings->skgen_options, G.scene->toolsettings->skgen_threshold_internal, G.scene->toolsettings->skgen_threshold_external);
+
+ finalizeGraph(rg, G.scene->toolsettings->skgen_postpro_passes, G.scene->toolsettings->skgen_postpro);
+
+#ifdef DEBUG_REEB
+ REEB_exportGraph(rg, -1);
+
+ arcToVCol(rg, em, 0);
+ //angleToVCol(em, 1);
+#endif
+
+ printf("DONE\n");
+ printf("%i subgraphs\n", BLI_FlagSubgraphs((BGraph*)rg));
+
+ MEM_freeN(data);
+
+ return rg;
+}
+
+void BIF_GlobalReebFree()
+{
+ if (GLOBAL_RG != NULL)
+ {
+ REEB_freeGraph(GLOBAL_RG);
+ GLOBAL_RG = NULL;
+ }
+}
+
+void BIF_GlobalReebGraphFromEditMesh(void)
+{
+ ReebGraph *rg;
+
+ BIF_GlobalReebFree();
+
+ rg = BIF_ReebGraphMultiFromEditMesh();
+
+ GLOBAL_RG = rg;
+}
+
+void REEB_draw()
+{
+ ReebGraph *rg;
+ ReebArc *arc;
+ int i = 0;
+
+ if (GLOBAL_RG == NULL)
+ {
+ return;
+ }
+
+ if (GLOBAL_RG->link_up && G.scene->toolsettings->skgen_options & SKGEN_DISP_ORIG)
+ {
+ for (rg = GLOBAL_RG; rg->link_up; rg = rg->link_up) ;
+ }
+ else
+ {
+ i = G.scene->toolsettings->skgen_multi_level;
+
+ for (rg = GLOBAL_RG; rg->multi_level != i && rg->link_up; rg = rg->link_up) ;
+ }
+
+ glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
+
+ glDisable(GL_DEPTH_TEST);
+ for (arc = rg->arcs.first; arc; arc = arc->next, i++)
+ {
+ ReebArcIterator arc_iter;
+ BArcIterator *iter = (BArcIterator*)&arc_iter;
+ float vec[3];
+ char text[128];
+ char *s = text;
+
+ glLineWidth(BIF_GetThemeValuef(TH_VERTEX_SIZE) + 2);
+ glColor3f(0, 0, 0);
+ glBegin(GL_LINE_STRIP);
+ glVertex3fv(arc->head->p);
+
+ if (arc->bcount)
+ {
+ initArcIterator(iter, arc, arc->head);
+ for (IT_next(iter); IT_stopped(iter) == 0; IT_next(iter))
+ {
+ glVertex3fv(iter->p);
+ }
+ }
+
+ glVertex3fv(arc->tail->p);
+ glEnd();
+
+ glLineWidth(BIF_GetThemeValuef(TH_VERTEX_SIZE));
+
+ if (arc->symmetry_level == 1)
+ {
+ glColor3f(1, 0, 0);
+ }
+ else if (arc->symmetry_flag == SYM_SIDE_POSITIVE || arc->symmetry_flag == SYM_SIDE_NEGATIVE)
+ {
+ glColor3f(1, 0.5f, 0);
+ }
+ else if (arc->symmetry_flag >= SYM_SIDE_RADIAL)
+ {
+ glColor3f(0.5f, 1, 0);
+ }
+ else
+ {
+ glColor3f(1, 1, 0);
+ }
+ glBegin(GL_LINE_STRIP);
+ glVertex3fv(arc->head->p);
+
+ if (arc->bcount)
+ {
+ initArcIterator(iter, arc, arc->head);
+ for (iter->next(iter); IT_stopped(iter) == 0; iter->next(iter))
+ {
+ glVertex3fv(iter->p);
+ }
+ }
+
+ glVertex3fv(arc->tail->p);
+ glEnd();
+
+
+ if (G.scene->toolsettings->skgen_options & SKGEN_DISP_EMBED)
+ {
+ glColor3f(1, 1, 1);
+ glBegin(GL_POINTS);
+ glVertex3fv(arc->head->p);
+ glVertex3fv(arc->tail->p);
+
+ glColor3f(0.5f, 0.5f, 1);
+ if (arc->bcount)
+ {
+ initArcIterator(iter, arc, arc->head);
+ for (iter->next(iter); IT_stopped(iter) == 0; iter->next(iter))
+ {
+ glVertex3fv(iter->p);
+ }
+ }
+ glEnd();
+ }
+
+ if (G.scene->toolsettings->skgen_options & SKGEN_DISP_INDEX)
+ {
+ VecLerpf(vec, arc->head->p, arc->tail->p, 0.5f);
+ s += sprintf(s, "%i (%i-%i-%i) ", i, arc->symmetry_level, arc->symmetry_flag, arc->symmetry_group);
+
+ if (G.scene->toolsettings->skgen_options & SKGEN_DISP_WEIGHT)
+ {
+ s += sprintf(s, "w:%0.3f ", arc->tail->weight - arc->head->weight);
+ }
+
+ if (G.scene->toolsettings->skgen_options & SKGEN_DISP_LENGTH)
+ {
+ s += sprintf(s, "l:%0.3f", arc->length);
+ }
+
+ glColor3f(0, 1, 0);
+ glRasterPos3fv(vec);
+ BMF_DrawString( G.fonts, text);
+ }
+
+ if (G.scene->toolsettings->skgen_options & SKGEN_DISP_INDEX)
+ {
+ sprintf(text, " %i", arc->head->index);
+ glRasterPos3fv(arc->head->p);
+ BMF_DrawString( G.fonts, text);
+
+ sprintf(text, " %i", arc->tail->index);
+ glRasterPos3fv(arc->tail->p);
+ BMF_DrawString( G.fonts, text);
+ }
+ }
+ glEnable(GL_DEPTH_TEST);
+
+ glLineWidth(1.0);
+ glPointSize(1.0);
+}
+
+#endif
diff --git a/source/blender/editors/armature/reeb.h b/source/blender/editors/armature/reeb.h
index c4c062196fc..3bdd55509ad 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);
@@ -168,8 +176,10 @@ void verifyFaces(ReebGraph *rg);
#define REEB_MAX_MULTI_LEVEL 10
+struct bContext;
+
ReebGraph *BIF_ReebGraphFromEditMesh(void);
-ReebGraph *BIF_ReebGraphMultiFromEditMesh(void);
+ReebGraph *BIF_ReebGraphMultiFromEditMesh(struct bContext *C);
void BIF_flagMultiArcs(ReebGraph *rg, int flag);
void BIF_GlobalReebGraphFromEditMesh(void);
@@ -182,6 +192,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/curve_intern.h b/source/blender/editors/curve/curve_intern.h
index bb7a5b500a7..71684ceae7a 100644
--- a/source/blender/editors/curve/curve_intern.h
+++ b/source/blender/editors/curve/curve_intern.h
@@ -45,11 +45,11 @@ void FONT_OT_insert_text(struct wmOperatorType *ot);
void FONT_OT_line_break(struct wmOperatorType *ot);
void FONT_OT_insert_lorem(struct wmOperatorType *ot);
-void FONT_OT_toggle_case(struct wmOperatorType *ot);
-void FONT_OT_set_case(struct wmOperatorType *ot);
-void FONT_OT_toggle_style(struct wmOperatorType *ot);
-void FONT_OT_set_style(struct wmOperatorType *ot);
-void FONT_OT_set_material(struct wmOperatorType *ot);
+void FONT_OT_case_toggle(struct wmOperatorType *ot);
+void FONT_OT_case_set(struct wmOperatorType *ot);
+void FONT_OT_style_toggle(struct wmOperatorType *ot);
+void FONT_OT_style_set(struct wmOperatorType *ot);
+void FONT_OT_material_set(struct wmOperatorType *ot);
void FONT_OT_copy_text(struct wmOperatorType *ot);
void FONT_OT_cut_text(struct wmOperatorType *ot);
@@ -72,20 +72,20 @@ void CURVE_OT_separate(struct wmOperatorType *ot);
void CURVE_OT_duplicate(struct wmOperatorType *ot);
void CURVE_OT_delete(struct wmOperatorType *ot);
-void CURVE_OT_set_weight(struct wmOperatorType *ot);
-void CURVE_OT_set_radius(struct wmOperatorType *ot);
-void CURVE_OT_set_spline_type(struct wmOperatorType *ot);
-void CURVE_OT_set_handle_type(struct wmOperatorType *ot);
-void CURVE_OT_set_smooth(struct wmOperatorType *ot);
-void CURVE_OT_clear_tilt(struct wmOperatorType *ot);
+void CURVE_OT_spline_type_set(struct wmOperatorType *ot);
+void CURVE_OT_radius_set(struct wmOperatorType *ot);
+void CURVE_OT_spline_weight_set(struct wmOperatorType *ot);
+void CURVE_OT_handle_type_set(struct wmOperatorType *ot);
+void CURVE_OT_smooth_set(struct wmOperatorType *ot);
+void CURVE_OT_tilt_clear(struct wmOperatorType *ot);
void CURVE_OT_smooth(struct wmOperatorType *ot);
void CURVE_OT_smooth_radius(struct wmOperatorType *ot);
void CURVE_OT_de_select_first(struct wmOperatorType *ot);
void CURVE_OT_de_select_last(struct wmOperatorType *ot);
-void CURVE_OT_de_select_all(struct wmOperatorType *ot);
-void CURVE_OT_select_inverse(struct wmOperatorType *ot);
+void CURVE_OT_select_all_toggle(struct wmOperatorType *ot);
+void CURVE_OT_select_invert(struct wmOperatorType *ot);
void CURVE_OT_select_linked(struct wmOperatorType *ot);
void CURVE_OT_select_row(struct wmOperatorType *ot);
void CURVE_OT_select_next(struct wmOperatorType *ot);
@@ -101,7 +101,7 @@ void CURVE_OT_make_segment(struct wmOperatorType *ot);
void CURVE_OT_spin(struct wmOperatorType *ot);
void CURVE_OT_add_vertex(struct wmOperatorType *ot);
void CURVE_OT_extrude(struct wmOperatorType *ot);
-void CURVE_OT_toggle_cyclic(struct wmOperatorType *ot);
+void CURVE_OT_cyclic_toggle(struct wmOperatorType *ot);
void CURVE_OT_specials_menu(struct wmOperatorType *ot);
diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c
index a53acb2e9b7..a0390fe1084 100644
--- a/source/blender/editors/curve/curve_ops.c
+++ b/source/blender/editors/curve/curve_ops.c
@@ -72,8 +72,8 @@ static int specials_menu_invoke(bContext *C, wmOperator *op, wmEvent *event)
head= uiPupMenuBegin("Specials", 0);
uiMenuItemO(head, 0, "CURVE_OT_subdivide");
uiMenuItemO(head, 0, "CURVE_OT_switch_direction");
- uiMenuItemO(head, 0, "CURVE_OT_set_weight");
- uiMenuItemO(head, 0, "CURVE_OT_set_radius");
+ uiMenuItemO(head, 0, "CURVE_OT_spline_weight_set");
+ uiMenuItemO(head, 0, "CURVE_OT_radius_set");
uiMenuItemO(head, 0, "CURVE_OT_smooth");
uiMenuItemO(head, 0, "CURVE_OT_smooth_radius");
uiPupMenuEnd(C, head);
@@ -100,11 +100,11 @@ void ED_operatortypes_curve(void)
WM_operatortype_append(FONT_OT_line_break);
WM_operatortype_append(FONT_OT_insert_lorem);
- WM_operatortype_append(FONT_OT_toggle_case);
- WM_operatortype_append(FONT_OT_set_case);
- WM_operatortype_append(FONT_OT_toggle_style);
- WM_operatortype_append(FONT_OT_set_style);
- WM_operatortype_append(FONT_OT_set_material);
+ WM_operatortype_append(FONT_OT_case_toggle);
+ WM_operatortype_append(FONT_OT_case_set);
+ WM_operatortype_append(FONT_OT_style_toggle);
+ WM_operatortype_append(FONT_OT_style_set);
+ WM_operatortype_append(FONT_OT_material_set);
WM_operatortype_append(FONT_OT_copy_text);
WM_operatortype_append(FONT_OT_cut_text);
@@ -126,20 +126,20 @@ void ED_operatortypes_curve(void)
WM_operatortype_append(CURVE_OT_duplicate);
WM_operatortype_append(CURVE_OT_delete);
- WM_operatortype_append(CURVE_OT_set_weight);
- WM_operatortype_append(CURVE_OT_set_radius);
- WM_operatortype_append(CURVE_OT_set_spline_type);
- WM_operatortype_append(CURVE_OT_set_handle_type);
- WM_operatortype_append(CURVE_OT_set_smooth);
- WM_operatortype_append(CURVE_OT_clear_tilt);
+ WM_operatortype_append(CURVE_OT_spline_type_set);
+ WM_operatortype_append(CURVE_OT_radius_set);
+ WM_operatortype_append(CURVE_OT_spline_weight_set);
+ WM_operatortype_append(CURVE_OT_handle_type_set);
+ WM_operatortype_append(CURVE_OT_smooth_set);
+ WM_operatortype_append(CURVE_OT_tilt_clear);
WM_operatortype_append(CURVE_OT_smooth);
WM_operatortype_append(CURVE_OT_smooth_radius);
WM_operatortype_append(CURVE_OT_de_select_first);
WM_operatortype_append(CURVE_OT_de_select_last);
- WM_operatortype_append(CURVE_OT_de_select_all);
- WM_operatortype_append(CURVE_OT_select_inverse);
+ WM_operatortype_append(CURVE_OT_select_all_toggle);
+ WM_operatortype_append(CURVE_OT_select_invert);
WM_operatortype_append(CURVE_OT_select_linked);
WM_operatortype_append(CURVE_OT_select_row);
WM_operatortype_append(CURVE_OT_select_next);
@@ -155,7 +155,7 @@ void ED_operatortypes_curve(void)
WM_operatortype_append(CURVE_OT_spin);
WM_operatortype_append(CURVE_OT_add_vertex);
WM_operatortype_append(CURVE_OT_extrude);
- WM_operatortype_append(CURVE_OT_toggle_cyclic);
+ WM_operatortype_append(CURVE_OT_cyclic_toggle);
WM_operatortype_append(CURVE_OT_specials_menu);
}
@@ -165,9 +165,9 @@ void ED_keymap_curve(wmWindowManager *wm)
ListBase *keymap= WM_keymap_listbase(wm, "Font", 0, 0);
/* only set in editmode font, by space_view3d listener */
- RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_toggle_style", BKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_BOLD);
- RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_toggle_style", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_ITALIC);
- RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_toggle_style", UKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_UNDERLINE);
+ RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_style_toggle", BKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_BOLD);
+ RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_style_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_ITALIC);
+ RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_style_toggle", UKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_UNDERLINE);
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_SEL);
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_SEL);
@@ -213,7 +213,7 @@ void ED_keymap_curve(wmWindowManager *wm)
WM_keymap_add_item(keymap, "OBJECT_OT_curve_add", AKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "CURVE_OT_add_vertex", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "CURVE_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CURVE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CURVE_OT_select_row", RKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "CURVE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "CURVE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
@@ -224,15 +224,15 @@ void ED_keymap_curve(wmWindowManager *wm)
WM_keymap_add_item(keymap, "CURVE_OT_extrude", EKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CURVE_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "CURVE_OT_make_segment", FKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "CURVE_OT_toggle_cyclic", CKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "CURVE_OT_cyclic_toggle", CKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CURVE_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "CURVE_OT_delete", DELKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "CURVE_OT_clear_tilt", TKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "CURVE_OT_tilt_clear", TKEY, KM_PRESS, KM_ALT, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "TFM_OT_transform", TKEY, KM_PRESS, 0, 0)->ptr, "mode", TFM_TILT);
- RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_set_handle_type", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1);
- RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_set_handle_type", HKEY, KM_PRESS, 0, 0)->ptr, "type", 3);
- RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_set_handle_type", VKEY, KM_PRESS, 0, 0)->ptr, "type", 2);
+ RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1);
+ RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", HKEY, KM_PRESS, 0, 0)->ptr, "type", 3);
+ RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", VKEY, KM_PRESS, 0, 0)->ptr, "type", 2);
WM_keymap_add_item(keymap, "CURVE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "CURVE_OT_hide", HKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 830d36dcfd8..ce639e4bfc1 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1061,11 +1061,11 @@ static int set_weight_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void CURVE_OT_set_weight(wmOperatorType *ot)
+void CURVE_OT_spline_weight_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Curve Weight";
- ot->idname= "CURVE_OT_set_weight";
+ ot->idname= "CURVE_OT_spline_weight_set";
/* api callbacks */
ot->exec= set_weight_exec;
@@ -1113,11 +1113,11 @@ static int set_radius_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void CURVE_OT_set_radius(wmOperatorType *ot)
+void CURVE_OT_radius_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Curve Radius";
- ot->idname= "CURVE_OT_set_radius";
+ ot->idname= "CURVE_OT_radius_set";
/* api callbacks */
ot->exec= set_radius_exec;
@@ -1595,11 +1595,11 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void CURVE_OT_de_select_all(wmOperatorType *ot)
+void CURVE_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select or Deselect All";
- ot->idname= "CURVE_OT_de_select_all";
+ ot->idname= "CURVE_OT_select_all_toggle";
/* api callbacks */
ot->exec= de_select_all_exec;
@@ -1741,7 +1741,7 @@ void CURVE_OT_reveal(wmOperatorType *ot)
/********************** select invert operator *********************/
-static int select_inverse_exec(bContext *C, wmOperator *op)
+static int select_invert_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
ListBase *editnurb= curve_get_editcurve(obedit);
@@ -1780,14 +1780,14 @@ static int select_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void CURVE_OT_select_inverse(wmOperatorType *ot)
+void CURVE_OT_select_invert(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Select Inverse";
- ot->idname= "CURVE_OT_select_inverse";
+ ot->name= "Select Invert";
+ ot->idname= "CURVE_OT_select_invert";
/* api callbacks */
- ot->exec= select_inverse_exec;
+ ot->exec= select_invert_exec;
ot->poll= ED_operator_editsurfcurve;
/* flags */
@@ -2476,7 +2476,7 @@ static int set_spline_type_exec(bContext *C, wmOperator *op)
return (changed)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
}
-void CURVE_OT_set_spline_type(wmOperatorType *ot)
+void CURVE_OT_spline_type_set(wmOperatorType *ot)
{
static EnumPropertyItem type_items[]= {
{CU_POLY, "POLY", "Poly", ""},
@@ -2488,7 +2488,7 @@ void CURVE_OT_set_spline_type(wmOperatorType *ot)
/* identifiers */
ot->name= "Set Spline Type";
- ot->idname= "CURVE_OT_set_spline_type";
+ ot->idname= "CURVE_OT_spline_type_set";
/* api callbacks */
ot->exec= set_spline_type_exec;
@@ -2517,7 +2517,7 @@ static int set_handle_type_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void CURVE_OT_set_handle_type(wmOperatorType *ot)
+void CURVE_OT_handle_type_set(wmOperatorType *ot)
{
static EnumPropertyItem type_items[]= {
{1, "AUTOMATIC", "Automatic", ""},
@@ -2529,7 +2529,7 @@ void CURVE_OT_set_handle_type(wmOperatorType *ot)
/* identifiers */
ot->name= "Set Handle Type";
- ot->idname= "CURVE_OT_set_handle_type";
+ ot->idname= "CURVE_OT_handle_type_set";
/* api callbacks */
ot->exec= set_handle_type_exec;
@@ -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;
}
@@ -3621,7 +3581,7 @@ static int toggle_cyclic_invoke(bContext *C, wmOperator *op, wmEvent *event)
return toggle_cyclic_exec(C, op);
}
-void CURVE_OT_toggle_cyclic(wmOperatorType *ot)
+void CURVE_OT_cyclic_toggle(wmOperatorType *ot)
{
static EnumPropertyItem direction_items[]= {
{0, "CYCLIC_U", "Cyclic U", ""},
@@ -3630,7 +3590,7 @@ void CURVE_OT_toggle_cyclic(wmOperatorType *ot)
/* identifiers */
ot->name= "Toggle Cyclic";
- ot->idname= "CURVE_OT_toggle_cyclic";
+ ot->idname= "CURVE_OT_cyclic_toggle";
/* api callbacks */
ot->exec= toggle_cyclic_exec;
@@ -4617,11 +4577,11 @@ static int set_smooth_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void CURVE_OT_set_smooth(wmOperatorType *ot)
+void CURVE_OT_smooth_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Smooth";
- ot->idname= "CURVE_OT_set_smooth";
+ ot->idname= "CURVE_OT_smooth_set";
/* api callbacks */
ot->exec= set_smooth_exec;
@@ -5169,11 +5129,11 @@ static int clear_tilt_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void CURVE_OT_clear_tilt(wmOperatorType *ot)
+void CURVE_OT_tilt_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear Tilt";
- ot->idname= "CURVE_OT_clear_tilt";
+ ot->idname= "CURVE_OT_tilt_clear";
/* api callbacks */
ot->exec= clear_tilt_exec;
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 722dfcdbd1d..e6992009056 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -646,11 +646,11 @@ static int set_style_exec(bContext *C, wmOperator *op)
return set_style(C, style, clear);
}
-void FONT_OT_set_style(wmOperatorType *ot)
+void FONT_OT_style_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Style";
- ot->idname= "FONT_OT_set_style";
+ ot->idname= "FONT_OT_style_set";
/* api callbacks */
ot->exec= set_style_exec;
@@ -683,11 +683,11 @@ static int toggle_style_exec(bContext *C, wmOperator *op)
return set_style(C, style, clear);
}
-void FONT_OT_toggle_style(wmOperatorType *ot)
+void FONT_OT_style_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Toggle Style";
- ot->idname= "FONT_OT_toggle_style";
+ ot->idname= "FONT_OT_style_toggle";
/* api callbacks */
ot->exec= toggle_style_exec;
@@ -727,11 +727,11 @@ static int set_material_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void FONT_OT_set_material(wmOperatorType *ot)
+void FONT_OT_material_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Material";
- ot->idname= "FONT_OT_set_material";
+ ot->idname= "FONT_OT_material_set";
/* api callbacks */
ot->exec= set_material_exec;
@@ -1509,11 +1509,11 @@ static int set_case_exec(bContext *C, wmOperator *op)
return set_case(C, RNA_enum_get(op->ptr, "case"));
}
-void FONT_OT_set_case(wmOperatorType *ot)
+void FONT_OT_case_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Case";
- ot->idname= "FONT_OT_set_case";
+ ot->idname= "FONT_OT_case_set";
/* api callbacks */
ot->exec= set_case_exec;
@@ -1551,11 +1551,11 @@ static int toggle_case_exec(bContext *C, wmOperator *op)
return set_case(C, ccase);
}
-void FONT_OT_toggle_case(wmOperatorType *ot)
+void FONT_OT_case_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Toggle Case";
- ot->idname= "FONT_OT_toggle_case";
+ ot->idname= "FONT_OT_case_toggle";
/* api callbacks */
ot->exec= toggle_case_exec;
diff --git a/source/blender/editors/datafiles/blenderbuttons.c b/source/blender/editors/datafiles/blenderbuttons.c
index d251673c1e9..c29137ab74c 100644
--- a/source/blender/editors/datafiles/blenderbuttons.c
+++ b/source/blender/editors/datafiles/blenderbuttons.c
@@ -1,3877 +1,4103 @@
/* DataToC output of file <blenderbuttons> */
-int datatoc_blenderbuttons_size= 123869;
+int datatoc_blenderbuttons_size= 131097;
char datatoc_blenderbuttons[]= {
-137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 88, 0, 0, 2, 0, 8, 6, 0, 0, 0,
- 94,187, 18, 70, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 13,215, 0, 0, 13,215, 1, 66, 40,155,120, 0, 0, 1, 57,105, 67, 67,
- 80, 80,104,111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,111,102,105,108,101, 0, 0,120,218,173,145,177, 74,195, 80,
- 20,134,191, 27, 69,197,161, 86, 8,226,224,112, 39, 81, 80,108,213,193,140, 73, 91,138, 32, 88,171, 67,146,173, 73, 67,149,210,
- 36,220,220,170,125, 8, 71,183, 14, 46,238, 62,129,147,163,224,160,248, 4,190,129,226,212,193, 33, 72,112, 18,193,111,250,206,
-207,225,112,224, 7,163, 98,215,157,134, 81,134, 65,172, 85,187,233, 72,215,243,229,236, 19, 51, 76, 1, 64, 39,204, 82,187,213,
- 58, 0,136,147, 56,226, 39, 2, 62, 95, 17, 0,207,155,118,221,105,240, 55,230,195, 84,105, 96, 2,108,119,163, 44, 4, 81, 1,
-250, 23, 58,213, 32,198,128, 25,244, 83, 13,226, 14, 48,213, 73,187, 6,226, 1, 40,245,114,127, 1, 74, 65,238,111, 64, 73,185,
-158, 15,226, 3, 48,123,174,231,131, 49, 7,152, 65,238, 43,128,169,163, 75, 13, 80, 75,210,145, 58,235,157,106, 89,181, 44, 75,
-218,221, 36,136,228,241, 40,211,209, 32,147,251,113,152,168, 52, 81, 29, 29,117,129,252, 63, 0, 22,243,197,118,211,145,107, 85,
-203,218, 91,231,159,113, 61, 95,230,246,126,132, 0,196,210, 99,145, 21,132, 67,117,254,221,133,177,243,251, 92,220, 24, 47,195,
-225, 45, 76, 79,138,108,247, 10,110, 54, 96,225,186,200, 86,171, 80,222,130,251,241, 23,194,179, 79,254, 28, 9,179, 39, 0, 0,
- 0, 32, 99, 72, 82, 77, 0, 0,122, 37, 0, 0,128,131, 0, 0,249,255, 0, 0,128,232, 0, 0, 82, 8, 0, 1, 21, 88, 0, 0,
- 58,151, 0, 0, 23,111,215, 90, 31,144, 0, 1,226, 30, 73, 68, 65, 84,120,218,236,157,119,120, 20,197,255,199,223,179,123,123,
- 61,141,132, 36,228, 82,105,210,107,232, 32, 77, 20,233, 2, 2, 42, 40,162, 82,108, 40, 42, 77,233, 96, 80, 4, 17, 20,193,138,
-128, 32,168,128, 2,130,116,144, 78, 66,175, 95, 32,129, 52, 72, 33, 61,151,187,219,219,157,223, 31,228,238,119, 9,151,228, 46,
- 9, 69,156,215,243,220,115,119,123,187,239,155,217,157,153,125,239,103,102,103, 9,165, 20,247, 10, 66, 72, 35, 74,233, 25,166,
-201, 52,153, 38,211,100,154, 76,147,105, 50,205,255, 18, 92, 57,118,106,165, 59, 50, 66, 8, 45,124,117,122,216, 53,239, 97,222,
-105, 37,106,118, 42,212,156,254, 47, 73,103,167,135, 85,211,150,223,202,212,117,220,135,149,181, 63, 29,210, 73, 43, 59,157,247,
- 74,179,178,235,101,101,150, 81, 39,199,125,250,191, 36,157,157, 30, 54,205,226,229,167, 50,116,157,149,201,138,238, 79, 39,233,
-164,149,157,206,123,165, 89,217,231,203,202, 42,163,165, 28,251, 74, 59, 55, 61,204, 40, 30,180,193, 0, 0, 74, 41,113,208, 39,
- 15,171,166,227,126,176,233, 87,102, 90, 43,145, 61,149,173, 89,108,127, 86, 22,211, 41,165,132, 16,178, 23, 64,167,202,204,123,
-101, 28,247, 98,121,173, 20,221,123,105,174, 42,179,220,223,107,205,202,170, 75,197, 53, 43,163,220, 59, 59,238,247,240, 24, 85,
- 86, 58, 43,165, 46,221,139, 50,239,164,252, 84, 88,183,184,102,101,212,165,226,154,149, 81,238,239,135,102,101,212, 37,103,154,
-149, 81,238, 75, 58,246, 44,130,117,127,140, 64,241,138,221,249, 97, 54, 66,247, 56,138,213,233,223,160, 89,201,199,104,122,161,
-102,101, 94,205,116,174,172, 99, 84,188,236, 84,198, 85,151,163,102,101,149, 77, 39,233,172,240,113,114,166, 89,209,244,150,144,
-206, 74,207,123, 69,203,253,253,210,172,228, 99, 84, 41,117,169,152,102,231, 74,190, 8,232, 92,153,117,201, 81,179,178,234,146,
-147,116, 86,248, 56, 57,211,172,104,122, 75, 72,103,165,231,189, 18, 35,162,149,174,251,200, 69,176,238,165,185,186, 23,230,205,
-118,149, 84,217, 39,178,202, 52, 89,247, 42,210, 86, 89, 81, 28, 39,186,123, 43, 81,110, 79,101,167,179, 48,125,228, 94, 24, 97,
- 74,233,116, 66,200,180,135,185, 66,179,186,196,234,210,195, 86,151,156,149,155,138,214,165,123,117,241,236,168, 89, 89, 70,200,
- 73,222, 43, 84,151,138,111, 91, 25,117,169, 12, 77,114, 47,242, 95,217,245,233, 97,132,123, 88, 18,114, 15,198,247,208,123, 17,
- 21,187,135,249,174,204,116,118,254, 55,228,253, 94,164,147, 16, 50,253, 30,229,253,223,178, 79, 89, 93, 98,117,233,161,171, 75,
-197,202,100,231,202,138, 12, 85,246,133, 84,113,205,202, 28,135, 84,153,101,244, 94,231,189, 50,235,210,189, 56,246,255, 22,220,
-142, 96,221,171,171,227,127,131,230,189,208,190, 71,121,223,123, 47,174, 14,238,193,184,174, 74, 79, 39,165,116, 58, 42,177,203,
-209,150,231,202, 76,235,189,236, 38,188, 23,101,243, 94,150,247,202, 28,231,113,143,242,254,111, 57,238,149,158,206,202,170, 75,
- 78,142,121,133,211,234,108,255, 85,118, 23,118,101,150,205,123,169, 89, 25,218,247, 34,157,247,234,216,255,155, 32,247,114,154,
- 6, 6,131,193, 96, 48, 24,140,255, 34, 78, 35, 88,141, 26, 53,218,213,170, 85,171, 58, 39, 78,156,176, 80, 74, 65, 8, 1, 33,
- 4, 28,199,129, 16, 2, 89,150,147,143, 31, 63,222,142,237, 62, 6,131,225,210,149, 28, 33, 28,254,127, 72,130,124,231, 98,150,
- 93,221, 49, 24,140, 71,184,221,115,214,198, 53,105,210,228,242,137, 19, 39,130,255,254,251,111,104,181, 90,232,245,122,232,245,
-122,120,120,120, 64,175,215,163, 87,175, 94, 55,247,239,223, 95,211,221, 63,171, 94,189,250, 37,171,213, 90,205, 45, 7,168, 80,
-164,198,197,197,213,161,148, 74,206,126, 15, 10, 10,186, 68, 8, 9,113,179,177, 79, 79, 74, 74,170, 65, 41,181,222, 47,205, 86,
-173, 90,197, 73,146,228,239,142,166, 74,165, 74, 56,120,240, 96, 29, 86, 76,239, 15,237,218,181,187, 36,138,162,219,229, 51, 56,
- 56,184,206,186,117,235,156,150,207, 54,109,218, 92,151, 36,169,138,139,101, 8, 0,192,113, 92,236,145, 35, 71,154,150,100, 64,
-154, 55,111,238,118,249, 4,144, 26, 29, 29, 29, 81,210,143, 77,155, 54,189,196,243,124,165,106,218,136,140,140, 20,130,130,130,
-190, 5,240,108,105,235, 9,130,144,158,145,145, 81, 99,207,158, 61, 86, 86, 26, 25, 12,198,191, 29,167, 17, 44, 89,150, 19, 71,
-143, 30,173,143,137,137, 41, 41,130,149, 82,158, 63, 51,155,205, 33,113, 59,118, 64, 17, 24, 8,106, 54,195,226,237, 13, 74, 41,
-100, 89,134,112,229, 10,168,197, 2, 88, 44, 48, 53,108, 8, 0, 16, 69, 17,173, 91,183, 14, 8, 15, 15, 23, 0, 72, 37,200, 86,
-123,251,237,183,225,233,233,137,130,130, 2, 20, 20, 20,192,100, 50,193,100, 50,193,108, 54,195,108, 54,195, 98,177,192, 98,177,
- 64, 20, 69,152, 76, 38,196,196,196,248,132,135,135, 43, 0,148,212,144, 87,123,235,173,183,224,225,225, 97,215,179,189,219, 52,
- 28,245, 76, 38, 19, 78,157, 58, 85,170,166, 36, 73,254,123,247,238,133, 94,175,135, 44,203,144, 36, 9,146, 36, 65,150,101,200,
-178,108,219,239,142,235,163,123,247,238,213, 88, 17,189,127,152,205,230,144,253,115,230,128,175, 90, 21, 84, 20, 97,173, 95,223,
-126,124,132,127,254, 1, 68, 17, 84, 20, 33, 62,249,164,189,220,246,237,219, 55, 32, 45, 45,173,196,242, 41,138, 98,213,189, 31,
-124, 0,206,211, 19,180,160, 0,186,254,253,129, 59,225, 27,228, 44, 92, 8, 42,138,160, 22, 11, 60, 38, 78,188,179, 44, 39, 39,
-187,105,211,166, 59,166, 79,159, 78, 0,208, 18,140, 88,181,157, 59,119,218,203, 12,165, 20, 54, 47,102,171,167, 60,207,219, 95,
- 71,143, 30,197,123,239,189, 87,170,185,231,121,190,218,240,225,195, 97,177, 88,236,117,199,246, 89, 20, 69,123,121,183, 90,173,
- 16, 69, 17,102,179, 25, 9, 9, 9,101, 94, 48,216,204, 85,104,104,232,211, 11, 22, 44,192,166, 77,155, 80,189,122,117, 40,149,
- 74,123,250,108,233,125,231,157,119,124, 10,219, 36,102,176, 24, 12,198,163,105,176,206,156, 57,211, 21, 0, 6, 12, 24,176,171,
- 81,163, 70,117, 46, 92,184, 96,177, 53,222,133,175,160, 23, 94,120, 33,206,214,152, 83, 74,147, 87,174, 92,233, 82,151,161, 34,
- 48, 16,113,190,190, 0,128,248,221,187,109, 87,236, 8,238,212,201,190, 78,198,177, 99,224,121, 30, 17, 17, 17,246,171,250,210,
-240,240,240,192, 83, 79, 61, 5,149, 74,133,200,200, 72, 40,149, 74, 8,130, 80,226,203, 21,116, 58, 29,102,204,152, 97,139, 82,
- 64,175, 81,227,245,199,219, 64, 67,128, 31, 78, 93,128, 73,146,161, 80, 40,160, 80, 40, 92,214,212,235,245, 88,187,118, 45,148,
- 74,165,211,215,206,157, 59,209,175, 95, 63, 40,149, 74,248,250,250,226,191, 52, 33,219,195, 2, 95,181, 42, 18,155, 55, 7, 0,
-100, 69, 71,219,203,167,103,159, 62,246,117, 44, 23, 46,128,227, 56, 4, 4, 4,184, 84, 62, 57, 79, 79,220,236,209, 3, 0,144,
-180,111, 31, 84, 42, 21,148, 74, 37,188,102,205, 2, 21, 4,112, 74, 37, 44,175,189, 6,139,197,146, 53,117,234,212, 21,106,181,
-250,108, 89,154,146, 36,225,200,145, 35, 80, 42,149, 80,171,213,119,189, 84, 42, 21,212,106, 53,214,172, 89,131,248,248,120,151,
-242,110, 52, 26, 49,103,206, 28, 16, 66,138,212,161,146, 62,187, 16,145,227,122,246,236,249,117, 72, 72,200,147, 11, 22, 44,208,
- 43,149, 74, 44, 89,178, 4, 10,133, 2,189,122,245,130,175,175, 47,182,111,223, 14,165, 82,137, 15, 62,248,128, 21, 62, 6,131,
-241,232, 27, 44,135, 6, 50,248,163,143, 62,242, 94,181,106, 21,212,106, 53,180, 90, 45,116, 58, 29,116, 58, 93,145,207, 31,126,
-248,161,228,234, 31, 82,179,185,248,149, 51, 56,142,187,107, 25,207,243,246, 43,114, 23, 34, 15, 24, 52,104, 16, 0,148,105,174,
- 92, 53, 67, 38,147, 9, 10,133, 2, 53,195,252,241,209,160, 22,104,207, 83, 24,211, 1,164,229, 97,120,144, 2, 39, 67, 30,195,
-226, 27,233,184,158,157, 11,133,194,181,155, 49, 37, 73, 42,209, 92, 41,149, 74,172, 92,185, 18,131, 6, 13,130, 82,169,188,107,
-159, 48,238, 15, 84, 20,139,154, 35,142,187,235, 88, 56, 91, 86,170,102, 65,129,173, 96,219,205,149, 74,165, 2, 84, 42,112,130,
- 0,162, 84,194, 98,177,100,189,248,226,139,235,188,188,188,142,249,248,248, 24,203,212,164, 20,106,181,250, 46,131,165, 82,169,
-236,230,106,221,186,117, 88,181,106, 21, 90,183,110,237,114,153, 87, 42,149,120,243,205, 55,239,250,109,227,198,141,118,131,165,
- 80, 40,160, 84, 42,203, 50, 87, 4, 0, 39, 8,194,224,121,243,230,113,182,245,253,252,252, 32, 8, 2, 26, 53,106, 4, 15, 15,
- 15, 28, 56,112,192, 94, 47, 24, 12, 6,163, 20, 4, 0, 77, 1,248,227, 78,143, 65, 14, 0, 31,135,223, 83, 11,223,253, 29,190,
- 31,115,162,211,178,112, 29,219,239,182,239,102, 0, 42, 39,203,211, 1,104, 11, 95, 38, 0, 7, 1, 52,116,248, 31,219,118, 40,
-254,191,138,194,198,176, 19,128, 61, 0, 58, 59, 78,126, 71, 41, 77,156, 61,123,182,222, 73, 4,171, 72,183, 33,165,212,229, 46,
- 67,209,199, 7,241,187,119,131,227, 56,132, 58, 68,173,210,143, 28,177,155, 45,175, 39,159, 4,209,233, 32,124,246,153, 75,154,
-102,179, 25, 41, 41, 41,119, 93,121,151,215, 96, 17, 66, 32,138, 34,180, 90, 53,118, 47,235,136,228,107, 86,204,217, 20,143,141,
- 71, 99,161, 80, 40,208,187,110,109, 12,180, 2,115,125, 53, 24,101,149, 96,145, 93, 27,171,107,181, 90,157, 70, 2,108, 47, 66,
- 72,145,207,140,251,143,181,126,125,123,228,202, 59, 50,242,255,205,199,185,115,118, 99, 37,180,111, 15,162,211,129, 76,158,236,
-146,166,174,127,127, 36,239,223, 15,165, 82, 9,191, 39,159, 4, 10,163, 86,138, 99,199,160, 84, 42, 33,138, 98,214, 59, 79, 61,
-245,221, 45, 89,142,110,211,166, 77,198,205,155, 55,245,174, 24, 44, 71, 51,229, 24,181,114, 52, 87,130, 32, 64, 44,102, 26, 75,
- 51, 88, 37,213, 15, 91,121,117, 39,130, 5, 0,178, 44,211,191,254,250, 11, 75,150, 44,129,159,159, 31,158,122,234, 41, 84,171,
- 86, 13,235,214,173, 3,165, 20,111,190,249, 38,180, 90, 45,180, 90, 45, 43,243, 12,198,127,148,146, 60, 72, 49, 58, 78,154, 52,
-169,197,220,185,115, 63,110,219,182,237,154,131, 7, 15,174, 38,132,108,114,104, 19,123, 23,106,109,114,248,222,178,152,201, 18,
- 0,248, 19, 66, 54,217,214,119,252,238,176,188, 27, 0,149,237,251,164, 73,147, 26,206,157, 59,247,227,137, 19, 39, 78,142,138,
-138, 82, 78,154, 52,169,241,220,185,115, 63,182,253,143,179,116, 56, 70,176,156,206, 2,252,251,239,191,119, 45,158,195,250,245,
-235,239,106,211,166, 77,157,152,152, 24, 71,211, 21,212,178,101,203, 56, 74,105,153,119, 23, 82, 74,237, 99,185,156, 69,173, 56,
-142, 3,209,235, 1,189, 30,178, 11, 13,174,205, 12, 41, 20, 10,112, 28,135,237,219,183, 67,171,213,162,103,207,158, 37, 26, 44,
- 87,163, 98, 42,149, 18, 10, 31, 14, 47, 46, 56,142,180,140,124,123,151,224,142,184,120, 28,213,104,240, 81,131, 38,240,200,141,
- 67,182,201,236, 86, 4, 75,165, 82,217, 79, 86, 74,165, 18,111,188,241, 6,204,102, 51, 56,142,179, 47, 43, 52,174,236,140,243,
- 96, 42,123,137, 81, 43,199,242, 73, 93,140, 98,201,178,252,255, 81, 43,165, 18,156, 82, 9, 82,120,156, 69, 81,204, 26, 54,108,
-216,186, 91,178, 28,125,241,226,197,179, 0,116,173, 90,181,114,201, 96,217, 76,149, 77,219,153,185, 82, 40, 20,176, 88, 44, 46,
- 95,168,148, 20, 73,114,215, 96,209, 59, 13,138, 12,128, 70, 68, 68,216,183, 9, 12, 12,132,143,143,143,125,108,155, 70,163,129,
- 86,171,101, 17, 44, 6,227,191,141, 43, 79, 34, 80,207,157, 59,247, 99, 71, 3, 83,220,208, 56, 26,167, 98, 38,202,209,164, 53,
- 44,163,253,223, 84,220, 52,217,254,151, 16,178, 41, 42, 42,170,119, 25,233, 72, 45,110,176, 92,158,102,159,231,249,224,101,203,
-150,121,111,216,176, 1, 30, 30, 30,240,241,241,129,151,151, 23,124,124,124, 48,112,224,192, 50,187, 10,101, 89,118,218,197,226,
-104,176,160,215,223, 57,137,185,120, 69,107,177, 88, 32, 8, 2, 56,142,195,152, 49, 99,236,227,162, 42,210, 69,104, 54,155,193,
-115, 60,160,174, 14,138, 35,118,115,101,127,169, 84,136, 11,107, 2,114, 51, 17, 10,133,107, 61,164,178, 44,219, 79,122,130, 32,
- 96,234,212,169,152, 63,127,126,145, 27, 8, 4, 65, 64,179,102,205,112,249,242,101, 86,229, 30, 0, 37,149, 79,219, 64,108, 66,
- 8,136,135,199,157,242,169, 80,184,100,214,109,209, 38,165, 82, 9, 78,165, 2, 41, 52, 88,162, 40,102,189,255,254,251,223,221,
-186,117, 43, 58, 52, 52, 52, 21, 0, 15, 23, 39,225, 35,132,216, 53, 53, 26, 77,137,230, 74,161, 80,184, 28,193,178,213, 35, 71,
- 70,142, 28, 89,228, 29, 0,222,124,243, 77, 87,235, 17, 5, 0, 65, 16,208,173, 91, 55, 52,110,220, 24, 27, 55,110,132, 44,203,
-120,227,141, 55,160,213,106,177,112,225, 66, 88,173, 86,124,242,201, 39,172,240, 49, 24,255,237, 11,219,178, 60,136,113,226,196,
-137,147, 9, 33,155, 10, 35, 73,103, 75, 49, 82,206,104, 89,204,164,165,150,208, 94,247,118,102,178, 28, 63,219,152, 52,105, 82,
- 67, 39,233, 56,118,151,193,114,112,143,101,157,128, 18, 71,141, 26,165,183,205,145,101, 51, 6, 60,207,187,116,119,161,226,127,
-255, 67,208,227,143, 3, 0,110, 31, 61,106, 55, 85,158,221,187, 3, 58, 29,136, 78, 7,241,247,223,239,232,249,249,185,116, 96,
- 68, 81,180, 27,172,244,244,244, 74, 25,131, 37,138, 34,120,165,128,195, 30, 2,168,192, 23, 49, 87,130, 32,128, 83, 8,136,243,
-127, 12, 68,241, 55, 20,146,107, 55, 61,217, 12,150,237,197,113, 28,222,121,231, 29,251, 62,228, 56, 14,237,219,183,183, 27, 78,
-198,253, 71,177,127, 63, 60,122,223,169,171,230,243,231,255,223,248,118,236, 8,162,215,131,232,116,224, 54,111,190, 99,180, 60,
- 61,129,239,191, 47, 83, 51,111,201, 18,120,206,153, 3, 34, 8, 80, 28, 62, 12,149, 74, 5,139,197,146,245, 66,100,228,186, 84,
- 31,159,227, 23, 47, 94, 60, 15,128, 27, 56,112,160, 95,171, 86,173, 20, 46, 54, 70, 78,187, 5, 87,175, 94, 93,196, 92, 41, 20,
- 10, 88,173,174,149,207,210, 34, 88,206,162, 89, 46, 24, 75,218,183,111, 95,240, 60, 15,111,111,111,120,122,122,218,239,190,180,
- 69,174,172, 86, 43,172, 86,171,203,227, 24, 25, 12,198,163,137, 11, 30,196, 20, 21, 21,117, 54, 42, 42,202, 30, 73, 42, 30,193,
- 42,129, 94,133,102,202,223,102,206,112,103, 44,213,177, 82,210,210,187, 36,227,229,184,108,238,220,185, 31, 59, 73,135,189, 91,
-178,196,137, 70, 91,183,110, 93,199,113,154, 6,158,231, 33, 73, 82,242,185,115,231, 42, 52,193, 40,117,232,174,112, 22,181, 34,
-122,253,255,119, 21,186, 24,193,178,117, 17,242, 60,111, 55, 47, 63,253,244, 19, 60, 60, 60,240,242,203, 47, 87,192, 96,241,248,
- 67,121, 25, 80, 42,238,138, 96,241,130,128, 27,222,161,224, 4, 1, 10, 73,116, 41,173,217,217,217, 80, 42,149,248,226,139, 47,
-240,225,135, 31,218,246,169, 61, 58,226,104,180, 24, 15,168,146, 59, 68,123, 28, 47, 30,108, 81, 43,162,215,219, 35, 92, 60,207,
-195,165,185, 50,173, 86, 64,169, 4, 10,187,242, 44, 22, 75,214,248,241,227,191, 75,245,241,137, 14, 11, 11, 75,197,157, 9, 56,
- 57, 79, 79, 79,151,203, 39,199,113, 78,205,149,173, 30,216,203, 41,207,187, 21,193, 82, 42,149,216,188,121,179,189,174, 56, 70,
-174,220, 53, 88,142,105,221,183,111, 31, 98, 98, 98, 48,102,204, 24,104,181, 90, 44, 90,180, 8, 86,171, 21, 51,103,206,132, 86,
-171,189,211,125,202, 96, 48, 24, 37, 83,197,102,112, 10, 77, 82,145,200, 18,165,180,183,163, 9, 42,169,171,176, 48,226,180,175,
-140,255,218, 92,104,204,156, 98,139,164, 21,187,232,221, 84,220,156, 41,108,206,209,241,157,227,184,224,165, 75,151,122,239,219,
-183, 15, 58,157,206, 62,209,232,243,207, 63, 47, 85,120, 23, 21, 26, 44,234, 96, 42,138,156,192,116,186,114, 25, 44, 65, 16,138,
- 24,172,105,211,166, 65,161, 80,224,219,111,191, 5, 0,188,255,254,251,110, 25, 44,139,197, 2, 42, 3, 7,165, 61, 48, 44,105,
- 2,186, 92,131, 91,251, 46, 64, 16, 4, 84,107,245, 36,228, 22, 3,145,174,242,130,158,202, 46, 95,125,103,100,100,224,252,249,
-243, 32,132, 96,198,140, 25, 69,242,239, 56,198, 7, 0,182,111,223, 14,252,135,158,217,244,208, 25,172,194,238, 64,123, 89, 44,
- 44,159,156,131,193,178, 69,146, 92,209, 36, 42, 21,248, 66,115,245,210, 75, 47,173, 75, 78, 78, 62,126,241,226,197, 11, 0,184,
-231,158,123,206, 79,163,209,224,135, 31,126,200, 1,160, 94,179,102, 77,153, 99,176, 56,142,115,106,174,156, 25, 44, 73,146,220,
-170, 71,101, 93,140,148,199, 96, 17, 66, 32, 73,146, 61,114, 37,138,162,253,187, 90,173,102, 5,143,193,248,143, 71,175, 28,223,
- 75, 32,181,216, 56, 39, 82, 44,210,148,234,204, 88, 57,118, 7, 58,124, 22,157,232,154,139,117, 29, 22, 95,110,123, 79,143,138,
-138,218,109,139, 92, 57, 44, 47,146,142, 18, 35, 88,148, 82,251, 68,163,182,147, 8,199,113,144, 36, 41,165,162, 59,178,160, 65,
- 3,100, 69, 71,131,231,121,120,246,236, 9,162,211,129,234,116, 16,215,174,181, 15, 84, 87,204,154,117,231,100,214,179,167, 75,
-154,182,187,243, 28, 13, 86,102,102, 38, 4, 65,192,236,217,179,193,113, 28, 62,249,228, 19, 4, 7, 7, 35, 57, 57, 25, 91,183,
-110,117, 73,147,147, 57,104,134,251, 66, 51,202, 19,220,152, 90,104,216,103, 20,178,114, 34,112,218,172, 71,189,188,203,168,178,
-107, 26, 44,146,235,221, 27,162, 40,218,231, 46,162,148,218,163, 87,182,110, 19, 73,146,236,147, 58,126,250,233,167, 96, 79, 18,
-185,255, 88,158,120, 2,226,197,139,224,121, 30,202,206,157,239,140,181,210,233,192,109,220,248,255,198,106,218, 52, 80,189, 30,
-114,103,215, 30, 8,175,125,231, 29, 88,238, 76,226,153,245,110,143, 30,223, 39,139,226,177,154, 53,107,218, 34, 87, 68,163,209,
- 64,175,215, 19,220, 25,131,229, 82,248,210, 86, 87,202, 50, 87,182,207,174,150, 79,199,105, 24, 42,195, 96,217,218,142,151, 95,
-126, 25, 65, 65, 65, 88,188,120,113,145,200,213,228,201,147, 33,138, 34, 22, 46, 92,200, 10, 31,131,193, 40,141, 99,110,172,219,
-210,193, 44, 29, 43,167,238,177,138, 38,216,105,203,123,250,244,233,174, 37,109,224,216,125,104,107, 64, 41,165,201, 49, 49, 49,
-237,156, 52,174,141, 40,165,103, 28,151,201,178,252,255,243, 92,233,116,128,135, 7, 56,189,222,126,194,176, 69,179,120, 79, 79,
-167,131,136,157,105,218, 12, 22,199,113, 69,174,190, 21, 10, 5,178,178,178, 32, 8, 2, 22, 47, 94, 12, 47, 47, 47,152, 76, 38,
-184,146, 78,139,197, 2,158,231,145,127, 61, 31,177, 83, 78, 67,173,191,130, 58, 79,122,194, 83,184,138,218,251, 55,192,106, 53,
- 3, 14, 93,134,174,104,214,168, 81, 3,227,198,141,179, 15, 78, 46,254,114,204, 43,165, 20, 45, 91,182, 44, 83,179,162, 48,205,
-162,154,182, 46,113,219,221,130,196,195,227,206,184, 43,135, 8, 35,245,240, 0,231,225,113,231,110, 64, 23,202,103,161,121,185,
- 19,185, 18,197, 99,182,200,213,139, 47,190,232, 91, 24,185,202, 5,192,205,154, 53,203, 35, 36, 36, 68, 81,124,252,157, 51, 77,
-158,231,239, 50, 87,238, 24,172,146,234, 81,241,233, 67,198,142, 29,123,215, 68,163, 37, 25,172,146,242,206,243, 60,170, 86,173,
- 10,157, 78, 7,171,213,106,143, 92,105, 52, 26,251,236,240, 37, 93, 76,176,242,201, 52,153,230,127, 71,243, 1,153,177,123,134,
-219, 35, 75,109,221,135,135, 15, 31,134,167,167, 39,188,189,189,221,234, 58, 52,155,205, 48, 24, 12,144,101, 25,234, 79, 62,185,
- 19,189, 1,144,175, 84,254,255, 99, 73,186,116, 1,229, 56,100,228,228,192, 98,177,148,217, 13, 99, 52, 26,139, 12, 64,183,153,
- 43,199, 19, 67,110,110,174,125,242, 80, 87,176,105,218,162, 98, 68,162,184,182,227,215,187,239, 38,116, 99, 38,119, 73,146, 16,
- 16, 16, 80,100, 12,143,237, 36,232,228, 68, 13,176, 46,194,251,142, 40,138,168, 82,165, 10, 40,165, 16, 38, 78, 4, 8, 1, 37,
- 4,166,194, 72,163,213,106,133,208,182, 45, 40,207, 35,219,104,132,197, 98,129, 70,163, 41, 85, 51, 55, 55, 55,235,131, 15, 62,
-248, 14,192,145,174, 93,187,166, 0, 48, 2,160, 62, 62, 62,106, 74,169, 12, 32, 5, 0, 77, 74, 74,242,189,118,237,154,108, 54,
-155,203,124,206,231,225,195,135,113,237,218, 53, 52,111,222,220,254,248, 26,219,203,246, 8,166,242, 68,176,156,205,209, 86,222,
-153,220, 29,218, 12,120,123,123, 67,165, 82, 97,246,236,217, 80, 42,149,208,106,181, 0,128,133, 11, 23,222,217,215,110,232, 49,
- 24, 12,198,191, 1,183, 13,150,173,251,240,196,137, 19, 22, 91,227,233,234, 68,163, 74,165, 50,181, 69,139, 22,110, 61,240, 88,
-169, 84,102, 94,191,126,221, 90,138,139,190,185,103,207, 30,183, 30, 82,203,243,124,153,154,135, 15, 31,118, 75,147,227,184, 82,
- 53, 5, 65, 72,237,222,189,187, 91,121, 87,171,213, 41,172,136,222, 63, 4, 65, 72,237,213,171,151,243, 99,180,104, 81, 73,219,
-100,162,148,103,231, 9,130,112,173, 97,195,134,187,212,106,245, 21,111,111,111, 28, 58,116, 40,160, 89,179,102, 1,142,235, 52,
-107,214, 44,172, 88, 89, 50, 77,159, 62,157, 78,155, 54,173, 36,217,155,227,199,143,119,183,124,166,150,113, 53,122,243,230,205,
-155,238,214,163,212, 50, 27, 24,133,226,230,219,111,191, 29,226,106, 93, 7,123, 14, 33,131,193,248,175, 26,172,210,186, 15,203,
- 34, 46, 46, 46,162,178, 51,144,152,152, 88,231,223,160,121,248,240,225, 8, 86,220, 30,110,238,197, 49, 58,124,248,112,163,202,
-214,140,142,142,174,244,242,121,252,248,241, 58,247, 98,159,254,246,219,111,117, 88,201, 98, 48, 24,255, 69,216,124, 0, 12, 6,
-131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 60,220, 16, 0, 78,187, 48,220,185, 59,128, 16,226,118, 55, 72, 89,250,
- 76,147,105, 50, 77,166,201, 52,153, 38,211,124,244, 52,203,210,126,136,239, 78,116,207, 96,221,203,185,150,216, 45,172, 76,147,
-105, 50, 77,166,201, 52,153, 38,211,252, 47,194,186, 8, 25, 12, 6,131,193, 96, 48,152,193,122,244, 8, 15, 15,175,198,246, 2,
-131,193, 96, 48, 24,143, 14, 37, 78,211,208,170, 85,171, 56, 73,146,220,154,183, 73, 16,132, 84, 87,111,117, 39,132, 40, 12, 6,
- 67,127,173, 86,219, 73, 16,132,182, 0, 32,138,226, 33,163,209,184, 55, 41, 41,105, 61,165,180, 92,243,225, 4, 6, 6, 70,112,
- 28,247, 2, 33,100, 16, 0, 80, 74,215,201,178,252,243,173, 91,183,226, 30,182,157, 79, 8,225, 66, 66, 66,190,175, 91,183,110,
-215,144,144,144,115, 94, 94, 94,253,206,157, 59,103,169,128, 94,134,179,229,148,210, 42,229,213, 12, 11, 11,243,177, 90,173, 45,
- 0, 52, 43, 92,116, 66,161, 80, 28,191,113,227, 70, 38,171, 62,143, 6,229,169,235,192,157,121,237, 14, 29, 58, 20, 81,153,154,
- 42,149, 42,225,224,193,131,117, 74,208,188, 36, 73, 82,200,191, 32,157,255,138,253, 89, 18, 45, 90,180,248,157, 82,218,189,176,
- 77,217,118,252,248,241, 1,172,150, 48, 24,149,104,176, 36, 73,242,223,187,119, 47,244,122,189,237, 36, 13, 73,146,236,179, 68,
-203,178,108,127,134,158,109,134,235,167,158,122,202,165, 6, 32, 52, 52,180, 65,157, 58,117, 86,189,249,230,155,161,125,250,244,
- 81, 5, 6, 6,130, 16,130,155, 55,111,214,218,180,105,211,144,197,139, 23, 79, 14, 13, 13, 29, 26, 31, 31,127,206, 21, 61,127,
-127,127,189, 82,169,124,134, 82, 58,180, 73,147, 38,237, 62,248,224, 3,210,190,125,123, 72,146,132, 93,187,118, 77, 90,176, 96,
-193, 68,131,193,112,144, 16,178,202, 98,177,108, 72, 77, 77,205,123,128,166,138, 4, 6, 6,134,221,186,117, 43, 30, 0,105,222,
-188,121,187,249,243,231,251,254,254,251,239,143,127,254,249,231, 95, 2, 24, 89, 1,121, 85, 37,166, 83, 17, 20, 20, 52, 14,192,
-196,226,186, 86,171,213,108, 48, 24,230, 38, 39, 39, 47, 40,175, 17,102, 60, 60, 56,214,117,219, 51, 49,173, 86,171,189,110, 75,
-146, 4, 74,169,253, 49, 66,182,246,160, 91,183,110,254,238,104,218,218, 13,155, 46,112,231,209, 89, 14,219,160,123,247,238, 37,
- 70,115, 41,165,213,118,238,220, 9,111,111,239, 82, 53, 29,145,101, 25, 79, 60,241, 68,185,210,105,107,223,138, 35,138, 98,169,
-233, 44,174,233,168, 91,146,166, 44,203,232,210,165,203,125, 77,167,141,214,173, 91, 7, 88,173,214, 69,132, 16, 21,207,243, 31,
- 80, 74,187,111,221,186, 21,146, 36,161, 87,175, 94,221, 91,183,110, 93, 75,146,164,121, 58,157, 78, 54,153, 76, 99,142, 28, 57,
-194, 38, 64,102, 48, 42, 98,176, 0, 64,175,215, 99,245,234,213,246,199, 99, 20,127, 20,141,227,231,240,240,112,151,254, 48, 40,
- 40,168,121, 68, 68,196,182,245,235,215,107, 3, 2,254,127, 66,107,139,197, 2, 47, 47, 47,188,252,242,203,170,110,221,186,213,
- 26, 58,116,232,158,160,160,160,238,201,201,201, 49,165,233, 5, 7, 7,143, 14, 8, 8,152, 53,110,220, 56,109,223,190,125, 81,
-165, 74,209, 96, 77,239,222,189,209,179,103, 79,114,237,218,181,246,235,214,173,107,191, 98,197,138,249,193,193,193, 83, 19, 19,
- 19,151,150,149,214,144,144,144, 42, 26,141,230,203,192,192,192, 70,177,177,177, 7, 85, 42,213,248,130,130,130, 55,131,130,130,
-158,207,205,205,141, 55,153, 76,111,220,184,113, 35,214, 29,115, 85,173, 90,181, 45,141, 26, 53,106,162, 82,169, 98, 77, 38,211,
-139,103,206,156,137,185,122,245,170, 97,232,208,161,228,204,153, 51,125, 13, 6,195,174,164,164,164,181,229,137, 92, 89,173,214,
-227,165,253,238,106, 36,171, 65,131, 6,202,160,160,160,109, 0, 90,245,233,211,231,250,244,233,211,169,143,143,143, 39,199,113,
- 36, 61, 61, 61,227,211, 79, 63, 85,174, 93,187,118, 90, 80, 80, 80,247, 6, 13, 26,116,175, 72,212,141,241,112,160,215,235,241,
-203, 47,191, 20,121, 28,142,227,115, 7,139, 63, 46,199,215,215,247,158,104, 82, 74, 75,125, 60,148,135,135, 7,126,253,245, 87,
-112, 28,119,151,142,163,182,237,123,213,170, 85, 65, 8, 1, 33,132,208, 18,238,232,113, 55,157, 85,171, 86,133, 44,203, 92,101,
-230,221,223,223,191,210,247,103,213,170, 85,203,220,159,133,237,198,162, 79, 63,253,180,151,167,167, 39, 38, 76,152,112, 50, 60,
- 60, 28, 94, 94, 94, 88,182,108, 25,170, 84,169, 2, 73,146, 78,126,246,217,103, 36, 62, 62, 30, 11, 23, 46,252, 26, 64,127, 86,
- 99, 24,140, 10, 26, 44, 0, 69, 42,109,105, 6,171,132, 43,206, 34,119, 24, 68, 68, 68,168, 61, 60, 60,126,254,227,143, 63,180,
-126,126,126,246,229,102,179, 25, 57, 57, 57,200,205,205, 69, 78, 78, 14,244,122, 61,150, 44, 89,162,125,225,133, 23,126,142,136,
-136,104, 18, 23, 23,103, 42, 73,147, 82, 58,247,212,169, 83,130,213,106,133, 74,229, 60,128,195,113, 28,106,213,170,133,177, 99,
-199,162, 67,135, 14,186,231,158,123,110, 46,128,165, 37,105, 58, 24,147,229,251,247,239,111, 27, 16, 16,160,217,176, 97,131,102,
-201,146, 37,151,123,246,236,153,251,210, 75, 47, 5,101,102,102, 6,245,238,221,251, 79, 0, 13, 92,201,123, 97,228,206,187, 81,
-163, 70, 13, 23, 44, 88,224,117,238,220,185,166, 83,167, 78,221,148,157,157, 61,107,214,172, 89,245, 87,174, 92, 89, 99,230,204,
-153,250, 83,167, 78, 77, 34,132,252, 70, 41,149, 92,209,116,140, 92,113, 28,167,112, 55,178,229, 76, 51, 51, 51,115, 50,128, 86,
- 63,253,244,211,153, 39,158,120, 34,140, 82,154, 14,224, 38, 0, 4, 4, 4,104, 22, 44, 88,160,235,212,169,211,137, 49, 99,198,
-180, 42, 92,119,186,139,233, 44, 55, 76,243,222,106,202,178, 12, 65, 16, 48,112,224, 64, 16, 66,138, 60,199,208, 86,207,247,239,
-223,143,167,158,122, 10,130, 32,224,213, 87, 95,117, 89,243,185,231,158,131,213,106,189, 75,115,231,206,157, 69,140, 1,199,113,
- 46,105, 58, 62, 35,180,164,151,187,154,165,105, 21,215,116,103,127,186,170,233,236,121,171,165,105, 14, 24, 48, 0, 91,183,110,
-173,112, 58,109,205,252,169, 83,167,208,164, 73, 19,172, 90,181,138,240, 60,143, 35, 71,142, 64,171,213, 98,248,240,225,104,212,
-168, 17,209,106,181,184,118,237, 26,114,115,115, 9,171, 71, 76,243, 94,105,150,129, 0,160, 41, 0,127, 0, 18,128, 28, 0, 62,
- 0,204,133,231,184,116, 0,218,194,151, 9, 64, 46,128,170,133,219,166,225,206,180, 84,126, 14,122,169, 40,250, 80,232,150,133,
-218,182, 71,128, 57, 94,245,152,139,157, 71,109,223,139,191, 23,209,230, 10,141, 4, 45,124,117, 42,182, 3, 93, 50, 87, 37, 53,
- 16,197,145,101,121,212,196,137, 19, 3, 28,205,149,201,100, 66,118,118, 54,114,114,114,236,239,151, 47, 95,134, 74,165,194,160,
- 65,131, 2,100, 89, 30, 85,214, 78,231,121, 30, 49, 49, 49,216,176, 97, 3, 98, 99,239, 14, 40, 93,189,122, 21, 95,124,241, 5,
-230,205,155,135,236,236,108,219,129,114,138,193, 96,240,107,208,160,193,204, 70,141, 26, 93,110,221,186,117,151,212,212, 84,205,
-169, 83,167, 16, 30, 30, 30,184,126,253,122,143,200,200,200,160,232,232,104, 92,188,120, 81,217,182,109,219,176,250,245,235, 95,
-111,210,164,201,151,129,129,129, 17,101, 69,175, 44, 22,139,215,217,179,103, 15,108,222,188, 89,106,209,162, 5, 86,173, 90, 21,
- 94,187,118,237, 79,175, 93,187,182,118,217,178,101, 70,127,127,127,244,236,217, 51,194, 96, 48, 60,237,106,228,138, 16,146, 97,
-181, 90,143, 59,139, 94,201,178,140,236,236,108, 92,191,126,253,248,233,211,167, 99, 10,215,191, 89, 70,212,174, 38,128,113,131,
- 7, 15,254, 95,161,185,186, 81, 88,144, 69, 0,162, 36, 73, 57, 25, 25, 25,137,157, 58,117, 10,234,214,173,219, 69, 0,227, 10,
-183, 97,252,139,177, 90,173, 16, 4, 1,127,253,245, 23,118,236,216,129, 93,187,118, 97,207,158, 61,216,183,111, 31,246,237,219,
-135,253,251,247, 67, 16, 4, 28, 56,112, 0, 7, 14, 28,192, 91,111,189,229,178,230, 31,127,252,225, 84, 83,167,211, 21, 49, 6,
-174,180, 33,146, 36,149,104, 86,126,252,241, 71,112, 28,119,151, 38, 33,132,162,148, 7,167,219,210,233,236,213,172,121,243,187,
-150, 57, 51,109, 37,165,115,203,150, 45,176, 90,173, 88,183,110, 29,178,179,179,241,195, 15, 63, 32, 57, 57, 25,139, 23, 47,198,
-149, 43, 87, 48,119,238, 92,156, 58,117,202, 37, 77, 91, 58, 7, 14, 28,104,127, 48,183, 32, 8, 72, 75, 75,195,178,101,203,112,
-253,250,117, 44, 88,176, 0,231,207,159,199,172, 89,179, 92,210, 4, 0,158,231,199,173, 89,179,198,186,123,247,110,172, 92,185,
- 18,107,215,174,197,149, 43, 87,160,209,104,160,213,106,113,243,230, 77, 92,184,112, 1,107,215,174,181,114, 28,247, 30,171, 45,
-140,202,166, 36, 15, 82,140,142,147, 38, 77,234, 74, 8,217,212,174, 93,187, 97, 0,124, 8, 33,155, 0,168, 10,223,253, 38, 77,
-154,212,138, 16,178,105,210,164, 73, 45, 0, 84, 37,132,108, 42,252,222, 5,128,159,237,123,225,250,254,197,204,155,191,195,114,
-255, 98,235,170,156,125, 47,254, 94, 92, 91,225, 96,166, 72,241,134,200,177, 49, 43,203, 96,185, 82,153, 61, 61, 61,159,126,250,
-233,167,149,142,230,202, 49,114,101,123,207,201,201,193,165, 75,151,208,168, 81, 35,165,167,167,231,211, 0,190, 40, 51, 20,167,
- 80,192, 96, 48, 32, 45, 45, 13,103,206,156, 65,120,120, 56, 68, 81,196,182,109,219,144,153,153,105, 15,165,155,205,230, 82,117,
- 2, 2, 2, 22,191,240,194, 11, 61, 71,141, 26,197,255,253,247,223,168, 87,175, 30,170, 87,175,142,131, 7, 15,194, 98,177, 32,
- 52, 52, 20,109,219,182,197,175,191,254,138,166, 77,155,114, 35, 71,142,172,122,246,236,217,225,139, 22, 45,106, 3,160,121, 73,
-186,213,170, 85,219,220,164, 73,147,166,231,207,159,191, 58,111,222,188,181, 55,110,220,232, 51,113,226, 68,125, 84, 84,148,239,
-192,129, 3,159,220,186,117,235,229, 41, 83,166, 52,237,221,187,183, 98,197,138, 21,195, 1,108,118,161, 92,150, 24,185,178, 90,
-173,200,205,205,181,153, 86, 69,118,118, 54, 7, 23,198,104,201,178,252, 56, 0,126,202,148, 41,160,148,222, 46,188, 82,176, 71,
- 26,115,115,115,145,155,155, 43, 75,146,148, 53,106,212, 40,227,142, 29, 59,248,194,109,174,178,102,226,223,139,173,174, 15, 24,
- 48,160, 72,116,104,231,206,157,232,221,187,247, 93,221, 82, 61,122,244,112, 89,115,200,144, 33, 69,162, 47, 10,133,194,105,244,
-197, 29,227,226, 44,130, 85,220, 92,217,150,149, 53,215, 95,105,209, 38, 0,119, 45,115,199, 8, 62,251,236,179, 80, 42,149, 24,
- 62,124, 56,148, 74, 37,222,124,243, 77, 8,130,128, 9, 19, 38, 64, 16, 4,180,104,209,194,229,188,219,210,185,113,227, 70,244,
-236,217,211,158,158,176,176, 48,188,251,238,187, 80, 42,149,104,220,184, 49,148, 74, 37,218,182,109,235, 82, 58,109, 3,218, 27,
- 53,106,132, 49, 99,198, 96,253,250,245,248,233,167,159,236,191, 15, 28, 56, 16, 3, 6, 12, 64,110,110, 46, 2, 3, 3, 21, 73,
- 73, 73,103, 91,180,104,193, 6,190, 51, 42, 29,103, 30,164, 24,234,185,115,231,126, 76, 41,237, 93,146,134,237,119, 66,200,166,
-168,168,168,222,133,186,119,125,119,136, 50, 57,154,183,134,142, 17, 40,219,118,142,255, 87,218,127, 23, 91, 63,181,136,193, 42,
-204, 88,103,103,141,132, 82,169,180, 55,104, 37, 25, 45, 87, 40, 40, 40,104,108,139, 94, 21, 20, 20, 20, 49, 84,133, 39,110,251,
-103,179,217,140, 26, 53,106,160,160,160,160,177,155, 78, 24, 65, 65, 65,176, 88, 44,248,246,219,111,237,198,202,134,197, 98, 41,
-235, 32, 7,117,237,218,149,143,139,139, 67, 98, 98, 34,100, 89,198,161, 67,135, 32, 8, 2,140, 70, 35, 76, 38, 19,126,253,245,
- 87,240, 60,143,171, 87,175, 66,163,209,160, 73,147, 38, 68,146, 36,159,146, 52, 3, 3, 3,117,109,218,180,169,191,120,241, 98,
-175,211,167, 79, 55,159, 52,105,146,215,186,117,235, 54,134,135,135, 15,126,237,181,215,132, 17, 35, 70, 52,253,230,155,111, 82,
-162,163,163,209,174, 93, 59,120,121,121,133, 87,164,160,154, 76,166, 34,251, 50, 59, 59, 27, 89, 89, 89,174,110,222, 12, 0,188,
-188,188,170, 2, 72,182, 45,204,207,207, 71,126,126, 62,178,179,179,145,159,159, 15,163,209,104,209,233,116, 42,135,109,126, 96,
- 77,196,191,223, 96,109,221,186,245,174,177, 76,187,118,237,186,107,204,143, 74,165,194,230,205,155, 93, 50, 4,127,254,249,103,
-137, 99,133, 28,187,181,120,158, 47,115,204,144, 45,170,206,243, 60,126,254,249,103, 0,192,232,209,163,237,203, 28,219, 36,155,
- 38, 0, 60,251,236,179,196,149,168, 88,199, 47,239,140, 45, 59,253,145,228,212, 96, 57,106,186,146,247, 95,127,253, 21,189,123,
-247,198,166, 77,155, 74,125,239,222,189,187, 91,209, 59,224,255,135,111,220,184,113,195,169,238,226,197,139, 93,217,159,221,183,
-110,221, 10, 47, 47, 47,123,183, 32, 0,244,238,221,251, 61, 15, 15,143, 14, 5, 5, 5,253, 54,109,218,132,204,204, 76,212,168,
- 81, 3, 1, 1, 1, 56,114,228, 72,119, 86, 99, 24,247, 34,138, 85,220,131, 20,195, 56,113,226,196,201,132,144, 77, 19, 39, 78,
-156, 28, 21, 21,117,182,112,187, 77,197,116, 54,149,241, 63, 54, 19,100,235, 30,108, 89,204,188,217,186, 14,123,149,178,173,185,
-152,161, 42,222, 69,120,172,204, 8,150, 44,203, 69,204, 85,105, 6,203,149, 43, 48, 74, 41, 79, 8, 41, 98, 0, 74,138, 96,137,
-162,136,244,244,116, 80, 74,249,202, 60,136,101, 25,172,244,244,244, 15,222,124,243,205,141,159,127,254,185,215,144, 33, 67,240,
-207, 63,255,160,126,253,250, 48,153, 76,240,243,243, 67,108,108, 44,120,158,199,229,203,151, 17, 30, 30, 14,189, 94,143,169, 83,
-167,230, 26,141,198,169, 37,105,222,186,117, 43, 63, 60, 60,124,255, 31,127,252,209,111,200,144, 33,252,218,181,107,107,142, 25,
- 51,198,243,171,175,190, 74, 26, 60,120,112,248,224,193,131,249,111,190,249, 70, 17, 27, 27,139, 14, 29, 58,192,199,199, 71, 87,
-222,252,229,229,229,221,101,174,108,223, 93,188,138, 16, 10, 67,181,246,219,146,108,230,215,246,202,206,206,134,201,100,162,162,
- 40,114,119, 54,161, 2,107, 30,254,221,216, 12,193,160, 65,131,138,212,107,155,169,216,182,109, 27, 6, 12, 24, 0,149, 74, 5,
-165, 82,137,200,200, 72, 87,202, 18, 4, 65,192,243,207, 63,111, 55, 42,127,252,241,135, 83,115,101, 27, 87,229,138,201,176,141,
-227,122,237,181,215, 32, 8, 2,126,248,225, 7,188,254,250,235,224,121, 30, 75,150, 44, 1,199,113,152, 56,113,162, 93,179,176,
- 93, 43, 51,157,130, 32,224,248,248,130, 59,145,160,217, 60,174, 70,221, 41,214, 33,161,161,119,234, 86,110,174,253,191, 93,221,
-159, 47,189,244, 18,148, 74, 37,222,120,227, 13, 8,130,128,241,227,199, 67, 16, 4, 68, 70, 70, 66, 16, 4,116,234,212,201,229,
-188, 59,166,243,224,193,131,246,207,117,235,214, 69,163, 70,141,160, 84, 42,209,166, 77, 27,168, 84, 42, 60,241,196, 19, 46,165,
-211,182, 79,151, 45, 91, 6,173, 86, 11,141, 70, 99, 59, 86,109,198,141, 27,215,207,217,250, 13, 26, 52, 96, 21,134,241, 32, 34,
- 88,166,168,168,168,179, 81, 81, 81, 78, 35, 84,197, 35, 73,165, 69,154, 28,140,213, 49, 20,118, 7, 78,156, 56,113, 50,238,140,
-221, 58,230,194,182, 42,155,185, 42, 30,229,114,164,120, 4,107, 70,241, 70,162,248, 64, 87,103,159, 21, 10,133, 75, 6, 75,167,
-211,157, 77, 75, 75,107,173, 86,171,237, 39,126,103,230, 42, 55, 55, 23, 60,207, 35, 37, 37, 5, 58,157,238,108,101, 30,196,178,
-186, 8, 19, 18, 18,142,133,132,132,140, 24, 57,114,228, 56,179,217,220, 80,161, 80, 40, 77, 38,147,234,207, 63,255, 36,219,182,
-109, 67,181,106,213, 48,118,236, 88,154,155,155,107, 33,132,152, 5, 65,136,205,203,203, 91, 26, 27, 27,187,170, 52,221,235,215,
-175,191,104, 48, 24,102,220,184,113, 99,212,212,169, 83, 61,198,141, 27,231, 63,102,204,152,156,152,152, 24,244,232,209, 3,190,
-190,190,118, 19,228,225,225,161,246,247,247,215,187, 51,157,132, 44,203,119,237, 67,199,125, 92, 56,246,172, 76, 56,142, 59, 73,
- 41, 29,154,159,159,159,173,213,106, 53,217,217,217, 22,199, 8, 99,110,110, 46,242,242,242, 32, 73,146,226,214,173, 91, 9, 0,
-234,113, 28,119,146, 53, 15,143,134,193,218,188,121,115,137,209, 38, 91,116,203,118, 65,181,109,219, 54,151, 34, 46, 27, 55,110,
-188, 43, 42,230,248,114,115, 28,167,125,155,229,203,151, 3,128,253, 2,144,227, 56,140, 27, 55, 14, 26,141, 6, 11, 22, 44,192,
-164, 73,147,236,219,165,165,165,185, 20,193,106,241,169,198,190,220, 22, 41,186,157,158, 14, 65, 16,224,233,225, 1,201,106,117,
-107,127,150,245,178,229,221,157, 40, 99, 73, 81,192,242,104, 2,216,220,171, 87,175, 94, 85,170, 84,193,240,225,195,161,211,233,
-208,191,127,127, 20, 20, 20, 12, 4,128,185,115,231,218,247,227,180,105,211, 48,125,250,116,228,231,231,155, 88,141, 97,220,163,
- 8,214,140, 82, 86,169, 98, 51, 78,133,102,200, 85,221, 77,142,235,219, 52,138,155,162,194,136,216,190,178,180,156,109, 91, 18,
- 10,155,115, 44,233,138,169, 44,115,101,123,185,114, 5,150,151,151,183,103,207,158, 61,145,207, 60,243,140,194,241,196, 95,220,
-104, 21,246,247,227,234,213,171,214,188,188,188, 61,174, 52, 60,149, 21,193, 42, 52, 89,219, 0,216,207, 30,126,126,126, 63,231,
-230,230,246, 12, 8, 8, 16,204,102, 51,178,178,178,174, 94,185,114,165,137,187, 5, 40, 41, 41,105,154,193, 96,168,213,165, 75,
-151,190, 61,123,246, 68, 64, 64,128,242,236,217,179,232,217,179, 39,234,213,171,231,149,151,119,199, 79,233,245,122, 53,207,243,
-126, 0,242, 92,205,147,179,136, 96, 94, 94, 30,178,178,178,144,159,159,239,114, 23, 33, 33,228, 32,165, 20, 31,127,252,113,246,
-244,233,211, 35,178,179,179,243,178,178,178, 36,199,200, 88,126,126, 62,209,233,116,138,213,171, 87,123,218,182, 97,205,195,163,
- 97,176, 92,121,185, 58,120,218, 49,130,229,104, 12,108,230, 64,165, 82, 97,221,186,117,197,199, 74,185,212, 69,248,227,143, 63,
- 98,244,232,209, 80,171,213, 88,186,116,233, 93,227,178, 56,142,179,167,147, 16,226,244,238,183,226,154, 45,231,105,113,126, 58,
-129, 82,169, 68,173,201,230,187,186, 8, 11, 47, 64,220, 74,231,119,223,125,231, 82, 23, 97,207,158, 61, 93,222,159, 45, 91,182,
- 4, 0,124,254,249,231,120,230,153,103,112,230,204, 25,167,186, 95,127,253,117,153,233,140,142,142, 30,220,188,121,243,154, 86,
-171, 53,166,113,227,198,138,155, 55,111, 98,192,128, 1, 88,183,110, 29, 10, 79,100,152, 56,113, 98,145,109,114,115,115,153,193,
- 98, 84,122,244,202,133,213, 82,139,141,159, 34,142,221,117,165,188, 23, 95, 31, 14,203, 28,117, 83,113,231,102, 46, 56, 89, 94,
-220, 84, 21,255, 15,199,117, 82,239,138, 96,185,210,232,150,102,182, 92, 49, 88,132,144,197,211,166, 77, 27,213,161, 67,135, 42,
- 94, 94, 94, 72, 74, 74,114, 26,193,242,242,242,130,197, 98,193,158, 61,123,114, 8, 33,139,203,144,181,138,162,168, 8, 8, 8,
- 64, 90, 90,154,211, 9,247,108, 13,163, 86,171, 69,110,110, 46, 0,184, 59, 57,166, 57, 39, 39, 71,124,254,249,231,133,197,139,
- 23,195,104, 52,150,187,129, 33,132,108, 61,113,226, 68,159,167,158,122,138,132,135,135, 43,108,198, 71,173, 86, 43,108, 17, 44,
-189, 94,175, 33,132,248, 2,184, 94,134,156, 47, 0,120,122,122, 38, 3,192,161, 67,135, 46, 56, 27,215, 54,121,242,228,122,133,
- 39, 5, 95, 0,180, 12,115,121,214, 96, 48, 44,255,233,167,159,134,119,234,212,233, 80,211,166, 77,107,100,100,100,100,229,230,
-230,154,243,243,243, 41,165, 84,161,211,233,132,253,251,247, 95,190,124,249,114,111, 0,203, 19, 18, 18,206,178, 38,226,223, 79,
-101,154, 43, 71, 67, 80, 60,130, 85,252,189, 60,154,175,191,254, 58,190,251,238, 59,123,221,182,233, 44, 88,176, 0, 60,207,227,
-163,143, 62,114,185,139,204,166,121,110, 26, 80,127, 58,197,157,225, 20,255, 31,193,242,244,242,186,179, 94, 9,109, 75,105,154,
-111,191,253, 54,148, 74, 37, 26, 54,108, 8, 65, 16,208,186,117,107, 8,130,128,174, 93,187, 66, 16, 4,151,140,213, 93,233, 60,
-119, 14, 74,165, 18,181,107,215,198,160, 65,131,208,186,117,107,116,232,208, 1, 74,165, 18,221,187,119, 7,207,243,232,217,179,
-103,153,131,251, 29,218,198,207, 62,249,228, 19,133, 70,163,129,217,108, 70,126,126, 62,210,211,211, 81, 82, 4,203,104, 52,170,
- 89,109, 97, 60, 0,142,221,103,221, 10,255,159,194,149, 10, 93,222,105, 26,138, 63,109,251,218,181,107,217, 6,131,225,229,231,
-159,127,126,205,146, 37, 75,180, 53,107,214,196,197,139, 23,145,145,145, 1,139,197, 2,165, 82, 9,131,193,128,220,220, 92,252,
-246,219,111,249, 70,163,241,229,164,164,164,236,210, 52, 9, 33, 51,159,126,250,233,105, 83,166, 76,225, 27, 52,104,128,140,140,
- 12,228,230,230,218, 27, 23, 66, 8,188,188,188,160,211,233,112,230,204, 25, 28, 62,124, 88, 34,132,204, 44, 77,211,201,137, 39,
- 62, 54, 54, 86, 94,180,104, 17, 10, 10, 10, 76, 86,171, 53,193, 5, 35,229, 84,147, 16,178, 59, 46, 46, 46, 23,128,167, 94,175,
-151, 83, 82, 82, 10, 0,104,100, 89,150,210,210,210,204,184, 51,135, 7,229,157, 56,214,226,154,148, 82, 83,225,114, 21, 0,100,
-102,102,222, 53,166, 45, 59, 59, 27,146, 36,169, 28,215, 47, 43,157,162, 40, 78, 16, 4,161,195,203, 47,191,220,182, 87,175, 94,
-167,134, 14, 29, 90,224,227,227,227,199,243,188,241,234,213,171,183,215,173, 91,167,190,114,229, 74,111, 0,215, 68, 81,156,224,
-106,222, 43, 24, 62,102,154,247, 80,211, 86,215,139, 71,166,221,137, 82,151,164,105, 27,135,228,248,178, 69,174,138,107, 22, 55,
- 5, 37,105,242, 60,143,177, 99,199, 22,137,138, 77,158, 60,185,196,121,249, 76, 38, 19, 41,109,127,218,182,139,251, 84, 85,164,
-251,205,152,159,239,116, 96,123, 89,233,180,105, 46, 90,180,168,220, 17,172,210,210,217,175, 95, 63, 36, 38, 38, 66, 16, 4, 28,
- 57,114,164,196, 8,150, 43,233, 4, 80,176,117,235, 86,104, 52, 26,252,246,219,111,214,192,192, 64,133,143,143, 79,137, 17,172,
-130,130, 2, 53,171, 71, 76,243, 94,104, 62,106,148,106,176,172, 86, 43, 66, 67, 67,237,230,137,227, 56,219,188, 50,224,121, 30,
- 28,199,217, 6,145,186,252,135, 73, 73, 73, 59, 13, 6,195,243,253,251,247,255, 97,248,240,225, 30,245,234,213, 19,194,195,195,
- 97, 52, 26, 17, 23, 23,135,184,184, 56,235,174, 93,187,114,140, 70,227,136,164,164,164,157,101,233, 37, 38, 38,206, 55, 24, 12,
-155,135, 13, 27, 54,171,105,211,166, 61,199,141, 27,135, 26, 53,106, 32, 43, 43, 11, 85,170, 84, 65, 64, 64, 0, 98, 99, 99,241,
-235,175,191, 34, 43, 43,107, 11,128, 41, 73, 73, 73,151,221,217, 73, 90,173,246,243, 79, 62,249,164, 99, 96, 96, 96,189,244,244,
-244, 4,165, 82, 57,185,188, 59, 60, 49, 49, 49,229,175,191,254,250,223,208,161, 67, 3,246,238,221,155,194,113,156,105,240,224,
-193, 97, 7, 15, 30, 76,225, 56,206, 52,100,200,144,176, 3, 7, 14,164, 36, 39, 39, 31,119, 67,214, 23, 0,158,126,250,233,219,
-197, 27,127,135,200,149,203,164,166,166,230,213,170, 85,171,189,209,104,140,218,188,121,243,240, 18,238, 22, 91,174,213,106, 39,
- 93,185,114, 37,143, 85,163, 71,164, 49, 80, 40,160, 82,169,202,101,174, 74,211,252,237,183,223,156, 70,174,138,107,186,218,142,
-148,102, 4,157,153, 43, 87, 34, 57,238,228,221,213,116, 42, 20, 10, 76,154, 52, 9,130, 32,160, 85,171, 86, 16, 4, 1, 93,186,
-116, 41, 18,185,114, 39,130,101,211,172, 83,231,206,163, 5,131,131,131,145,153,153,137, 46, 93,186,224,169,167,158,130, 66,161,
- 40,151, 46,165,244,173, 77,155, 54, 89, 41,165, 58,142,227,222, 79, 74, 74, 58,107,139, 42, 58,139, 96, 49, 24,140, 10, 26, 44,
- 65, 16, 82, 93,125,182,160, 13,149, 74,149,234,162,201,218, 81,171, 86,173,250,223,126,251,237, 27, 30, 30, 30, 93,140, 70, 99,
-163, 66, 35,115, 38, 55, 55,119,183, 66,161,248, 42, 41, 41, 41,199,213,255, 45, 52, 76,131, 12, 6, 67,219, 97,195,134,205,106,
-215,174, 93,235,215, 94,123, 13, 10,133, 2,107,215,174, 69, 98, 98,226,145, 66, 99,117,168, 60, 59,233,218,181,107,217, 40,253,
-246, 81,119, 26, 51, 43,128,142,149,121, 16, 29, 34, 89,165,254,238, 14, 87,174, 92,201, 1,240, 70, 80, 80,208,151, 60,207,183,
-151, 36,169, 25, 0,240, 60,127, 66,146,164, 3,201,201,201, 23, 89,245,121,116,144,101, 25,254,254,254, 69, 46,154,108,211, 30,
-148,215, 92,201,178,140,128,128, 0,251,120, 40,219, 69, 89, 25, 55,197, 16, 87,210, 73, 8, 41,162, 91,154, 38,165,148,154,205,
-102, 82,154,102, 96, 96,160, 61,159,149,145, 78, 73,146,236,154,182,180,242, 60,111,215, 46,239,254, 12, 12, 12,180, 13,115,168,
-148,116, 2, 64,116,116,116, 58,128, 97,182,239,145,145,145,155, 47, 94,188,216,171,164, 8, 22,131,193,168,160,193, 58,124,248,
-112,196,189,252,227,194, 19,120, 84,225,171, 82, 40, 52, 80, 93, 13, 6, 67,239,131, 7, 15,218,186,174, 62, 73, 74, 74,218,244,
- 95, 56,152,148, 82, 93,101,107, 22, 26, 41,102,166, 30, 97, 4, 65, 72,125,250,233,167,253,221,221,174,180, 11, 42, 65, 16, 82,
-187,119,239,238,182,166, 90,173, 78, 41, 69,243,102,143, 30, 61, 66,202,145,206,204,224,224, 96,169,178, 46, 36, 93, 72,103,185,
- 52,203,218,159,149,157,206, 82, 12,215, 96,131,193,112,208,207,207,175,166,201,100, 82, 26,141, 70,165, 99, 20, 80,171,213,166,
-177, 90,195, 96, 84,192, 96,253,155, 41, 52, 84,155,216,225,101, 48,202,230, 94, 92, 76,221, 11,205,131, 7, 15,214,249,175,230,
-253, 94, 95,240, 58,105, 67,219,177,154,193, 96, 84, 12,142,237, 2, 6,131,193, 96, 48, 24,140,202,133, 0,104,228,236, 7,119,
-238, 14, 32,132, 52,114,247,143,203,210,103,154, 76,147,105, 50, 77,166,201, 52,153,230,163,167, 89,150,246,163,114,119, 34,113,
-117,174,148,114,137,179, 91, 88,153, 38,211,100,154, 76,147,105, 50, 77,166,249, 31,132,117, 17, 50, 24, 12, 6,131,193, 96, 48,
-131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24, 12,102,176, 24, 12,
- 6,131,193, 96, 48, 30, 26,238,233, 93,132, 12, 6,131,193, 96, 48, 24,255, 69,236, 17, 44, 66,200, 94, 66,200, 94,182, 75, 24,
- 12, 6,131,193, 96,220, 79, 30, 69, 15,162, 40,204, 24, 69, 37, 61,204,152,193, 96, 48, 24, 12, 6,195, 13,115,245, 72,122, 16,
- 66, 41, 5, 33,132, 82, 74, 9, 59,204, 12, 6,131,193, 96, 48,238,183,193,122, 20, 61, 8, 27,228,206, 96, 48, 24, 12, 6,131,
-113,143, 12,214, 12, 54, 6,139,193, 96, 48, 24, 12,198, 3,224,145,244, 32,246,187, 8, 9, 33,157, 0,128, 82,202, 76, 22,131,
-193, 96, 48, 24,140,251,103, 70, 30, 65, 15,194,166,105, 96, 48, 24, 12, 6,131,193,168,100,238,233, 24, 44, 66, 72, 35,166,201,
- 52,153, 38,211,100,154, 76,147,105, 50, 77,102,176, 24, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,
-197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24,140, 7, 4, 1,224,244,
- 78, 0, 74,233, 25,151, 69,202,113, 55, 65, 89,250, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,244, 52,203,210,118,199,127,
- 60,212, 6,203,149,121,176, 72,225,131,130,220, 22, 39,164, 81,101,239,168,210, 52, 9, 33,164,240,224,208,202, 76,103,121,242,
-127,191,243,206, 52,153, 38,211,100,154, 76,147,105,254,155, 53, 31, 53, 20,101,236, 64, 14,119,186, 17, 9, 33, 68, 6, 32,211,
- 74,152,153,212, 65, 23, 0,228, 66, 79, 68, 43,160, 71, 0,240,182,252, 16, 66,172, 0,164,138,166,245, 94,229,255, 95,225,188,
-239,236, 83,242,255, 23, 20,108, 70, 90, 6,131,193, 96, 48, 42,100,176, 8, 33,164,126,253,250, 66,251,246,237,143,250,248,248,
-212,118,252,173, 79,159, 62, 0, 0,139,197, 34,109,219,182,205,211,221, 63,108,208,160,129,178, 52, 93, 73,146,164, 45, 91,182,
-184,172, 75, 8, 33,225,225,225,170,144,144,144, 35,222,222,222,181,156,105,202,178, 44,109,222,188,217, 45,205,178,242,239,110,
- 58,255,101,230, 74, 81,187,118,237,129, 58,157, 78,107, 91,214,172, 89, 51,199,223,105, 76, 76,204,143,172,250, 48, 24, 15,158,
-176,176,176, 81, 0,112,227,198,141,101,238,110,219,185,115,103, 69, 89, 23,218, 78,176,238,217,179,199,202,246, 60,131, 81, 14,
-131, 85,179,102, 77,165,191,191,255,190,176,176,176, 90,223,125,247, 29, 78,157, 58,133,230,205,155, 67, 20, 69, 88,173, 86,200,
-178,140,231,158,123,142, 47,143,185,242,247,247,223,111,211,189,117,235, 22,180, 90,251, 57, 28,146, 36, 97,196,136, 17, 46,235,
-218,204, 85, 68, 68,196,190,240,240,240,154,223,126,251, 45, 46, 93,186,132,234,213,171, 67,161, 80,192, 98,177, 32, 47, 47, 15,
-175,189,246,154, 91,105, 45, 41,255,178, 44, 67, 20, 69, 72,146,132, 33, 67,134,184,165,217,186,117,235, 75, 86,171, 53,196,157,
-109, 84, 42, 85,194,193,131, 7,235,148,244,123,219,182,109, 47, 89, 44, 22,183, 52,213,106,117,194,129, 3, 7,234,148,102,174,
-106,213,170,245,108,195,134, 13, 53,107,215,174, 69, 98, 98, 34,180, 90, 45,100, 89,134, 36, 73, 16, 69, 17,207, 60,243, 12, 97,
- 85,135,193,120,240,212,170, 85, 75, 69, 41,157, 66, 8, 65,173, 90,181,150, 95,185,114,197,236,206,246, 70,163,241, 26,165,212,
-167,132,182,192,233, 54, 60,207,103, 2, 8, 43,163,109, 14, 7,208, 83,161, 80,212, 84, 40, 20,117, 40,165, 97, 86,171, 53,160,
-176, 93, 75,225,121,254,134,197, 98,185,100, 54,155,175, 2,216, 66, 41,189,206,142, 38,227,145, 55, 88,132, 16,174,115,231,206,
- 91, 66, 67, 67, 27,124,247,221,119,132,231,121, 28, 60,120, 16,137,137,137, 8, 10, 10,130,167,167, 39, 52, 26, 77,121,162, 34,
- 92,231,206,157,255,114,212,221,180,105, 19,130,131,131, 17, 24, 24, 8, 15, 15,143,242,232,242,225,225,225,127,133,133,133,213,
-255,246,219,111,237,105,205,201,201,129,183,183, 55,242,242,242,144,146,146, 82,158,116, 86,122,254,101, 89,174,182,107,215, 46,
-120,122,122, 66,146, 36, 80, 74, 33,203, 50, 40,165,246, 87,145, 75, 68,171, 21,221,186,117,171, 86,234,101,164,213, 90,109,223,
-190,125,118, 3,228,168, 37, 73, 18, 84, 42, 21, 56,142,179,155, 87,139,197,130, 78,157, 58, 85, 43,205,176,214,174, 93,123,160,
-205, 92,241, 60,143, 53,107,214, 32, 48, 48, 16,190,190,190, 68,167,211,145, 66, 67, 76,203, 59, 46,143,193, 96, 84, 30,102,179,
-249,185,113,227,198,105, 11, 10, 10,240,245,215, 95, 63, 7, 96,185, 59,219, 75,146,228,183,127,255,254, 34, 23,186,101,172,143,
- 86,173, 90,249,149,209,134,118,247,243,243,251,185,109,219,182,130,191,191, 63,175,213,106,161,215,235,225,227,227, 3,141, 70,
- 3, 89,150,195,172, 86,107,152,201,100,122, 60, 37, 37, 69, 90,191,126,253, 76, 66,200, 11,148,210,109,236,136, 50, 30, 89,131,
- 85, 56,238,134,211,235,245,109,190,255,254,123,240,252,157, 32,141, 82,169,132, 70,163,129, 86,171,133, 70,163,129, 70,163,129,
- 36, 73,232,211,167, 79,190,227,246, 37,117, 27,150,166,171,213,106,139,232, 2, 40,162,107, 54,155,165,191,255,254,187, 36, 77,
-133,135,135, 71,171,239,190,251,206,174, 41, 73, 18, 50, 51, 51, 97,177, 88,144,147,147,131,212,212, 84,119,204,149,203,249, 47,
- 15, 58,157, 14, 27, 55,110,132, 66,161,128, 32, 8, 80, 42,149,246,119,219,103,219,119,127,127,127, 87, 35, 82, 56,120,240, 32,
- 56,142,179,111, 47, 8, 2, 54,111,222,140,247,222,123, 15,183,110,221,178,255,166,215,235,203,220, 5, 58,157, 78,107, 51, 87,
-182,188,139,162,168, 92,176, 96,193, 84, 15, 15, 15, 47, 0, 8, 14, 14, 70,112,112,240,162,242,118,193, 50, 24,140,202,193,203,
-203,235,195, 81,163, 70,169, 86,174, 92, 9, 65, 16, 38,185,107,176, 0, 64,171,213, 98,219,182,109,246,118, 73, 16, 4,240, 60,
- 15,149, 74, 5, 65, 16,138, 44, 15, 9, 9,113,165, 77,250,104,221,186,117,234,213,171, 87,227,202,149, 43, 40,140, 90, 65,175,
-215,195,203,203, 11, 62, 62, 62,240,245,245,133,159,159, 31,154, 53,107,198,191,250,234,171,124,135, 14, 29, 62, 2,192, 12, 22,
-227,209,142, 96,161,112, 96,243,169, 83,167,112,240,224, 65,251,201,222,199,199,167,136,193, 24, 60,120, 48, 94,124,241, 69,152,
- 76, 38,152,205,102, 88,173, 86,188,252,242,203, 69,186,205,156,221, 97,144,150,150,134,141, 27, 55, 66,165, 82,193,207,207,207,
- 30, 17,178,189, 58,119,238,140,119,223,125, 23,148, 82,100,100,100,148,165, 73, 0,224,242,229,203, 56,112,224, 0,172, 86, 43,
-180, 90, 45, 68, 81,196,173, 91,183,112,238,220, 57,196,197,197, 33, 47, 47, 15, 61,122,244,248, 90, 16,132, 89,127,252,241, 71,
-114,241, 52, 57,211, 44, 43,255,101,225, 44,239,146, 36,161,127,255,254, 32,132,128,231,121, 40, 20,138, 34,141,151,227,231,211,
-167, 79,187,164, 41,203, 50, 58,116,232, 0, 0,208,235,245,240,240,240,192,238,221,187,237,191, 55,111,222, 28,102,179, 25,254,
-254,254, 56,115,230,140, 75,154,201,201,201,248,249,231,159,109,198, 79,185,102,205,154,233, 53,107,214,212, 47, 93,186, 20, 9,
- 9, 9,208,233,116,144,101, 25,178, 44,195, 98,177,224,173,183,222, 42,243,184, 87, 20,166,201, 52,153,102, 81, 12, 6,195, 19,
- 31,125,244,145, 79, 94, 94, 30,242,243,243, 81,173, 90, 53, 15,131,193,240, 68, 82, 82,210, 78,119, 53, 21, 10, 5, 36, 73,194,
-214,173, 91, 17, 27, 27,139,157, 59,119,162,160,160, 0, 85,171, 86,133,143,143, 15,218,180,105,131, 17, 35, 70, 56, 53, 88,197,
- 53, 37, 73,250,153, 16,210,100,232,208,161,100,203,150, 45, 72, 75, 75, 67, 78, 78, 14, 44, 22, 11, 44, 22, 11, 4, 65,128, 78,
-167,131, 94,175,135,193, 96, 0,199,113,180,160,160,224,103,118,220,153,102, 25,180, 4,224, 24,121, 48, 3, 80, 57,188,167, 2,
- 56,230,100, 61,219,114, 1, 64,211,194,223, 36, 0, 57, 0,124,156,232,149,164,147, 6,128, 58, 44,179,173, 95,252,127,138, 26,
- 44, 66,136,173,171,167, 51,128,127,108, 39,230,164,164, 36,168,213,106,248,248,248,160,101,203,150, 0,128,220,220, 92,168, 84,
- 42,108,216,176, 1, 10,133, 2, 30, 30, 30,208,235,245,165, 70, 71, 40,165,180,240, 46, 60,232,245,122,132,132,132, 64,163,209,
-160,107,215,174,184,122,245, 42,170, 87,175,110,215, 61,117,234, 20,126,254,249,103,120,121,121,193,219,219,187, 44, 77, 17, 0,
-106,212,168,129,204,204, 76,100,101,101, 65, 20, 69, 28, 59,118, 12,221,187,119, 71,207,158, 61,161,211,233,144,150,150,134,227,
-199,143,247,152, 59,119,238, 51,189,122,245,122,105,243,230,205,127,151,149,206,226,249,119, 52, 88, 42,149,170, 92,165, 67,150,
-101,108,221,186,181, 72,164,170,120, 4,203,246, 94,210,248, 7,103,154, 71,142, 28,177,155, 51,133, 66, 97,143, 62, 17, 66,112,
-246,236, 89,112, 28, 7,165, 82,233, 82,157, 1, 0, 15, 15, 15, 4, 6, 6, 66,169, 84,146,111,190,249,102,106,173, 90,181,244,
- 75,151, 46, 37,182, 46,195,160,160, 32, 4, 4, 4, 64,175,215,151, 59,154,199, 96, 48, 92, 39, 44, 44, 44,134, 16, 18,164,215,
-235,137, 78,167, 3, 0, 68, 68, 68,112,195,134, 13,211, 28, 63,126, 28,190,190,190,232,219,183,175,215,234,213,171, 87,183,107,
-215, 78, 38,132, 32, 55, 55, 23,102,179,153, 18, 66,146, 47, 94,188,216,188, 52,125,158,231, 49,110,220, 56, 76,156, 56, 17,131,
- 6, 13,194,206,157, 59, 49, 97,194, 4,140, 24, 49,162,200, 5,160, 43,136,162,248,195,176, 97,195, 94, 89,183,110,221, 99,227,
-198,141,227, 10,163, 90,208,233,116, 32,132,192,100, 50,193,104, 52,162,160,160, 0, 23, 47, 94,148, 95,125,245,213,255,153,205,
-230, 31,216, 81,254,239,226,232, 65, 40,165,123, 75, 88,205,159, 16,178,201,225,124,221,155, 16,178,201,241,189,164,245, 10, 63,
-118,156, 52,105, 82,139,185,115,231,126,220,182,109,219, 53, 7, 15, 30, 92, 93,146, 94, 73, 58,147, 38, 77,106, 56,119,238,220,
-143, 29,215,119,242, 63,119, 71,176,238,120, 11, 66,225, 48,187,123, 80, 80,144,189,107, 44, 37, 37, 5, 90,173, 22, 30, 30, 30,
-144,101, 25, 30, 30, 30,240,244,244,132,135,135, 7,108,125,236,174,156,188, 1, 32, 48, 48, 16, 26,141, 6, 63,255,252, 51,106,
-214,172,137,191,254,250, 11,106,181, 26, 60,207, 67,167,211,193,195,195,195,254, 42, 3,201,214, 56,120,123,123,195,106,181, 98,
-231,206,157, 24, 55,110, 28,100, 89,198,149, 43, 87,240,245,215, 95,227,157,119,222, 65,147, 38, 77,252,190,255,254,251, 91, 35,
- 70,140, 88, 49, 96,192,128,230,191,255,254,123, 98, 73,158,197, 89,254,117, 58, 29,180, 90,173, 61,157,229, 53, 88,253,251,247,
- 7,207,243, 78,163, 86,142, 38,107,255,254,253, 46,107,182,105,211, 6, 58,157,206,126, 60,254,250,235, 47,251,239,173, 90,181,
- 2,165, 20,254,254,254,248,231,159,127,202,186, 34,161,205,154, 53,131, 44,203,168, 90,181, 42, 81, 40, 20,196,211,211,211,107,
-233,210,165,246, 60,171, 84, 42,123, 20, 79,173, 86, 67,173, 86,179,214,129,193,184,247, 39, 32,159, 46, 93,186,120,126,253,245,
-215, 69, 46,240,114,114,114,112,251,246,109, 84,169, 82, 5,193,193,193, 24, 55,110,156,206, 86, 87, 11, 10, 10,176,107,215, 46,
-188,255,254,251, 5,101,233, 27,141, 70, 88, 44, 22,132,135,135, 35, 58, 58, 26,121,121,121,120,226,137, 39,238,138,182,187, 24,
-217, 48, 19, 66,186,246,233,211,103,255,130, 5, 11,106, 52,104,208,128,228,229,229,193, 22,105,179,125, 62,115,230, 12, 93,189,
-122,117,108,126,126,126, 23, 74,169,153, 29,229,255, 54, 14, 30,132,148,177, 94,111, 23,245,108,235,221, 42,124, 87,207,157, 59,
-247,227,226,219,151,165,231,248,123,177,237,205,197, 76,217,173, 18, 13,150,227, 73,182, 79,159, 62,144, 36, 9, 94, 94, 94, 80,
-171,213,208,104, 52,168, 90,181,106,145,245,108, 39,115, 91,168,183, 44,131,101,211,149,101, 25,158,158,158,168, 93,251,255,103,
- 63,232,209,163,135,221, 44,216, 12,150, 77,223, 21, 77,139,197,130,220,220, 92, 36, 37, 37,161,123,247,238,160,148,226,242,229,
-203, 80, 42,149,248,254,251,239,241,246,219,111,163,160,160, 0, 30, 30, 30,129,195,135, 15,191,182,118,237,218, 79, 1, 60, 95,
-154, 38,128, 34,249,183,153, 9, 91,227,165, 80, 40,138,140, 21, 83, 40, 20,169,235,215,175,143, 40, 35,189,216,182,109, 91,153,
- 17, 44,165, 82,105, 31,156,238, 66, 33, 66, 76, 76,204, 93,227, 39,108, 17,176,147, 39, 79,218, 27, 72, 87,163, 98,146, 36,193,
-195,195,195,158,215,155, 55,111, 98,229,202,149, 80,169, 84,168, 82,165, 74,145,110, 93,102,176, 24,140,123,143, 36, 73, 79,237,
-221,187,119,219,248,241,227,253, 90,180,104,161,112,108,143,170, 84,169, 98,175,139,177,177,177,246,207,219,182,109,179,126,252,
-241,199,105,249,249,249, 79,151,165,239,235,235,139, 85,171, 86, 65, 16, 4,108,218,180, 9, 94, 94, 94, 24, 48, 96, 0,188,188,
-188, 48,126,252,120, 12, 25, 50, 4,130, 32,184,115,178,204, 38,132, 60,241,238,187,239,238,255,244,211, 79, 67,195,194,194, 96,
-177, 88, 96, 54,155, 97,177, 88,112,245,234, 85,172, 89,179, 38, 33, 63, 63,255, 9, 74,105, 54, 59,194, 12, 55, 46, 54, 54,185,
- 98,178, 28,214,139,182, 93, 71, 76,156, 56,113, 50, 33,100,211,196,137, 19, 39, 71, 69, 69,157,117, 69,175,132,223, 55, 23,190,
-247,114, 88, 22, 93,166,193,114, 60,201,218, 42,106,213,170, 85, 33,138, 34,120,158,183,159,248,191,250,234, 43,124,245,213, 87,
-246,245,179,178,178, 92,218, 57, 28,199, 65,163,209,216,186,237,208,163, 71, 15,236,222,189, 27,157, 58,117, 2, 0,119, 35, 88,
-246,171,175,212,212, 84,196,196,196,160, 87,175, 94,136,139,139,131, 74,165,178, 27, 21,133, 66, 1,165, 82, 9, 66, 8,158,122,
-234, 41,252,240,195, 15,237, 92, 49, 25,142,198,170,120,228, 42, 60, 60, 28, 11, 22, 44,176,127,239,211,167, 79,153,163,210,101,
- 89,198,179,207, 62, 91,196, 12, 21, 55, 88,182,116,111,222,188,217,101,131,213,169, 83, 39,251,254,242,244,244,196,250,245,235,
-237,191,119,236,216, 17,132, 16, 4, 4, 4, 96,211,166, 77, 46, 71,197,180, 90, 45,181,117, 43,234,245,122,123, 52,207,211,211,
- 19, 94, 94, 94, 44,130,197, 96,220, 71, 18, 18, 18,174, 24, 12,134, 86, 91,182,108,217,150,153,153, 25, 62,104,208, 32,141,227,
-152,208,226,175,133, 11, 23, 22,172, 89,179,230, 90, 78, 78, 78,143,196,196,196,219,101,233,219,218,164,220,220, 92,236,217,179,
- 7,191,252,242, 11, 90,180,104, 81,164,157,114, 55,114, 79, 41, 77, 35,132,116, 27, 63,126,252,158, 89,179,102, 5,249,249,249,
-193, 98,177,224,250,245,235,248,241,199, 31,147,243,242,242,186, 81, 74,211,216,209,101,184, 89,174,108,209,162, 64, 39, 63,247,
-114, 18,121,106,137, 59, 99,163, 76, 81, 81, 81,103,163,162,162,122, 19, 66, 54, 69, 69, 69,245, 46, 37,130,213,171,140, 8, 87,
- 47,220, 25,115, 85,122,189,114,112,105, 20,119,198, 96,217, 79,220,182, 19,168, 40,138,119, 93,189,124,252,241,199,232,223,191,
- 63,244,122, 61,130,131,131, 93,233, 34,180, 19, 18, 18,130,220,220, 92,244,232,209, 3,178, 44,131,227, 56,200,178,124,151,193,
-242,244,116,237,198,180,156,156, 28,220,186,117, 11,215,175, 95,135, 82,169,132, 36, 73, 24, 60,120, 48,226,226,226,224,237,237,
- 13,181, 90,109, 55, 46,158,158,158, 1, 22,139, 69,215,163, 71, 15,213, 95,127,253,101, 46,205,100,148,100,174, 0, 64,163,209,
- 96,207,158, 61,110,221, 85, 72, 41,197,230,205,155, 75, 29,123,101,123,119,117, 6, 4, 74, 41, 14, 29, 58,116, 87, 4,171,240,
-152,218,127,179, 13, 98,117, 21, 71,243, 36,203, 50, 2, 2, 2,236,121,181, 53,236,204, 96, 49, 24,247,143,164,164,164,244,144,
-144,144, 14,135, 15, 31,222,221,175, 95,191, 70,117,234,212,129, 36, 73,246,161, 11,182,250,185,125,251,118,252,252,243,207,255,
-179, 90,173,157, 19, 19, 19, 93,234,122,179, 88, 44, 80, 42,149,248,227,143, 63,208,178,101, 75, 68, 70, 70,218,219, 13,219,184,
- 78, 87,187, 8,139,181, 79,137,132,144,167, 23, 45, 90,180,119,193,130, 5, 62,185,185,185,248,241,199, 31,179,115,114,114,158,
-166,148, 38,178,163,202, 40,201,131,148, 65,116,177,232, 17,108,227,161,108,134,168,248,119, 0, 85,108,203, 38, 78,156, 56,217,
-213,237, 28,191,219, 34, 96,165, 24,175,187, 13, 22,165,148, 56,201,172,125, 64, 55,207,243,118, 3,100,195,214,133,103, 48, 24,
- 32, 73,146,203,221, 79,132, 16,228,229,229, 65,165, 82,217, 53, 29,181, 29,199, 18,185, 56, 48, 27, 89, 89, 89,246,249,174,110,
-221,186, 5,157, 78,135,191,254,250,203,110, 96, 28, 95,162, 40,222, 82, 42,149, 85, 74, 51, 87,142, 38,202,150,127,103,191,217,
-140,134,171,115,200, 80, 74,139, 92, 17,150,244,226, 56,206,101, 51, 36,203,178,189,241,227,121,222,254, 34,132,192,104, 52,150,
-235,202,211,214,104, 11,130, 64,109,223,245,122,253, 93,221,165,204, 96, 49, 24,247, 61,146, 85, 80,183,110, 93,191,238,221,187,
-195, 98,177,192,106,181,218,141,149,173, 13,142,140,140, 4, 33, 36,248,234,213,171, 46, 95, 81,173, 93,187, 22,215,174, 93,131,
-197, 98,193,236,217,179,139,152, 43,199, 87, 57, 35, 14, 87,155, 55,111, 46, 63,253,244,211, 56,116,232, 16, 52, 26,141, 72, 41,
-189,202,142, 38,195,161,140,184, 98, 32,210,138,141,117,178,125, 55, 23, 51, 59,197,191, 23, 95, 31, 0, 82, 0,240,101,108, 87,
-252,123, 90, 84, 84,212, 30, 91,228,171, 80,151, 47,105,252, 85,145, 8, 86,177,147,182, 52,112,224,192, 34,103,101, 65, 16,240,
-242,203, 47,227,194,133, 11,208,235,245,240,247,247,119,219, 92, 81, 74, 37,199, 25,224,121,158, 71,175, 94,189,112,227,198, 13,
-251, 88, 46, 63, 63, 63,119, 39, 29,149,166, 79,159,206, 3,119, 38,231,220,179,103, 15,158,122,234, 41,152,205,102,167, 6,107,
-253,250,245,178, 78,167, 59, 92,134,105,145, 6, 12, 24,224,212,149, 8,130,128, 38, 77,154,192,215,215,183,200, 28, 94,174,226,
-138,185,114, 23,155,169,114, 52, 89, 99,198,140,177,127,119,245,248, 0,128, 82,169,164,189,122,245,178,111, 16, 28, 28,108,143,
-102, 58, 51, 87,204, 96, 49, 24,247,143,208,208,208, 22,253,250,245,211,107,181, 90, 16, 66,144,147,147,131,215, 95,127, 61,135,
-227, 56, 44, 92,184,208, 51, 32, 32, 0,126,126,126,104,223,190,189, 50, 63, 63,255, 25, 0,191,186, 18,189,122,237,181,215,156,
-222, 45,104,155,184,216,246, 20, 11, 87, 47,122,157, 93, 92, 50, 24, 21,228,104, 25,223,221,221,254,158,227,212, 96, 57,155, 52,
-178, 79,159, 62,249,157, 58,117,194, 99,143, 61,102, 31,147, 99, 59,185, 23,143, 66, 57, 68,171,138, 60,109,123,211,166, 77,158,
-197, 53, 7, 12, 24,128, 51,103,206,192,219,219, 27,222,222,222,240,242,242,130,237, 54,228, 18, 34, 96, 69, 52,255,252,243, 79,
-187,230,160, 65,131, 2,191,255,254,251,147,173, 90,181,202,174, 82,165, 74,136,109,236,149,173,219,237,246,237,219,151,151, 44,
- 89, 98,240,243,243,235, 95,154,102,105,147,102,246,233,211, 39,127,202,148, 41, 56,119,238, 92,169, 17,172,146,158, 52,190,104,
-209, 34, 44, 59,112, 0,163,218,183, 47,245,192,124,249,229,151, 46,105, 82, 74,241,217,103,159, 85,154,230,145, 35, 71,126, 44,
-150,223,197, 0,236,221,172,142,198,202,113,166,120, 87,242, 94, 17,152, 38,211,100,154,128,151,151,215,152,209,163, 71,123, 80,
- 74,241,253,247,223, 91,190,250,234,171,124,179,217, 60, 14,128,178, 75,151, 46,159, 78,155, 54, 77, 63,104,208, 32,254,141, 55,
-222,240, 56,114,228,200,196,226, 6,203,153,102, 65, 65, 1, 22, 47, 94,236, 82, 27,178,108,217,178,114,229,221,241,252,224,138,
-217, 98,199,253,191,169,249,168,161,112,115,135,218,231,189,114,102,168,202, 67,126,126,126,145, 65,237,174, 14,108,119,198,186,
-117,235,110,245,234,213,107,248,168, 81,163, 86, 12, 25, 50, 36,238,153,103,158,129, 94,175,247, 55,153, 76, 41,191,254,250,171,
-180,116,233, 82,131,175,175,239, 27,127,254,249,103, 92, 69,211,173,211,233,138,116, 19,186, 16,185,186,113,245,234,213,136,249,
-243,231,115,121, 0, 62,231, 56,112, 28,103,191,113,160,184, 81,217,189,123,183, 85,165, 82,149,154, 78,149, 74,101,215,204, 39,
- 4,159, 19, 98,215,178,105,187,171,233, 52, 68, 40, 73, 69, 76,149,237,189,188,211, 85, 48, 24,140,242, 33, 73,210,147,102,179,
-153, 12, 28, 56, 48,239,242,229,203,219, 76, 38,211,216,184,184,184, 44, 0, 8, 15, 15,223, 53,123,246,236,229,191,253,246, 91,
-227,197,139, 23,123, 88,173,214,160,178,244,212,106,117,220,222,189,123, 67,103,206,156,201,167,113, 28,162, 28,134, 25,216, 94,
-142,109,211,238,221,187, 37,173, 86, 27, 95,145, 60,176,104, 22,131, 25,172,187,175, 64,164,178, 30,240,172, 84, 42, 37, 55, 27,
- 11,105,204,152, 49,124, 25,198,196, 45,205,205,155, 55,255, 61, 96,192,128,230,155, 54,109,250,120,237,218,181, 29, 76, 38,147,
- 86,165, 82,121,106, 52,154, 35,254,254,254, 3, 54,108,216,112,173, 66, 59, 76,161, 72,117,118,199,160, 82,169, 76, 45, 35,175,
-221,222,121,231,157, 93, 38,147, 41,194,149,255,209,106,181,137,121,121,121,221, 74, 91, 71, 20,197,110, 99,199,142,173, 84, 77,
- 39,166, 90, 26, 53,106, 84,169,199,200,195,195, 67, 98, 85,137,193,184, 47,164, 12, 27, 54, 44, 59, 35, 35, 99,116,114,114,114,
-145,137,237,174, 95,191,126, 19,192, 83,213,171, 87,127,177, 83,167, 78,115, 56,142, 43,243, 46, 39,171,213,218,245,179,207, 62,
-219, 97,177, 88,194, 92,249,115,149, 74,117,195, 98,177,116,115, 55,209,178, 44,147,228,228,100,204,155, 55, 47, 47, 61, 61,253,
- 32, 59,140,140,255, 2,228, 94, 94, 77, 60, 12, 97,201,178,238, 22,124, 88,210,201, 52,153, 38,211,100,154,143,170,166,175,175,
-239,102, 0,255,203,200,200,248,156, 82,154,192,246, 39,211,252, 47,160,120,212, 51,232,202,221,130, 12, 6,131,193,184,119,220,
-190,125,187, 23,219, 11,140,255, 26, 28,219, 5, 12, 6,131,193, 96, 48, 24,149, 11, 1,208,200,217, 15,238,132,254, 8, 33,141,
-220,253,227,178,244,153, 38,211,100,154, 76,147,105, 50, 77,166,249,232,105,150,165,253,168,116, 61, 62,242, 99,176,152, 38,211,
-100,154, 76,147,105, 50, 77,166,201,198, 96,221,111, 88, 23, 33,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,
-204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,227,161,129,176,
-231, 66, 49, 24, 12, 6,131,193, 96, 84, 46, 44,130,197, 96, 48, 24, 12, 6,131, 81,201, 40, 0,128, 16, 98, 15, 99, 81, 74, 9,
-219, 45, 12, 6,131,193, 96, 48,238, 7,143,170, 7, 81, 48, 99,197, 96, 48, 24, 12, 6,227, 65,242, 40,122, 16,206,153,131,100,
- 48, 24, 12, 6,131,193,184, 95, 60,138, 30,132,123,148,221, 35,131,193, 96, 48, 24,140,135,159, 71, 62,130,197,162, 88, 12, 6,
-131,193, 96, 48,238, 55,143,162, 7, 97,211, 52, 48, 24, 12, 6,131,193, 96, 84, 50,247,116,154, 6, 66, 72, 35,166,201, 52,153,
- 38,211,100,154, 76,147,105, 50, 77,102,176, 24, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96,
- 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24,140, 7, 4, 1,224,244, 78, 0,
- 74,233, 25,151, 69,202,113, 55, 65, 89,250, 76,147,105, 50, 77,166,201, 52,153, 38,211,124,244, 52,203,210,118,199,127, 60,212,
- 6,235, 94,206,131, 69, 8,105, 84,217, 59,138,105, 50, 77,166,201, 52,153, 38,211,100,154,143,158,230,163, 6,235, 34,100, 48,
- 24, 12, 6,131,193,168,100, 20,108, 23, 48, 24,174, 17, 25, 25,169, 85,171,213, 79,236,222,189, 91,121,254,252,121, 28, 61,122,
-148,174, 90,181, 74, 52,153, 76, 59,163,163,163,141,108, 15, 61, 26, 52,109,218,180, 27,207,243,239, 1,128, 36, 73,243, 79,158,
- 60,185,163, 2, 87,249,164,102,205,154,175,171,213,234,238,130, 32, 4, 73,146, 68, 76, 38, 83,114,126,126,254,206,164,164,164,
- 69,148, 82,185, 28,154,145,126,126,126,175, 54,106,212,168,214,213,171, 87, 19,226,227,227,215, 0,216, 1,160, 91,104,104,232,
-115, 53,107,214, 12, 57,115,230,204,149,244,244,244,239, 40,165,209, 15, 42,157, 12, 6, 51, 88,174, 85, 62,206,203,203,171,139,
- 32, 8, 35,141, 70, 99, 83,141, 70,115,150,227,184,239,210,210,210,182,177,138,247,232, 66, 8,225,131,130,130,186, 6, 4, 4,
-140,205,206,206,110,237,227,227,115,252,246,237,219, 11,175, 95,191,190,131, 82, 42,149, 83,147,211,233,116,157, 21, 10,197, 43,
-102,179, 57, 82,173, 86,159,150,101,249,251,156,156,156,237, 15,178, 44,181,111,223,254,180,213,106, 13, 46,109, 29,149, 74, 37,
-236,218,181,139, 95,191,126, 61,253,249,231,159,111, 63,247,220,115,250, 17, 35, 70, 40,150, 47, 95,190, 12,192,248,226,235,183,
-105,211, 38, 78, 20, 69,127, 87,254, 95, 16,132,212,195,135, 15, 71,176, 82,247,224,225,121,254,189, 17,115,247,180,151, 41,176,
-124, 82,103, 20,154,151,114,209,188,121,243,111,251,245,235,247,108,157, 58,117, 20,178, 44, 67, 20, 69,152, 76,166,199, 98, 98,
- 98, 30,223,182,109, 91,115, 0,195,220,172, 63, 61, 38, 78,156,248,213,204,153, 51,171, 10,130, 64, 68, 81,108,245,203, 47,191,
- 60, 53,102,204,152,211, 95,127,253,117,227, 33, 67,134,120,216,150, 79,155, 54,237, 41, 66,200, 4, 74,233,186,251,157, 78, 6,
-131, 81,134,193,242,242,242,170,165,213,106, 71,121,122,122,118,175, 93,187,118,226,136, 17, 35,142, 89, 44,150,255,241, 60, 79,
- 87,172, 88,241,182,217,108,254, 44, 56, 56,120,187,201,100, 90,154,158,158,126,201,205,134,162, 22,128, 17, 0,158, 2, 96, 0,
-112, 19,192, 54, 0, 63, 82, 74, 47,151, 39, 51, 33, 33, 33, 13,181, 90,237, 56,158,231, 91,230,229,229, 5,235,116,186,100, 0,
-199,114,114,114, 22, 38, 37, 37,157, 44,143,102,104,104,104, 13, 0,163,149, 74,101,123,171,213, 26, 33, 8,194, 13, 81, 20, 15,
- 72,146,180, 52, 33, 33,225, 74,121, 52,219,133,123,245,164,122,207, 40, 11,209,132,228,153, 36,165, 94,197,139, 74,106, 74,144,
-242,179,166, 30,189,158,179,225, 65, 23, 10,131,193, 80,167, 90,181,106,111,213,174, 93,123, 96,120,120,184,114,232,208,161,202,
- 78,157, 58, 97,239,222,189, 29, 86,173, 90,213, 74,169, 84, 90, 90,181,106,245,123, 98, 98,226,162,164,164, 36,151,142,187, 90,
-173,174,233,225,225,241,154, 78,167,235, 94,183,110,221,228, 55,223,124,243, 82, 76, 76,204,197,198,141, 27,199, 47, 93,186,244,
-173, 75,151, 46,205, 11, 8, 8,248,187,160,160,224,219,156,156,156,203,247, 59,207, 38,147,169,230,190,125,251,160, 82,169,156,
-254, 46,203, 50, 6, 15, 30, 12,149, 74,133,165, 75,151,146,163, 71,143,206, 52, 26,141, 83,190,250,234, 43,191,229,203,151,247,
-119,102,176, 68, 81,244, 63,116,232, 16,148, 74,229, 93,122, 86,171, 21, 22,139, 5, 22,139, 5, 70,163, 17,125,250,244,241,103,
-205,209,195, 1,165,180, 26, 5,176,245, 84, 1, 0,248, 84, 68, 75,163,209,212,233,223,191,191, 34, 45, 45, 13, 10,133, 2, 22,
-139, 5, 55,111,222, 68,205,154, 53,121,147,201,244,152,187,122,117,235,214,125, 53, 42, 42,202,127,203,150, 45,150, 85,171, 86,
-153,187,117,235, 38,140, 24, 49,194,179, 83,167, 78,237, 66, 66, 66,184, 31,126,248,193,180, 99,199, 14,113,232,208,161,170,143,
- 63,254,216,127,235,214,173,207, 2, 88,119,191,211,201, 96, 48, 74, 49, 88, 58,157,110,139, 74,165, 10, 27, 52,104,208,190, 41,
- 83,166, 44,246,243,243, 19, 1, 96,245,234,213,134,193,131, 7, 39,191,241,198, 27,113,153,153,153,138,153, 51,103, 54, 90,185,
-114,229,111, 90,173,246,150,209,104,124,194, 5, 99, 69, 0,188,193,113,220,232,150, 45, 91,110,145, 36,233,202,238,221,187,231,
- 62,241,196, 19,253, 0,208,227,199,143,255, 70, 8,249, 1,192, 23,174, 70, 52, 8, 33,124,245,234,213, 63, 12, 14, 14, 30,251,
-245,215, 95,171,171, 87,175, 14,157, 78,135,156,156,156,208,203,151, 47,135,140, 29, 59,182, 87,205,154, 53,191,246,246,246,158,
- 17, 29, 29, 45,186,168, 73,130,131,131,223,244,242,242,154, 58,127,254,124, 77,157, 58,117,136, 94,175, 71, 98, 98, 98,131, 99,
-199,142,213, 95,184,112,225,139,161,161,161, 31, 39, 36, 36,184,156,206,206,132, 40, 10,106, 85,253,163,202, 99, 45, 59,126,253,
-205,119,164,154, 78, 7,129,227, 32, 90, 44, 66, 66, 94, 94,245, 55, 95, 31,189,178,205, 99,129,135,114,133,148, 94,231,206, 81,
-203,131, 40, 16, 53,107,214, 60,237,233,233, 25,214,191,127,127, 97,208,160, 65,168, 89,179,166,253,183, 97,195,134, 97,216,176,
- 97,202,171, 87,175, 42,215,173, 91,247,210,202,149, 43,159,175, 94,189,122,124,108,108,108,163, 50,204,213, 38,173, 86, 27, 62,
-106,212,168,147,227,199,143,223,231,233,233,105, 1,144,116,250,244,105,105,232,208,161,255,123,229,149, 87, 18,114,114,114,240,
-225,135, 31,134,175, 90,181,106,173, 90,173, 78, 49,153, 76, 79,221,239,188,235,116, 58,156, 58,117,170,200, 50, 73,146,144,150,
-150,134,219,183,111, 35, 63, 63, 31,153,153,153, 40,188,194, 47,144,101, 25, 28,199, 1,119,238,198,117,138, 82,169, 68, 76, 76,
- 12,156,152, 47, 20, 20, 20,192, 98,177,128, 2, 80,168,212,232,216,237,201,255, 17,138, 77, 57, 5,249,139, 78, 28, 60,120,131,
- 53, 79, 15, 6,142,227,174,254,185,239, 74, 13, 0, 22, 0, 23, 43, 40, 39, 3,192,190,125,251,112,235,214, 45,164,166,166, 34,
- 53, 53, 21,161,161,161, 40, 79,196,246,226,197,139, 95, 53,111,222,156,156, 56,113, 98, 11,128, 31,127,249,229,151,190,183,111,
-223,254,226,131, 15, 62,168, 50,111,222,188,140,241,227,199,143, 5,240,199, 47,191,252, 50,172, 73,147, 38, 61, 79,157, 58,245,
-229,131, 72, 39,131,193, 40,101,144, 59,165, 52, 40, 44, 44,236,198,138, 21, 43, 58,142, 30, 61,186, 94,122,122,186, 0, 0,254,
-254,254, 38, 0,200,204,204, 84,188,246,218,107, 13,191,255,254,251,142, 26,141, 38, 65,146,164,170, 78, 52,156,221, 97, 48, 70,
-167,211, 61,125,238,220,185, 79,107,213,170,165,153, 51,103,206, 30,189, 94,143, 47,191,252,114, 87, 72, 72,136,247,165, 75,151,
- 62,214,235,245,143, 3, 24, 91, 66,186,238,210,140,136,136,152,252,236,179,207,142, 61,112,224,128,186, 73,147, 38,240,244,244,
- 4,207,243,240,241,241, 65,235,214,173,201,190,125,251,212,189,122,245, 26,147,149,149, 53,199, 85,205,208,208,208,177,189,123,
-247,158, 22, 29, 29,173,109,215,174, 29, 17, 4, 1, 89, 89, 89, 80, 42,149,104,219,182, 45, 89,179,106,149,182, 69,179,102,147,
- 67, 67, 67,167,184,170,105,170, 93,117,211,224,209,227, 59,109,250,107, 27, 9, 8, 8,128,105,230, 76,100, 53,108, 8,211,132,
- 9, 8,172, 86, 13,127,110,217, 74,122, 15,123,189,157,167, 24,176,197, 85,205, 74,184, 90, 47,162, 89, 80, 80, 80,179, 89,179,
-102,252,193,131, 7, 77, 87,174, 92, 49, 22,191,203,148, 82,138,115,231,206,229,255,245,215, 95,121,126,126,126, 48,155,205, 53,
-202,210,164,148, 86,123,252,241,199,197,229,203,151,183, 27, 53,106,148,112,243,230,205, 67, 0, 46, 85,169, 82, 37, 1, 64, 98,
- 74, 74, 74,236,243,207, 63, 31,188,114,229,202,174, 85,171, 86, 77,162,148,250, 63,136,188,219, 12, 85,241,151, 44,203,144, 36,
- 9,213,170, 85,195,166, 77,155,208,171, 87, 47,180,105,211,230,147,190,125,251,170,143, 30, 61, 74, 9, 33,127,185,147, 78, 89,
-150, 81, 80, 80, 0,163,209,136,164,228,100, 44, 90,178, 20, 71, 14, 30,192, 47, 43,126, 50,188,249,250,152,215,188,117,158, 7,
-155,181,107, 23,118,191,243,206, 52,237,191, 39,222, 49, 87, 36,159, 82,122,189,188,154,253,251,247,111, 16, 17, 17, 17,176,246,
-108, 21,100, 40,235, 66, 18,188, 33,171,124, 32,249,181,192,255,148, 79,195, 96, 48, 4, 68, 68, 68,180,118, 71,147, 82,186, 43,
- 38, 38,230, 25, 74,233,119,148, 82,137, 82,186,126,252,248,241,175, 19, 66, 54,140, 31, 63,254, 45, 74,233,250,194,229,203, 79,
-158, 60,249, 44,165,116,223,131, 72, 39, 43, 75, 76,243, 30,208, 18, 64,175,194, 87, 43, 0,173,139,125, 87, 21, 91,175, 91, 9,
-239,189,138,125,111, 89,108,187,150,149,106,176, 8, 33,212,246,114,136,224,136, 75,151, 46,253,253,155,111,190, 89,154,154,154,
- 26, 80,163, 70,141,119, 59,116,232,208,254,234,213,171,186,142, 29, 59,182, 55, 24, 12,227, 98, 98, 98, 2, 6, 12, 24,240,205,
-139, 47,190,248, 43, 33,196,234, 66, 84,168, 6,199,113,111, 28, 60,120,112, 77,221,186,117, 77,201,201,201, 62,221,186,117,203,
- 0,128,200,200,200,220,204,204, 76, 15,127,127,127,105,227,198,141,191, 17, 66, 94, 38,132,148, 25,154, 14, 14, 14,110, 82,181,
-106,213,177,115,230,204, 81,243, 60, 95, 82, 4, 5,179,103,207, 86,123,121,121,189, 28, 18, 18,210,170, 44, 77,131,193, 80,199,
-211,211,243,195,207, 63,255, 92, 83, 80, 80, 0,171,213, 10,127,127,127,232,116, 58,164,167,165, 33,229,198, 13,100, 38, 37, 96,
-242,187, 99,181,122,173,246,205,224,224,224,198,101,105,118,168,238,217, 91,111,168,247,248,219, 99,223, 69,193, 43,175, 32, 95,
-163, 65,254,184,113, 48, 69, 71, 35,127,238, 92,152,170, 84, 65,193, 83, 79,225,221,119,223,131, 42,160,102,155,182, 97, 30,207,
- 62, 40,215, 61,117,234, 84,238,221,119,223, 85,111,218,180, 73,211,169, 83, 39,243,143, 63,254,152,147,151,151,135,175,190,250,
- 42, 39, 50, 50,178, 96,233,210,165,154, 54,109,218,232,187,118,237, 42,184, 24, 17, 16, 87,174, 92,121,122,217,178,101,115, 46,
- 95,190, 44,212,174, 93,123,102,211,166, 77,123,230,228,228, 8,173, 91,183,238, 21, 22, 22, 22, 21, 19, 19, 83,165, 71,143, 30,
-179, 62,252,240,195,213, 0, 68, 60, 36,240, 60, 15,133, 66, 1,133, 66,129,250,245,235,227,151, 95,126, 65,112,112, 48,190,253,
-246, 91,159,192,192, 64,221,242,229,203,179, 50, 51, 51, 63,119, 71,211,108, 54,195,100, 50,193,104, 52, 34,250,196, 73,252,245,
-199, 6,172, 88,245, 51, 94,122,245,181, 12,171,213,106, 26, 51,234, 53, 79, 79,141,238,109,118,253,247, 96,184, 51,190,144,228,
- 3, 52,151, 16, 98, 6,128, 90,181,106,169, 66, 66, 66, 90,213,170, 85, 75,229,170,142,209,104, 92,188, 96,193,130, 96, 78,237,
-131,127,204, 61,241, 11,157,137,237,222, 95, 33, 53, 98, 60, 2, 67,107,163, 71,143, 30,254, 0, 22, 84, 66,122, 55, 81, 74,135,
- 82, 74, 55,150,103,251,123,157,206,200,200,200,246,145,145,145,255, 68, 70, 70, 94, 43,124,111, 95,209, 60, 47,157, 66,186,252,
- 48, 85,245,191,175, 39,145,252, 31,166,170,254,183,116, 10,233,194, 74,238,191, 23,103, 30,196, 9,254,132,144, 77,132,144, 77,
-147, 38, 77,234, 2,192,175,216,247,118,142,235, 1, 80, 57,123,183,189, 28,150,251, 23, 26, 43,127,135,239,149,130,194,161,146,
- 58,237,230, 8, 13, 13, 53,206,155, 55,111,123, 94, 94,222,238, 47,190,248,162,229,187,239,190, 59, 44, 56, 56,120,223,179,207,
- 62,251,185,151,151,151, 40, 8,130, 59,255,247, 82,155, 54,109,126, 15, 13, 13,149, 19, 19, 19,149,162, 40, 42,175, 93,187,166,
- 22, 69,145, 8,130, 64,141, 70,163,112,230,204, 25,165, 40,138, 82,195,134, 13,215,158, 57,115,102, 4,128, 9,165, 9,106,181,
-218, 81,223,124,243,141,166, 36,115, 37, 73, 18,114,115,115, 97,181, 90, 49, 99,198, 12,205, 7, 31,124,240, 58,128,163,165,105,
- 10,130,240,250, 87, 95,125,165, 17, 69, 17,182,252, 93,186,116, 9, 89, 25, 25, 16,115,115, 97,201,205,134, 53, 55, 11,138,124,
- 47,140, 29,246,130, 38,234,219,239,223, 6,240, 74,105,154, 22,149,199,172,159,190,253, 30,162, 40,194,188,102,141,211,117,196,
- 61,123, 0,179, 25,179, 63,158, 75,222, 27,245,252, 12, 0,191, 62,160, 19, 12,120,158,199,203, 47,191, 76,204,102,179,234,207,
- 63,255, 84, 53,110,220, 88,106,214,172,153,103,191,126,253, 96,181, 90,145,149,149, 5,141, 70,227,142,172, 84,189,122,245,252,
-111,190,249,230,247,244,244,244, 63, 63,249,228,147,199, 23, 45, 90, 52,210,223,223,127,203,224,193,131, 39,123,122,122, 90, 84,
- 42, 21,172, 86,171,215,195, 86,249, 5, 65,128, 86,171,133,193, 96, 64,239,222,189,177,104,209, 34,240, 60,159,206,243,252,246,
-220,220,220,121,103,206,156,137,117, 71,207, 98,177,192,100, 50,161,160,160, 0,113, 55,226, 33,138, 34,150,175, 92,137, 3,123,
-118,127, 68, 41,157,185,122,197, 79,186,175,150, 45,235, 7,224, 61,214,244,222, 95, 6, 13, 26,196, 19, 66,124,106, 85,211,228,
- 17,142,230, 31,162,180, 74, 88, 88,216, 48,171,213,218, 53, 52, 52,180,106,124,124,124, 90, 72, 72,200, 14,179,217,252, 71,106,
-106,106, 94, 25,145, 74, 98,181, 90, 49,170, 85, 38,198,180,225, 96,181, 90,145,153,153,137, 27, 55,110,224,236,217,179, 56,114,
-228,108,185,210, 24, 17, 17,241,146, 86,171,125, 66,169, 84,134, 83, 74,185,188,188,188, 27,102,179,121,119, 98, 98,226,247,180,
- 28, 19, 27,222,171,116, 58, 16, 53, 96,192,128, 32,111,111,111,196,196,196, 4,157, 58,117, 42, 10, 64,135,138, 8, 42,137,114,
-233,224,215,119, 27,116,158,129, 72,185,244,139, 97,203,198,153, 75, 1,212,102, 37,248, 95,125, 97, 67,202, 88, 37,149, 82,218,
-187,208,144,109,138,138,138,234, 93,184, 93,111,199,239, 46,252, 79,111, 39, 6,111,147,179,229,149,102,176, 8, 33,180,180, 12,
-234,245,122,235,135, 31,126,120,104,239,222,189,145,237,219,183, 63,224,166,177,178,209,230,177,199, 30,139,254,251,239,191,253,
-130,130,130, 76,178, 44, 19, 47, 47, 47,171,167,167,167, 84, 56,182,133,198,198,198, 10,177,177,177, 30,126,126,126, 18,128, 54,
- 46,156,252, 90,215,168, 81,163,196, 72, 65,110,110, 46,114,114,114, 96, 50,153, 16, 24, 24, 72, 56,142, 43, 51,252,167, 80, 40,
-218,213,174, 93,155,228,228,228, 32, 48, 48, 16,167, 78,157, 66, 65,110, 46,196,188, 28, 88,179,115, 32,229,102,129,102,103, 34,
- 47, 43, 19, 53, 2,170, 18,158,231,203,140,138, 89,121,109,168, 65,175,135,121,226, 68, 88,254,247, 63, 64,169,132, 50, 60, 28,
-176,220, 25,106,101,137,139, 3, 84, 42,112,175,188,130,218,175,190, 10, 43,212,134, 7, 88,208, 97, 54,155,145,159,159, 15,165,
- 82,137,129, 3, 7, 98,239,222,189,150,150, 45, 91,106, 18, 18, 18, 96, 54,155,193,113, 28, 36,201,245, 27, 9,101, 89,150, 56,
-142,163, 0,224,231,231, 39,206,155, 55,111, 87,199,142, 29, 59,119,235,214,109,187,227,192,114,147,201, 36, 3,160, 15, 83,197,
- 87,171,213, 48, 26,141, 32,132,216,198,246,225,194,133, 11,225,229,209,146, 36, 9, 22,139,197, 30,197,146,101, 25,135,143, 29,
-130, 70,171, 69,235,199, 59, 78,150,101, 89, 43, 40, 20,224, 11, 7,119, 49,238, 31,173, 91,183,110,174,164,214, 57,175, 27, 44,
- 97, 79, 15, 8,201,211,232, 20,121, 3,182,152, 59,215,172,213,250,153, 57,179,231,120,212,168, 81, 67,127,226,196,137,220, 57,
-115,230, 4, 31, 63,126, 28, 0,126, 46, 77, 47, 49, 49,113,195,220,185,115,171,116,238,220,185,186, 32, 8, 36, 51, 51, 19,169,
-169,169, 72, 73, 73, 65,124,124, 60,141,141,141,189, 38,138,226,239,238,164,177,105,211,166, 75,134, 14, 29,250,124,131, 6, 13,
- 4, 74, 41, 68, 81, 68,126,126,126,147, 35, 71,142,244,250,231,159,127,218, 1,120,217,221,124, 39, 37, 37,173,159, 59,119,174,
-190,115,231,206,143, 9,130,192, 85, 70, 58,139, 17,228,233,233,137, 29, 59,118,192,219,219, 27, 0,130, 42,122,172,204,162,197,
-160,243, 50, 0,113,159, 35,192, 39, 12,102,209, 98, 96, 37,248,223, 31,197, 42,195,100, 29, 3,208,171,162,102,232, 94,153,169,
-114, 69,176,108,220,186,117, 75,157,147,147,163,160,148,114,146, 36, 41,100, 89, 38,106,181,218,221,174,156,250,207, 62,251,236,
-111,221,187,119,207, 4, 0,165, 82, 41,250,249,249, 89, 51, 50, 50,144,149,149, 5,171,213, 42,121,121,121,229, 87,171, 86, 45,
-191, 94,189,122,217,187,119,239, 46,179,139,208,104, 52,134, 56,139,164,228,231,231, 35, 55, 55,215,110,176,242,243,243,225,229,
-229,133,188,188,188, 50, 43,183,197, 98, 9,211,106,181, 72, 77, 77, 69, 90, 90, 26, 10,114,179, 97,201,201,133, 53, 55, 27,214,
-236, 44,200, 57, 89,160,185, 57,144,101, 9, 85,252,253, 97, 54,155, 67,202,210,204, 55, 73, 42, 1,128,241,247,223,129,119,222,
- 41,217,220,236,222, 13, 93,157, 58, 48, 26, 45, 15,108,142, 50,199,139, 96,139,197, 2,171,213, 10, 74, 41, 53,155,205, 48,155,
-205,142,166,201, 77,111,113,199,144,157, 60,121,210, 43, 37, 37, 69, 67, 41,229,115,115,115,213,121,121,121, 92,213,170, 85, 11,
- 0, 80,171,213, 42, 61,108, 21,223,241,142, 63,179,217,236, 86,190,139,155, 80,171,213, 10,171,213,122, 39,146,105, 54,195,108,
- 49, 97,225,162, 37,216,176,246, 23,156, 63,127, 46,120,202,204,217, 16,173, 86, 72, 50, 27, 87,124,191,104,210,164,201,147, 60,
-207, 47,108,227, 45,123,142, 13, 17,115,171,170,228,188, 75, 95,189,149,119, 42, 84,107, 44, 48, 90, 12, 81,139, 62,246,163, 20,
-248,240,195, 15,111, 13, 30, 60,216,227,221,119,223,109, 56,100,200,144,110, 13, 26, 52,248,245,220,185,115,150, 18, 26,113,229,
-136, 17, 35,142, 85,169, 82,165,198,202,149, 43, 83,146,147,147,125, 69, 81,212,154,205,102,139,217,108,190,102, 54,155, 15,138,
-162,184, 59, 41, 41,233,132, 59,105,213,235,245,141,134, 12, 25, 34,100,100,100,216,239,246, 75, 77, 77, 69,243,230,205,249,157,
- 59,119,214, 47, 79,254,207,159, 63,191, 40, 56, 56,120,223,159,127,254,249,132,135,135, 71, 51,149, 74, 21, 40,203,178,100, 52,
- 26, 83,140, 70,227,233,242,164,179, 24,201, 49, 49, 49, 65, 94, 94, 94, 72, 72, 72, 0,128,228,138, 30, 51,149,160, 76, 72,185,
-252, 75, 72,128,119, 13, 92, 61,191, 25, 42, 65,153,192, 74,242, 35, 31,193,106,233, 24,177, 42,197, 36, 25, 39, 78,156, 56,153,
- 16,178,105,226,196,137,147, 75,137, 96, 73,142,235, 57,172,111,170,116,131,229,140,188,188, 60,197,177, 99,199,252,110,221,186,
-229, 17, 16, 16,144, 87,191,126,253, 76, 66, 8, 40,165, 36, 59, 59, 91,151,146,146,162,211,235,245,166,240,240,240,108, 23,255,
-239,127,239,188,243, 78,223, 9, 19, 38,236,120,225,133, 23,146, 1, 32, 35, 35, 3,183,110,221, 66,122,122, 58, 44, 22, 11, 18,
- 19, 19,201,254,253,251, 3,119,238,220,217, 21, 64, 92, 89,130, 90,173, 54, 33, 39, 39,167,182,143,143,143,221, 28,216, 76,149,
-227,187,197, 98, 65, 78, 78, 14,244,122,125,153,149, 91, 16,132,164,212,212,212,154,102,147, 9,169, 9, 9,119,140, 85,110, 14,
-164,236, 76, 72,217, 89, 32,121, 57, 80,138, 34,212,130,128,156,219,233, 80, 42,149,183,202,210,212,169,121,179,217,106, 85,241,
-125,250, 0,164,228,114, 68,219,181,195,237,134, 13,161,217,244,187,248, 0, 11,186,211,239,197,141,133, 59, 70,227,246,237,219,
-220,162, 69,139,234, 95,186,116,201, 35, 32, 32, 32,173, 91,183,110,177,132, 16,202,113,156,156,146,146,226,123,233,210,165,218,
- 62, 62, 62,121,130, 32,164, 62,168,124,139,162,232,212, 92,229,231,231,219, 35, 78, 89, 89, 89, 80, 40, 20,232,216,177,227,110,
-147,201,180,158, 16,178,226,200,145, 35, 57,165,152,245,187,246,153, 44,203,118,147,165,224, 20, 88,191,118, 45,190, 92,246, 37,
-126,255,253, 79, 58,248,217, 1,100,239,190,253,144,101,154,200,154,220,251, 3,207,243, 31, 31,152, 48,208,147, 72,214,220,204,
- 93,107,243,191,140, 87,229,109, 62,121,230, 64,126,129,153,175, 94,179, 70,189,136,240,234,194,148,105, 19, 82, 78, 93, 56, 28,
-151,241,117, 70,181,247,223,127, 63,188,118,237,218,129,177,177,177, 53, 1, 92,112,166,233,233,233, 25, 54,124,248,240, 23, 51,
- 51, 51,133,239,191,255,126, 85,124,124,252, 1, 74,233,181, 98, 38,172, 41, 33,228,227,194,118, 56, 0,128, 4, 96, 39,165,116,
-117, 41,201,149, 9, 33,216,179,103,207, 93,119,251, 73,146, 84,110, 87,158,148,148,148,217,166, 77,155, 70,151, 46, 93,218,148,
-145,145,241,203, 93,237,151, 78,215,171, 97,195,134,207, 30, 61,122,116, 22,165,244,170, 59,218, 28,199, 77, 56,123,246,236,108,
- 74,105, 24, 33,228, 6,199,113, 31, 85,244,152, 89,168,229,245, 45, 27,166,127,101,182,152, 67, 85, 74, 85,188,133, 90,222, 96,
- 37,249,145,199, 54, 70, 10,142,198,201,137, 49, 58, 24, 21, 21,165,157, 59,119, 46,162,162,162,206, 58,139, 96,217,140, 86, 84,
- 84,212, 89,219,122, 14,235,239,171, 84,131,229,204, 57, 74,146,164,153, 59,119,110,187, 6, 13, 26, 36,181,111,223, 62, 41, 52,
- 52,212,104, 59,217, 42, 20, 10, 49, 32, 32, 32,203,106,181, 22,220,186,117,171,234,190,125,251,170, 83, 74, 93, 25,252,185,215,
-211,211, 83,121,252,248,241,160, 95,126,249,165,201,197,139, 23,235,244,234,213,203, 30, 29, 72, 72, 72,168,179,112,225, 66, 73,
-173, 86,167,241, 60, 31, 13,160,204, 65, 62,162, 40, 30,185,124,249,114,173,214,173, 91, 19, 81, 20,139,152, 42,199,207, 42,149,
- 10, 9, 9, 9, 84,150,229, 99, 46, 24,140, 99,167, 78,156,168,217,176,110,221, 59,230, 42, 39, 11, 82,118, 22,164,172, 76,144,
-252, 92, 40, 69, 11,244, 58, 25,106,149, 14,103,239, 92,145,149, 57, 91,178,194,106,188, 17,151,157, 93, 59,124,222, 60, 40,125,
-124, 0,139,197,222, 45, 8,192,222, 93, 72,147,147,113,252,208, 33, 40,100, 83,210,131,140,216,248,250,250, 34, 59, 59, 27, 38,
-147, 9,148, 82, 80, 74,237,134, 74,165, 82,161,112,188,148,171, 81, 28,239,126,253,250,117,104,221,186,245,197,151, 95,126,121,
- 87,253,250,245,175,219,202,186, 78,167,179,212,173, 91, 55,201,100, 50,229, 94,187,118,173,206,202,149, 43,219,201,178,236,241,
- 32,242,237, 24,157,115, 52, 72,102,179, 25, 5, 5, 5, 72, 75, 75,195,158, 61,123,112,240,224, 65,156, 59,119,174,229,145, 35,
- 71, 26,111,216,176,225,253, 6, 13, 26,180, 62,119,238,220, 45, 87, 12,150,109, 95,218,204, 22,189,115,119, 60, 54,254,241, 23,
-122,246,234, 68,114,242,178,177,105,203,223,160,148, 6,177,246,244,190,145, 7,171,148,103,218,187, 38,255,229,243,234,204, 84,
- 51,102,157, 56, 17,189,191, 87,175, 94, 59,106, 86,127,204, 11, 0,204, 38, 90, 69,167,244,211, 42, 20, 10, 21, 0,132,133,133,
- 69, 82, 74,191,192,157, 59,145,238,226,153,103,158,105, 19, 24, 24,216,100,235,214,173,167,227,227,227, 15, 22, 55, 87, 0, 80,
-167, 78,157,143,206,156, 57,243,148, 32, 8,196,161,241,167, 0,156, 26,172,254,253,251,215, 14, 13, 13,245,221,114,217, 27,217,
-202,154,144,185, 76, 80, 94, 13,201,167, 9,174, 43, 27,160, 90,181, 11,190,143, 61,246, 88,227,203,151, 47,159,118, 39,243,132,
-144,208,193,131, 7,255,254,221,119,223,213,233,222,189,187, 10,192, 93, 6,171, 94,189,122,253,118,238,220,217,127,204,152, 49,
-141, 9, 33,207, 82, 74, 93,158, 3,240,216,177, 99,135, 0, 84,234, 32,244,209,179,232,110, 0,117, 89,209,253,207, 68,175, 0,
-135, 49, 88, 0, 82,113,231, 89,202,142,223,109,115, 93,154, 29,214, 77,117,136, 90,153,139, 69,189,156,253,150,138, 74,188,201,
- 74, 81,202, 73,118,207,209,163, 71,155, 70, 70, 70, 94,181,153, 43, 91,125,180,125,208,235,245,102, 0,244,226,197,139,245, 37,
- 73, 58,232,194,255,253, 24, 29, 29,189,101,201,146, 37,159,134,133,133,153,250,245,235,199,205,158, 61,123,147, 45,138,181, 96,
-193, 2,218,179,103,207,205,151, 46, 93, 34,231,207,159,255, 8, 64,255,178, 4,141, 70,227,178, 55,222,120,227,217,253,251,247,
-107,204,102, 51, 50, 51, 51,139, 68,175,114,114,114, 96,181, 90,193,243, 60,150, 44, 89, 98,202,203,203, 91, 82,230,213,145,197,
-242,253, 39,159,124,242,204,234, 31,127,208,240,162, 25, 5,153, 25,144,179, 51,193,229,231, 65, 97, 49, 67, 45, 72, 8,170,173,
- 71, 78,138, 18, 95,110,219, 99, 20, 69,113, 89,153, 81, 49, 83,222,228,215, 71,141,252,109,251,174,221, 16,186,118,133,184,117,
-235,221, 87,122,129,129, 40,176, 88, 16, 53,103, 22, 37,198,204, 41, 15,162,160, 11,130,112, 97,228,200,145,129,163, 70,141,170,
-210,168, 81, 35, 88, 44, 22,136,162, 8, 74, 41, 36, 73,130,159,159, 31, 0, 32, 62, 62, 30, 49, 49, 49, 89, 60,207,151, 25,189,
-147, 36,105,239,245,235,215, 27,188,242,202, 43, 87,158,126,250,233, 0,139,197,162,200,200,200, 72, 46,188, 50, 86,132,132,132,
-104, 85, 42, 21, 73, 73, 73,201,188,125,251,118,128, 44,203, 7, 31, 68,222, 45, 22, 11,230,206,157,139,159, 46, 95,198, 75,143,
- 61,102, 55,155, 38,147,201, 30,193,218,182,109, 27,254,249,231, 31,172, 90,181, 42,125,224,192,129,222, 47,188,240,130,247,170,
- 85,171,222, 4,240, 81, 73,154, 51,102,204,192,159,215,174,161,143,147,177,130,148, 18, 36, 38, 37, 66, 20, 69,252,254,251,246,
- 36, 65, 33,248, 44,248,116,174,246,131,201,147, 9,107,118,239, 15,178, 44, 79,111, 63,127,195,155, 28,167,179, 0,248,234,196,
-137,227, 7, 1, 64,171,213,250,207,159, 63, 95, 5, 0,243, 62,157, 39, 80, 74, 5,171,213, 10,179,217,140, 89,179,102,105, 70,
-141, 26, 85,226,221, 70,191,254,250,107,230,204,153, 51,125, 95,125,245,213, 39,247,236,217,163, 38,132,108, 47,188, 16, 75, 47,
-140, 84, 85, 5,112,168,106,213,170,213,214,174, 93, 91,227,169,167,158,210,151,149,206,130,130,130,175,151, 45, 91, 22, 62,127,
-159, 39,182,228, 13, 64, 60, 29, 12,234, 75,225,171,204, 65,125,143, 27,232, 20, 20, 31,180,106,213,170,175, 0,184,124,151, 30,
- 33,164,222,192,129, 3,127,249,238,187,239, 34, 70,142, 28,153,120,240,224,193, 4, 66,136,179,178,156, 62,124,248,240, 27,203,
-151, 47,175, 33,203,242, 70, 66, 72, 63,119, 76, 22,131, 81, 9, 28,187, 71,235,222, 51, 74, 51, 88,111, 19, 66,234,207,155, 55,
-111,246,247,223,127,223,122,242,228,201,123,218,180,105,147, 97, 51, 88, 55,111,222,244,221,191,127,127,231,252,252,124,171, 36,
- 73,111, 58,155, 19,163,248,211,182, 41,165, 55, 8, 33, 11,219,183,111,255,252,138, 21, 43, 86,233,245,250,140, 29, 59,118,248,
- 26, 12,134,219,209,209,209, 94, 28,199,229, 92,190,124, 89,177, 99,199,142, 33, 0,150, 57,171,192,197, 53, 19, 19, 19, 79, 85,
-175, 94,253,139,247,223,127,127,236,148, 41, 83, 52,178, 44,195,104, 52, 34, 39, 39, 7, 5, 5, 5, 16, 4, 1, 60,207, 99,205,
-154, 53, 38,179,217,252, 67, 66, 66,194, 81, 23, 52,143, 68, 68, 68,124,247,217,188,207, 70,190, 53,226, 37, 21,151,157, 9,227,
-237, 52,192, 98,130, 90,193, 33, 52,178, 10,140, 25, 60,190,218,246,143, 57,213,104,252, 45, 62, 62,126,127, 89,154, 7,174,103,
-111,109, 83,219,127,247,172, 25,211,186, 76,252,245, 87, 64,146, 64, 94,122, 9,216,185, 19,104,212, 8,114, 82, 18, 10, 44, 22,
-124, 56,105, 2,120, 99,202,129, 35,215,115,215,151,165, 89, 25, 20,215,188,113,227, 70,107,171,213, 58,116,230,204,153,211,107,
-214,172, 41,140, 24, 49,194, 39, 34, 34, 2,178, 44, 67,169, 84, 34, 49, 49, 17, 71,143, 30,205,190,125,251,182,133, 82, 58, 53,
- 41, 41,233,231,178, 52, 37, 73, 26, 67, 8,169,255,222,123,239,205,154, 61,123,182,240,217,103,159, 29,122,242,201, 39,131, 5,
- 65, 80, 54,105,210,196,127,223,190,125,218, 13, 27, 54, 60,145,151,151, 7, 74,233, 88, 87,202, 82,101,231, 93,169, 84,166,158,
- 63,127,190,234,236,217,179,201,245,172, 44, 76,224,121,123, 68,203, 22,185,251,228,147, 79,224,233,233,137, 5, 11, 22,224,216,
-177, 99, 11,210,211,211,199, 45, 90,180,200,111,205,154, 53,131,108, 6,203, 81, 83,173, 86, 95, 63,125,250,116,232, 23, 95,124,
-193, 93,182, 88, 48,167, 48, 82,235,200,244, 57, 31,195, 98,182,128, 16, 30, 49,135,247,205,233,208,249,137,153, 85,124,124,180,
-178, 76,233,253, 60,238,255,101,205,147, 39, 79,238, 5,176,183,148,171,107,219,197, 28,210,210,210,144,150,150, 6,111,111,111,
-219,164,201, 78, 53,141, 70,227,233, 9, 19, 38,156, 88,186,116,233,147, 7, 14, 28, 24,184,119,239,222,167,119,237,218, 85, 16,
- 23, 23,103, 21, 69,145, 6, 5, 5, 41, 58,116,232,160,233,217,179,167, 78,173, 86,115, 31,126,248, 97,250,156, 57,115,252, 10,
- 13,152, 83, 77, 89,150,121, 89,150, 49,238,241,108,140,239,162,128,201,116,231,130, 50, 41, 41, 17,231,206,157,195,193,131, 23,
- 65, 8,225,220,220,159,159,173, 90,181,170,186, 74,165, 34,171, 87,175, 14, 93,189,122,245,235,101,237,191, 21, 43, 86,132,175,
- 94,189,250, 11, 66, 72, 47, 74,169,204,202, 18,211,100,184,105,176, 10, 27,150,243, 0,158, 33,132,180,251,224,131, 15,102,132,
-132,132,164, 75,146,164,252,243,207, 63,159,206,206,206,246,149, 36,105, 26,165,244, 31, 55, 67,129,223, 17, 66, 48,100,200,144,
- 73, 33, 33, 33,155,207,158, 61,219,101,224,192,129,107,255,252,243,207,174,146, 36, 93,191,122,245,234,100, 0, 75, 0,124,237,
-170,102, 92, 92,220,199,219,183,111, 39,135, 14, 29,122,123,226,196,137,234,128,128, 0,226,227,227, 3,163,209,136,248,248,120,
-250,227,143, 63,154,204,102,243, 82,111,111,239, 25,174,106,250,250,250, 78,217,126,224,128,234,244,185, 51,195,222,121,110,144,
- 38, 60, 56, 20,158, 92, 40,114,110,167,227,159, 3,137,248,226,239,253, 5,105,102,243, 90,142,227, 92,190,149, 62,228, 74, 90,
-191,237,235,190,223,176,111,207,158, 46,179,162, 62, 33,117, 95,125, 21,186,234,213,145, 85,187, 54,142,238,219,135,168, 57,179,
- 40,159,151,114,192,122,229, 86,239, 7, 85, 32, 10,159, 49,248, 83, 68, 68,196,218,203,151, 47,143,154, 60,121,242,196,230,205,
-155, 83,147,201,164,220,178,101, 75, 94,114,114,178, 44,203,242,167,130, 32, 44,141,139,139, 51,185,161,123, 30, 64,127, 66, 72,
-187, 87, 94,121,101,122,112,112,112,138,213,106, 85,140, 31, 63,190, 75, 70, 70, 70, 32,165,116,186,187,101,169,146,163, 87, 79,
- 76,154, 52,105, 55, 33,196,195,177, 59,180, 72,101, 81, 40,148,217,217,217, 68,150,101,177,160,160, 32,213, 22, 25, 45,169, 30,
- 89,173,214, 46,211,167, 79,223,109, 50,153,194, 75,250, 95,165, 70,139,127, 14, 30,194,208, 33,131, 37, 5,207,207,126, 97,200,
- 96,213,193,195, 71, 36, 74,229,141,172,121,122, 56,161,148,162,240, 98,128,150,178, 78, 60, 33,228,163,227,199,143,107, 70,143,
- 30,221,108,232,208,161,158, 93,187,118,213, 23,139,190,203,127,254,249,103,254,178,101,203,210,247,238,221, 27,253,202, 43,175,
-244,197,157,217,227,157,146,148,148,180,245,203, 47,191,244,238,212,169, 83, 45,219, 19, 6,108, 99,176, 18, 18, 18,112,253,250,
-245, 27,146, 36,109,118, 51, 59,239,188,240,194, 11,235,151, 47, 95, 30, 54,114,228,200,196, 53,107,214,108, 6,224,108, 76,173,
-126,192,128, 1,189,150, 47, 95, 30, 54,106,212,168,120, 0,239,177, 25,222, 25,140, 10, 24, 44,135,198,226, 32,128, 39, 8, 33,
-189, 9, 33,126, 5, 5, 5, 43, 40,165,155, 42,208, 64,125, 71, 8,217, 17, 31, 31, 63, 28, 64,240,226,197,139, 23, 3, 72, 0,
-112, 25, 64, 95,103,227, 21, 92, 48, 5, 51, 67, 66, 66, 54, 76,159, 62,189, 82,158, 69, 88,248, 72,157,119, 13, 6,195,175, 31,
-125,243,227, 4, 89,150,155,202,162,197, 23,188, 34,147,231,249, 83,162, 40,126, 18, 31, 31,239,150, 33, 88,119, 39,157,125, 90,
-135,123,245,152, 48,102,232, 28, 43,175, 13,203, 51, 89, 85, 58,149,194,172,164, 5,241,156, 49,107,250,145,184,156,135,226,196,
- 90,104,158,190,168, 85,171,214,143, 71,143, 30,125, 31,192,232,220,220,220,101, 26,141,230,179, 43, 87,174,228, 84,224,216, 31,
- 4,208,173,176, 44, 5,228,231,231,255, 82,145,178, 84, 89, 68, 71, 71, 95,139,140,140,172, 9, 64, 91,210, 58, 60,207, 47,218,
-186,117,107,255, 39,159,124,178,192,100, 50,205,123,242,201, 39, 21, 39, 78,156,160,148,210,221,206,214, 63,114,228, 72, 10,128,
- 82,239,236,106,214,174, 93,216,242, 21, 43, 14,142, 24, 62,220,243,171,133, 11,170, 28,139,142,145,126, 88,190, 60, 39,175,160,
- 96, 17,107,158, 30, 14,108,129, 42, 65, 16,160,211,233,224,229,229,133,212,212,212, 50,111,242,160,148, 94, 37,132, 12,248,224,
-131, 15,218,125,240,193, 7, 79, 7, 7, 7,215, 15, 15, 15, 15,225, 56,142, 75, 78, 78, 78,139,143,143,191, 97,177, 88,118, 3,
-216, 10, 64, 89,163, 70,141, 83, 0,214,148,164,119,238,220,185, 79,130,131,131,247,173, 95,191,254,105,141, 70, 83, 87,169, 84,
- 86,177, 88, 44, 92,126,126,126,134,217,108,190,104,177, 88,254, 74, 76, 76, 60,236,102,125,252, 31, 33,164,135, 66,161,248,253,
-187,239,190,171,147,156,156, 28,190,119,239,222,187, 38, 57,142,140,140,252,102,249,242,229, 97, 99,198,140,185,182,122,245,234,
-103, 89,247, 32,131,225, 66,219, 81,142,121,233,220,105,152, 30,169, 80,103, 68, 68,132,218,213,168, 13, 11, 29, 63,122,154,141,
- 26, 53,242, 9, 12, 12, 28,244,246,219,111,171,234,214,173,139,139, 23, 47,226,171,175,190, 50, 39, 37, 37,173, 59,115,230, 76,
-102,121,211,217,172, 93,187, 48,189, 70,243, 54, 64,122, 3,116, 83, 94, 65, 65,145,103, 17,178, 99,244, 96, 52,251,245,235,183,
- 65,173, 86, 87,231, 56,142, 80, 74,169,237,209, 73, 14,211,108,196,238,218,181,235,153, 71, 33,239,132,144,208, 86,173, 90,205,
-184,120,241,226,223,217,217,217,119, 13,114, 87,171,213,189,154, 55,111, 62,228,208,161, 67,211,139,223, 69,200,202, 18,211,100,
- 84, 32,130,197, 40, 18,213, 97,252, 71, 41, 52, 81,246, 27, 26,106,212,168,129, 94,189,122, 85, 88,183,208, 76,189, 7, 54,115,
-251, 67,197,198,141, 27,159,249,175,228,149, 82, 26,143, 82, 38, 41, 53,153, 76,155, 1,108,102,165,130,193,112, 29, 54, 91, 52,
-131,193, 96, 48, 24, 12, 70, 37, 67, 0, 52, 42,225,138,198,229,208, 31, 33,164, 81, 57,174,152,206, 48, 77,166,201, 52,153, 38,
-211,100,154, 76,243,191,165,233,160, 61,179,132,159, 18, 11,117,190,249, 87, 27, 44, 54, 6,139,105, 50, 77,166,201, 52,153, 38,
-211,100,154, 15, 90,179,152,254,200,127,187,193, 98, 93,132, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 60,
-220,184,116, 23,161, 74,165,170, 15,224, 69, 0,129,132,144, 91,148,210, 21,102,179,249,252,127,109,103,169, 84,170,250,132,144,
- 23, 41,165,129, 0,110, 1,120,176,251,129, 16, 50, 99,250,157,153,245,167, 77, 7,197,189,236,239,101, 48, 24, 12, 6,131, 81,
-113,131, 85, 61, 44,108, 32,225,240,153,104,149,125,124,124,124,184, 47,191,252,146,235,211,167, 15,254,252,243, 79,188,253,214,
- 91,175,135,132, 24,100,129, 87,100,130, 74,239,199,222, 72,252,205,149, 63, 27, 48, 96, 64,156, 40,138, 37, 62,191,139,231,249,
-212, 13, 27, 54, 68, 84, 52, 83,193,205, 7,199,137,162,165,196,255, 81, 40,132,212,164, 19,235, 92,250,159,176,176,224,129, 28,
-200,103, 86, 89,246,169, 82,165, 10,183,120,241, 98,251,126,120,243,205, 55, 95, 15, 13, 9,145, 5, 5,151, 73,101,188, 31,123,
-227,198,111,247,237,200, 57,152, 43, 0,152, 49, 29,100, 26, 33,120, 40, 77, 86, 97, 90,167, 77, 3, 5,152, 9,100, 48, 24, 12,
-198,127,216, 96, 17, 66, 23,174, 94,246,153, 79,122,122, 6,214,108,220,134,122,245,234,225,220,185,115,168, 87,175, 30, 58,180,
-106,194,117,111,219,148,227, 57, 84,157,186,120,229, 66, 0, 46, 25, 11, 81, 20,253,215,175, 95, 15, 66,136,125,194, 62,219,164,
-125, 57, 57, 57, 24, 59,118,172,127,101,100, 74, 20, 45,254,215,142,253, 14, 5, 79, 96,149, 40, 44, 86, 10,209, 42,195, 34, 81,
-100,231, 91,209,181,215, 11, 46,255, 15,161,100,225, 15,139,231,249,100,102,101,225,247, 45,219,139,236,135,174,237, 91,114,131,
-122,118,230,116, 90,101,213, 81, 19, 62,113,121, 63, 84, 6,142,230,170,136,201, 2, 30, 58, 3, 99, 75,235,140, 25, 32,192,157,
-105,177,167, 79, 7,165, 44,226,198, 96, 48, 24,140,255,154,193, 50,137,146, 79,160,175, 55,126,252,225, 7,140,159, 56, 11,117,
-235,214, 5,165, 20,132, 16, 76,158, 50, 19,159,207,154,136, 33, 61, 58, 66,180,202, 62, 37,105,148, 48, 99, 48, 98, 99, 99, 97,
- 52, 26,139,188, 26, 54,108,232, 82,130, 93,189,107, 65,193, 19,108,142,201,129, 69,148, 97,177, 22,190, 68, 25, 93, 26,121,186,
-165, 41, 74,178,143,143,183, 7,190, 91,246, 53, 62,152, 57,175,200,126,152, 48,121, 10,190,154,251, 17,222, 29,243, 18, 76,162,
-228, 83,158,116,186,195,163,164, 57,125, 58,200,140, 25,132,184,218,181,201,246, 39,211,100,154, 76,147,105, 62,218,154,143,164,
-193, 34,132,116, 2,176,167,112,167,217, 35, 35,162,185, 0, 13, 66,253,240,245,252,217,160,224, 32,131, 2, 50, 64,101, 17,213,
-171,234, 96,204,207,119,251, 15,101, 89,134,197, 98,129, 40,138,248,230,155,111,144,155,155, 11, 89,150, 81,175, 94, 61, 0, 64,
-100,100,164,163,104,124,116,116,116,221,178, 52,253, 27,245,187, 72, 64, 66, 29,151, 77,155,247, 61, 14,196, 92, 5,165,128, 90,
-171,195,179, 67, 71, 65,146, 41, 44,162,251,207, 39, 45,200,203, 71,160,135,128,207,231, 76, 1, 39, 40,193,129,128,227, 8, 56,
- 34,163,110, 72, 21,152,140,198,251,126,224,166, 77, 7, 45, 30,197,154, 54, 29, 20,211,254, 93, 5,240,161,238,218,100, 48, 24,
- 12,198, 61,167, 36, 15,242, 72, 24, 44, 0,123,156,101,202, 92,144,143,144, 42, 74, 84,243,240,134,213, 42,225,172, 37, 8, 57,
-249, 5,176, 88, 68, 92,183, 88,112,229, 68, 50,218,181,107,135,103,158,121, 38,215,108, 54, 67,169, 84,102,111,220,184, 49,184,
- 44,131, 37,138, 34, 44, 22, 11,242,242,242,176,106,213, 42, 40, 20, 10,251,131, 83,109,231, 89, 74, 41,218,183,111, 31,234,210,
-193, 1, 9,189,114,244, 55,120,106,120, 88,101, 10,171,149,194, 42, 1, 86,153, 34,223, 44, 99,192, 43, 31,193, 42,203,144,100,
- 25,102, 75,217,231,241, 34,134,205,183, 37,250, 77, 90, 3,192,195,254,187,151,154, 98,124,123, 14, 74,149, 26, 42, 37, 15,147,
- 49,255,254, 31, 57, 74,233, 52, 66,240,111, 27,228, 62,109, 26,149, 1, 66,238,116, 23, 58,152,172,135,176,107,147,193, 96, 48,
- 24,247,133, 61,143,146,177, 42,110,176,236, 46,146, 82,186,247,255, 13,150, 17, 86, 81,130,104,149, 96, 21,173,200,202, 53,226,
-211, 79, 63,133, 90,173, 6, 33,196,110,150,100, 89,230, 68, 81, 68,207,158, 61,125,202,250, 67, 73,146,236, 17, 44, 74, 41,120,
-158, 71,235,214,173,239, 90,239,240, 97,183, 30, 10, 15, 79, 13,143,234,221, 38,221,181,252,200,111,179, 65, 41,133, 36, 81, 88,
- 37, 10,179, 85,170,176, 97,107,214,105, 16, 76,102,241,206,112,109, 10, 20,228,231, 63,152,163, 71, 41,181, 27,147,127, 85,228,
-138,210,105,211, 64,103,204, 32,108,154, 16, 6,131,193, 96, 56,245, 32,143,148,193,194,157, 16,157,221, 69,154,140, 70,136,162,
- 21, 86,171, 4, 81,188, 99,140,180, 90, 45, 58,118,236,104, 59,191,219,223,183,109,219, 6,139,197, 82,230, 31,218, 6,181, 91,
- 44, 22,200,178, 12, 74, 41,214,172, 89, 3, 65, 16,236, 47,165, 82,233,118, 70,172, 18,197,164, 9,227,160, 20, 56, 8, 60, 7,
-165,130,131,160,224, 33, 81, 10, 74, 1, 89,166,144,100, 10,147,232, 90,160,164, 52,195, 6, 0, 22,147, 5,160, 20, 20, 20,198,
-188, 60, 86, 51, 24, 12, 6,131,193,168, 24, 69, 60,200,163, 98,176, 58, 19, 66,238,114, 30,102, 99, 94, 97,244, 74,130,104,181,
-218, 13,212,252,249,243,161, 80, 40,160, 82,169,160, 80, 40,236,134,200, 21,131, 85, 80, 80,128, 26, 53,106,192,108, 54,163, 94,
-189,122,160,148,226,185,231,158,187,107,189,163, 71,143,186,149, 17, 81,162,136,250,100,193, 93,203,255, 89, 55, 11,141,235, 87,
- 71,203,218,122, 20, 88,100,100,231, 91, 43,108,216, 0,160,192, 44, 66,198,157, 73, 7,140,121,249,172, 90, 48, 24, 12, 6,131,
- 81, 62,156,122,144, 71,194, 96, 21,134,228,238,114,141, 5,249,249,176,138, 86,187,201, 50,155,205,144,101, 25,111,189,245,214,
- 93, 66, 59,119,238,132,217,108, 46,253,207, 20,138,212,215, 94,123,173,200, 20, 9,148, 82,252,246,219,111, 80,171,213, 69,162,
- 88,132,184,103, 98, 69,137, 98,250, 71,239, 67,165,224, 33, 40,108,134,136,131, 44, 3,127,110,254, 27,127,110,254,219,190, 46,
-207, 11,169, 21, 49,108, 0, 96, 54, 91, 0,122, 39, 2,151,151,155,195,170,135,139, 16, 66, 8,155,158,129,193, 96, 48, 24, 14,
- 62,192,169, 7,121, 36, 12, 86, 73, 20, 24,243, 32, 58,140,193,178, 88, 44,176, 90,173,248,230,155,111,138,116,231, 9,130, 0,
-142,227,202,140, 96,173, 95,191,190,200,228,158,145,145,145,249,148, 82, 60,251,236,179,246,238,198,151, 95,126, 25, 35, 71,142,
-116,219, 96, 89, 37,138, 25,115,230,219,117,122,118,123, 28,253,122,116,130, 92,120, 42, 79, 57,179, 65, 87, 89,134, 13, 0,204,
-166, 59, 99,176, 40,128,252, 28,214, 69,232, 42,246,233, 25,166, 81,153,237, 13, 6,131,193, 96, 60,170,148,104,176, 4, 5,151,
-125,229,250, 77,175,170,122, 45,172,114, 1, 36,249,206,184, 41, 73,146, 48,114,228, 72,251,122,207, 63,255, 60, 94,124,241, 69,
-167, 6,203,149,167,109,203,178,140,127,254,249, 7,132, 16,112, 28,103,127,149, 18, 1,113,170,153,103,146,113, 96,237, 76,200,
-148, 66,166,128, 92,120, 67,130,201, 90,118,176,196,153,102, 89,134, 77,237,233, 3,158, 80, 16, 2, 92, 73,184, 5, 5,207,101,
-187,155,119,119,249,183,106, 78,159, 14, 58,189,216,148, 18,238, 14,112,103,251,147,105, 50, 77,166,201, 52, 31,109,205,255,140,
-193, 34,148,188,183,116,211,225,249,162, 36,123,217,150, 53,104,208, 0, 22,139, 5, 91,183,110,181, 27, 15,158,231,237, 93,122,
-174,140,193, 42, 70,124,199,142, 29, 75,155,138, 33,222, 21, 17, 10, 26,223,162,203,224,208,210,126,119, 55, 97,101, 25,182,239,
-246,158,253,255,157,200,113,217, 28, 33,239,177,226, 84,194,254,167,182,251, 45,139, 78,207,192, 96, 48, 24, 12,198,127,206, 96,
-197,197,199,175, 1,176,198,113, 89,207,158, 61, 83,250,245,235,167,181, 90,173, 48,153, 76,176, 88, 44, 48,155,205,176, 88, 44,
- 48,153, 76,208,104, 52,110,205,184,233,202, 36,162,174,144,122,102, 99,221,202,220, 41,174, 24,182,164,164,164,186,172,248,184,
-111,181,238, 60,143,144, 25, 45, 6,131,193, 96,252, 71, 13,150, 51,140, 70,163, 1,128, 34, 49, 49,241,174,223,110,222,188, 9,
- 0,214, 71, 97,167, 84,182, 97, 99,148,110,180,254,141, 51,208, 51, 24, 12, 6,131, 81,105, 6,107,207,158, 61,214, 71,197, 68,
- 49, 30, 34,163,197,204, 21,131,193, 96, 48, 30, 49,216, 76,218, 12, 6,131,193, 96, 48, 24,149, 12, 1,208,200,217, 15,238,220,
- 29, 64, 8,105,228,238, 31,151,165,207, 52,153, 38,211,100,154, 76,147,105, 50,205, 71, 79,179, 44,109, 74,233, 25, 66,200, 72,
- 74,233, 55,255,106,131,117, 47,231,124,100,183,176, 50, 77,166,201, 52,153, 38,211,100,154, 76,179, 28,250,255,122,131,197,186,
- 8, 25, 15,140,200, 81, 49, 90,182, 23, 24, 12, 6,131,241, 40,162,120, 24, 19, 21, 25, 25, 89,141, 82,218,156,227,184, 42,148,
-210, 29,209,209,209, 55,217,161, 42,215, 21,128,130, 82,106,125, 24, 53, 67,135,172,253, 93, 45,231, 62,101,232,119, 62,190,157,
- 82,211,112,221,186,103, 37,118,196, 24, 12, 6,131,193, 12, 86, 33,173, 90,181,138,144, 36,233, 5, 0, 67, 0,156,142,142,142,
-126,193, 93,141,182,109,219,106, 68, 81, 28, 13,160, 21, 56, 69,243,199,154,116, 12,106,222,186, 35, 50,242,101,236, 88,251, 89,
-108,231,206,157, 91,236,217,179,199,228,142,102,139, 22, 45,126,167,148,118, 47,193, 36,124,124,252,248,241, 57,238,232, 53,109,
-218,180, 27,207,243,239, 1,128, 36, 73,243, 79,158, 60,185,227, 97, 60,160,254,254,254,122, 47, 47,175,143,106,213,170,213,237,
-133, 23, 94,168,217,190,125,251,244,164,164,164, 99,162, 40,206, 77, 76, 76, 60, 93, 94, 77, 31, 31,159,143, 26, 54,108,248,212,
-203, 47,191, 92,189,125,251,246,233,137,137,137,199,172, 86,107,185, 52,219,188,123, 36,156,230,165,117, 95,191,244, 13,140,153,
-181, 38,236,180, 85,243, 2,128, 21,110, 27,241, 81,235,171,113, 10, 94,113,236,171,190, 9, 0, 16, 17, 17, 17, 46,138, 98, 39,
- 89,150, 27, 43, 20,138,211, 60,207,239,141,139,139,187, 94,145,253,249,111,209,100, 48, 24, 12,198, 35, 96,176, 26, 52,104,160,
- 87, 42,149,207,112, 28, 55,180,105,203,246,237,250, 62,251, 18, 17, 57, 45,102,143,123,222,237,200, 70,100,100,100, 43, 16,254,
-155, 23,223,142,170, 25, 86,163, 30,212, 58,111,228,153,129, 91, 89, 50, 84,249, 18, 66,155, 92,169,126,237,200,154,118, 0,118,
-185,163, 75, 41,237,190,118,203, 17, 36,103, 74, 32,228,206,104,126,142, 3,114, 11,100, 76, 30,209, 97, 50, 0,183, 12, 22,199,
-113,147, 94,153,187,183,149, 76,129, 31, 38,118, 84, 2,120,232, 12,150,193, 96,104,219,166, 77,155, 21,227,198,141,171,230,231,
-231, 7,189, 94, 15, 65, 16, 2, 19, 19, 19,251,188,249,230,155, 61,130,131,131, 39, 36, 38, 38, 46,117, 87,179,123,247,238,171,
-222,127,255,253, 0, 66, 8, 20, 10, 5,148, 74,101, 96, 98, 98, 98,159,247,222,123,207,109, 77, 66, 8,215,176,235,136, 17,158,
- 1, 29,193,113, 4,222,122, 13,178,226, 78, 15,138,136,120,107, 93, 92, 92,156,203, 38,186,217,168, 45, 83, 40,212, 31,200, 86,
- 66, 26, 61,191,108,235,237,125, 51,111,212,169, 83,135,140, 24, 49,226,182, 36, 73, 70, 81, 20,253,151, 47, 95,254,166,193, 96,
-160, 28,199,237, 49,153, 76,255,164,165,165,229,150,150,176, 25,133,143,243, 89,177,194,199,195,108,214,118,160,148,118,172, 91,
-183, 46,121,229,149, 87,210, 69, 81, 52, 22, 20, 20, 4,172, 88,177,194,117, 77, 7,170, 86,173,234,161, 82,169, 30,167,148,118,
-170, 80, 58, 29, 24,212,141,156, 92,183,131, 54, 45,239,239,197,178,239, 13, 64, 67, 41,189,233,194,186, 1, 0,116,148,210,216,
-251,173,121, 47, 8, 14, 14,206,162,148, 10,238,108,163, 84, 42,125,221, 41,175, 12, 6,131, 25,172,210, 26, 64,210,172, 89,179,
-246,132,144, 97, 17, 53,106, 61, 51,224,133, 81,218,136,218,141,144, 43,123, 33, 54,141, 34,102,247,207, 32,132,252,230,170, 94,
-173, 90,181, 84,222,222,222, 83,195, 30,107,241,246,200,119,167,115,103,110,105,176, 55, 86,130,130, 51,131, 7, 96,206, 79, 69,
-118,242, 69,220,186,180,199, 40, 73,210,145,242,100, 46, 49,195,138,125, 23,205,224,185, 59,230,138,231, 8, 20,229,159, 63,188,
- 26, 5,240,215, 41, 35, 8, 33, 65, 15,219,129, 12, 13, 13,125,170, 79,159, 62,235,198,142, 29,171,200,207,207, 71, 65, 65, 1,
- 40,165,208,104, 52, 48, 24, 12,248,237,183,223, 20, 67,134, 12,249, 52, 36, 36,228,100, 66, 66,194, 81, 87, 53,135, 15, 31,190,
-238,141, 55,222, 80, 92,188,120, 17, 22,139, 5, 90,173, 22, 26,141, 6,190,190,190, 88,190,124,185,226,213, 87, 95,117, 73,179,
- 94,189,122,173,213,106,245,172,150, 45, 91,182,168, 85,211,159, 79,243,125, 12, 0, 16, 86,163, 54, 60,113,171,227,181,228,128,
-212,230,205,155, 95,202,207,207,159,115,233,210,165, 63, 74,211,106,244,250, 22, 31, 5,200,184,165,227,218,113, 10,158, 39, 99,
- 62,255,167,231,234, 63,246,126,217, 49,178, 86, 6,128,188, 45, 91,182, 20,244,236,217,211,252,202, 43,175, 88, 46, 93,186,196,
-125,254,249,231, 77,118,237,218,213, 55, 36, 36,100,127, 66, 66,194,207,206, 52,103, 76, 7,217,146,252,199, 5,139,104, 13,169,
-210, 81, 52,245, 8, 57,183,248,213, 87, 71,102,135,132,132,136,133,154,166,158, 61,123,154, 71,141, 26,101,190,122,245, 42,153,
- 63,127,126,163,237,219,183,247, 14, 13, 13,221, 31,127,231,169, 7, 37,210,124,200,162,191, 3,154, 62,167,236,213,178,202,129,
-183,198,188,150,101, 48, 24,172,229, 77,103, 49,106, 87,240,119, 71,120, 0, 51, 9, 33, 63, 82, 74, 15,149,210, 14, 52, 5, 48,
- 8,192,231, 15, 72,179, 84,180, 90,109, 92, 65, 65,129, 63, 0,104, 52,154, 84,163,209, 24,225,194,197, 24, 89,180,104, 17,148,
- 74, 37, 56,142,131, 36, 73,144, 36, 9,178, 44,131, 82,106,127,183,221, 16, 52,113,226, 68,214,157,205, 96, 48, 42,207, 96, 53,
-111,222,124,125,207, 1, 47, 61,217,166,227,147,176, 42, 3,113, 49,133, 32, 62,150, 66,193, 91,193, 65, 70,236,177,141,148,231,
-249,159,139, 53, 92,103, 74,138,128,121,123,251,236,126,118,212,244,250, 53, 26, 62,142, 77,231, 44,144, 37, 51,210, 46,252,133,
-204,235, 71,145,119,235,130, 89, 52,229,158, 35,132, 28, 84,169, 84,159,159, 62,125, 58,191, 44, 77,103,220,121,134, 32, 5,161,
- 4,144, 1,128, 2, 28,113,214,192,150,169,201,113,220,233,141,187,207,133, 18, 65, 15, 0, 87, 93,104,180, 43,253,238,138,146,
- 52,131,131,131,123,190,249,230,155,191,244,234,213,139, 75, 75, 75, 3, 0,108,216,176, 1,199,143, 31, 71,104,104, 40,198,143,
- 31,143,176,176, 48,204,152, 49,131, 31, 62,124,120, 20,128, 46,174,104,126,244,226,139,191,244,122,229, 21,238,248,241,227,176,
- 90,173,216,177, 99, 7,206,156, 57,131,160,160, 32,140, 29, 59, 22, 97, 97, 97,248,240,195, 15,249,209,163, 71,151,170,217,162,
- 69,139,115, 17, 17, 17,161, 47,190,248, 34,215,167, 79, 31,146,146, 3,140,254,242,226,157, 2,168, 84, 99,240,160,129, 92,143,
- 79, 94,195,246,237,219,235,255,248,227,143, 43, 90,180,104, 97, 62,126,252,184,191,203,251,147, 16,234,225,229,151, 14, 32, 5,
- 0,188,188,188,244, 0,242, 1,228,215,169, 83, 71,177,100,201, 18,235,197,139, 23,175,118,239,222,253,105, 0, 63,151,164,105,
-181,202,213,190,159,252, 36, 94,249,120,187,122,218,180,169, 41, 28, 39,136, 0, 44, 0,224,227,227, 99,215,172, 89,179,166,226,
-203, 47,191, 20, 47, 94,188, 24, 91,168,185,166,180,116,138,130, 95,187,166, 29, 26, 90,246,196,167, 55,202, 90,125,229,224, 27,
-253,213,219, 27,214,240,205, 45,111, 58, 7,117, 35, 39,109,230,105, 80, 55,146, 95, 70,148, 43, 31,192,255,138, 71,178,138,107,
- 82, 74,111, 19, 66,190, 3,176,134, 16, 50,212,153, 33, 34,132,180, 5,176, 10,192, 51,148,210,212,178,202,167,163,166, 90,173,
- 86,154,205,102,159,226,198,199, 93, 77,135,180,228, 71, 71, 71, 35, 50, 50, 18,142,239,182, 11,139,194,117,252, 93,173, 71, 60,
-207,227,235,175,191, 6,199,113, 80, 42,149, 16, 4, 1, 74,165,242,174, 87,211,166, 77, 65, 41, 5, 33,196,229,250, 78, 8,225,
-195,194,194,198, 41, 20,138,225,102,179, 57, 88,173, 86, 39,139,162,184,202,207,207,239,211,232,232,104,241, 97,104, 67,152, 38,
-211,124, 24, 52,203,160, 37, 0,199, 58,109, 6,160, 42,252,156,134, 59, 29, 85,126,197,150, 59,174,103,123,183,181, 51,254,133,
-219, 81, 7,221, 84, 0,199, 42,213, 96, 17, 66, 40,165,148,216,222, 75,216,153,158, 9, 70, 31,228,198,250, 67,193,201, 80,240,
- 4, 10, 30, 0, 8,210, 19,206,163, 32, 55,237, 96,116,116,116,156, 43,127,170,209,104,102, 13, 26, 51,167,190,228,215, 18,155,
- 79,153, 33,102,199, 35, 97,239,103, 52, 63,245,242,119, 60,207,255, 40, 73,210,133,152,152, 24,177,162,153,147, 41, 32, 57, 26,
- 43, 25, 32, 40,247,180, 20,142, 15,140, 78,126, 88, 28,178,193, 96,232, 59, 97,194,132,159,155, 55,111, 78, 86,174, 92,137, 70,
-141, 26,225,187,239,190,163,151, 47, 95, 94, 72, 8, 89, 24, 23, 23,215, 37, 47, 47,239,199,159,127,254, 25,109,218,180,129,183,
-183,119,211,200,200, 72,161,180,134,221, 96, 48,244, 93,241,214, 91, 63, 55,110,223,158,204,239,214, 13,134,231,158,195, 47,123,
-247,210,216,216,216,133,132,144,133,241,241,241, 93, 10, 10, 10,126,252,246,219,111,209,162, 69,139, 50, 53,121,158, 15, 89,179,
-102, 13,175,211,233,192,243, 60,194, 53, 64,128,143, 18,159,174,189,136,212,172, 2,124,240,140, 1, 10,133, 2,221,186,117, 67,
-112,112,176, 98,204,152, 49,165,222,221,122,102, 73,207,204,102,163,182, 44, 24, 61,255,192, 4,142,112,180, 70,128, 98,183, 55,
-159,121, 30,240, 81, 0,240,246,247,247, 23, 1,192,108, 54,103,109,222,188,217, 26, 19, 19,227, 91,163, 70, 13, 63,119,246,235,
-137, 19, 39,243,171, 84,241, 75,175, 94,189,186, 2,128,183,159,159, 95,133, 52,135,245,108,162,202, 53,154,177,231,248,181, 14,
-175, 68,237,110, 95,221,224,121,170, 95, 75,223,157, 0,242,220,213,180,153,165, 65,221, 72,254,186,117, 7, 83, 65, 37,192,154,
- 35,194,146, 37, 66,202, 18, 97,201,182, 66,188, 45, 14, 26,187,160,209,186, 29, 84,231, 70,131,121,148, 16, 50, 20,192,170,226,
- 38,203,193, 8, 13,165,148,158,118, 87,211,108, 54,239,176, 25, 31,141, 70,227, 79,200, 29, 99,168,209,104,196,130,130,130, 30,
-238,104, 2, 64,116,116, 52,154, 55,111,238, 81,168, 73,109,239,133,134,213,109,108, 15,173,231,121, 30,205,155, 55, 71,159, 62,
-125, 80,167, 78, 29, 36, 36, 36, 96,207,158, 61,184,124,249,178, 61,194,229, 14,132, 16, 62, 34, 34, 98,215,147, 79, 62,217,224,
-237,183,223,214,132,133,133,225,226,197,139,161, 75,150, 44,121,231,159,127,254,233, 21, 25, 25,249,120,105,117,145,193,248, 47,
-224,138, 7, 1,224, 79, 8,217,228,208,182,244,182,125,159, 56,113,226,228,168,168,168,179,132,144, 77,142,203, 29,215,115,124,
- 47,252,207, 77,148,210,222,147, 38, 77,106, 56,119,238,220,143,109,235, 62,144, 8,150, 32, 8,207,159,217,186,240,192, 99, 22,
- 26, 20,208,176, 87, 97, 91, 70, 0, 80, 92, 63,185, 21,178, 44,175,114, 69,167, 89,179,102,143,135,214,109,243,154,161, 78, 27,
-108, 57,105, 66,206,149,109,184,121,232,171,120,217,106, 30,125,226,196,137,125,149,145,169,230,205,155, 63, 83,165,106, 16, 76,
- 22, 90,104,176,138,154,172, 71,133,176,176,176,129,115,230,204, 89, 94,179,102, 77,178,110,221, 58, 80, 74,241,235,175,191,210,
- 43, 87,174,140, 73, 78, 78, 94,105, 59, 31,215,169, 83,231, 43,158,231,181, 28,199, 33, 52, 52, 84,121,234,212, 41, 3,128,235,
- 37,105,254, 50, 97,194, 79, 77,235,212, 65,226,160, 65,232, 96,181,226,251, 21, 43,232,117, 89, 46,162,249,216, 99,143,125,165,
- 80, 40,180, 60,207, 35, 44, 44, 76,121,242,228,201, 18, 53, 1, 64, 20, 69,156, 58,117, 10, 10,133, 2,190,190,190,248,228,197,
- 16, 28,185,112, 27,141,107, 4,192,152,145,128,181, 59, 79, 32, 54, 54, 22, 62, 62, 62,174, 25,160,101, 61,103,133, 63,214,188,
-222,138, 85,107,147,212, 52,227, 76,122,122,186, 95,122,122, 58,188,188,188,178, 36, 73, 18, 63,253,244, 83,225,202,149, 43,222,
- 26,141, 6,106,181, 26,162, 40,186,229,172,173, 86, 43, 87,217,154, 85, 60, 53, 24,208,181,129,242,233,118,143,225,159,147,215,
- 35, 63,251, 45,182, 81,252,249,221, 35, 42,162, 9, 42, 1,135, 30,143,185,107,121,200,112,255,114, 94,149, 30, 42, 52, 89, 91,
- 8, 33,202,194,197, 41,133,239, 67, 75,235,234, 43, 67,211,254,221,100, 50, 57, 70,153,132,242,104, 70, 70, 70,218, 52,228, 98,
- 23,111,169,182,200,149, 70,163, 73,117, 85, 79,146, 36,168, 84, 42, 52,108,216, 16,239,189,247, 30, 46, 94,188,136,127,254,249,
- 7, 1, 1, 1,232,222,189, 59, 20, 10, 5,226,227,227,221, 54, 88,193,193,193,227,158,120,226,137,122,139, 22, 45,210,196,197,
-197,225,226,197,139,240,242,242,194,172, 89,179,180, 19, 39, 78,172,113,224,192,129, 73, 0,102,178, 83, 44,131,225,114,123,210,
-187,248,119, 66,200,166,168,168,168,222,206, 76,149, 19, 51, 87,100,249,220,185,115, 63,118,248,158, 81,153,105,229, 28, 29,100,
-105, 43,138,162,216,214,167,170,193,127,228, 11,221, 33,203,128, 85, 6,172, 18, 69,126,126, 30,110, 94,220,147,111,177, 88, 54,
-148,245,103, 13, 26, 52,208, 19, 94,185,244,229, 55,167,144, 45, 39, 76, 40,184, 29,135,228,131, 95,222, 80,112,180, 85, 37,155,
-171,229, 83, 62,253, 30,199,174,153, 11,187, 9,239, 68,178, 36,249,206,231, 71, 1,131,193, 80,167,119,239,222,203,107,212,168,
- 65,214,174, 93, 11,147,201,132,248,248,120, 26, 19, 19, 51, 42, 49, 49,113,165, 67, 3, 63,188, 71,143, 30, 90,158,231, 33,138,
- 34,174, 93,187,150,119,235,214,173,248,146, 52, 95,121,252,241,229,141, 67, 66,144,240,194, 11,144,178,178,112, 74,171,165,199,
- 40,189, 75,243,153,103,158,209, 42,149,119,206,191, 87,175, 94, 45, 81,179, 88,193,134,217,108, 70, 98, 98, 34, 78,199, 28, 65,
- 94,252, 33,252,178, 98, 25, 86,172, 88,129,216,216, 88, 40, 20, 10, 88,173,174,223, 39, 97,205, 79, 49,213, 52,104,115, 28,151,
-101,103,103,123,199,196,196,200, 23, 46, 92,240,182,157, 56, 1, 64,150,229,114, 91,235,226,154,246, 8,105, 57, 53,181,106, 1,
- 93, 90,212,224, 69,153, 42, 43,156, 78, 41,199,226,116,185,229,182, 88,129, 6,236, 16, 0,165,195,184,163,128,242,154,171, 98,
-198,231,174,174,181,242, 18, 29, 29,109,139, 88, 21,193,104, 52, 70, 80, 74,117,209,209,209,112,101,252,149,195,177,132, 74,165,
- 66,223,190,125,113,225,194, 5, 36, 38, 38,130,231,121,152, 76, 38,152, 76, 38, 52,111,222, 28, 74,165,210,237,244,171,213,234,
-231,223,126,251,109, 93,108,108, 44,210,211,211,193,113, 28,172, 86, 43, 36, 73,194,171,175,190,170,211,104, 52, 67,216, 41,147,
-193,112,238, 65, 8, 33, 35, 9, 33, 35,139, 27,164,138, 26, 52,103, 26,147, 38, 77,106, 8, 64,125, 79, 34, 88,182,240, 92, 73,
-166,197,167,170, 97,249,164,168,239, 20,235, 79,241,200, 72,190,132,130,148, 75, 8,109,222, 15, 41,151, 14,128, 74,150, 63,206,
-157, 59,151,231, 66, 99, 51,110,192,107,211,195,246,199,169, 97,180, 20, 32,245,159,207,100, 66,173, 35,143, 28,137,206,169, 44,
-115,229,227, 87,109,249, 71,159,124,175,248,227,172,128,219, 73,151,112,113,227, 4, 72,150,252,226, 7,109,155,155, 7,158, 68,
- 70, 70, 86,171, 29,164, 5,167, 84,227, 48, 33, 1,131, 6, 13,226,215,173, 91,247,192, 6,187, 38, 37, 37, 93, 50, 24, 12,179,
-205,102,243, 20,142,227,112,243,230, 77,122,242,228,201,145, 9, 9, 9,171,109,235,132,134,134, 62,213,170, 85,171,133, 19, 39,
- 78, 4, 33, 4,187,118,237, 66, 94, 94,222, 1, 74,169, 92,154,166,239,217,179, 83, 58,229,231, 99,131,159, 31, 93, 38, 73,119,
-105, 62,249,228,147, 11,223,125,247, 93, 16, 66,176,127,255,254, 82, 53, 29,137, 77,163,200, 51, 1, 17,126, 28,124,124,124,176,
-103,207, 30,251,120,151, 76,209, 19,146, 85, 5,131, 96, 44,247, 62,145,101,153,100,102,102,242, 70,163,145, 23, 69,145, 83, 40,
- 20,212,118, 18, 22, 69, 81,174, 44, 77, 73,146, 42,164, 89,236,194,165, 98,233, 20,179,156, 27, 41,115,106,101,116, 59,153, 11,
-223, 85, 21, 49, 87, 54,227, 99, 27,128,174, 86,171,237, 70,197,157, 40, 83, 9, 17,172,114,253,238,204, 96, 9,130,128,218,181,
-107,227,208,161, 67,240,242,242,130,135,135, 7,180, 90, 45,212,106, 53,188,188,188,160, 82,169,192,113,156, 91, 38,203, 98,177,
-132,132,132,132,224,127,255,251, 31, 52, 26,141,253,165, 82,169, 80,167, 78, 29,228,231,231, 27,216,169,149,193,112,238, 65,156,
-205,228, 94, 25,221,120,206, 76,214,220,185,115, 63,118,140,130, 85,170,193, 42,213,180, 84, 53, 44,159,248,241,119,138,117, 49,
- 28, 50,147, 47,226,250,214,201, 86,201,146,159, 42,203, 98, 80,198,213,127, 32,203,242, 74, 23, 51,213,161, 90,141,198, 56,112,
-194,130,130,139,191,193,156,121,237,203,232,232,232, 3,149,105,174, 38,207,253, 94,241,251, 41, 5,110, 39, 93,194,213,205, 19,
- 37,171, 57,239,181,152,152,152,181,229,213,109,221,186,117,173,182, 45,154,125, 61, 44,208,210,166,239,160, 26, 80,105,149,152,
-112, 85,241,196,185,131,113,251, 91,180,104, 49,234,248,241,227,231, 30,160,201,154, 91,173, 90, 53, 33, 52, 52,116, 66, 98, 98,
-226,171, 73, 73, 73,191, 56, 68,153,122, 14, 24, 48,224,151,209,163, 71,115, 94, 94, 94, 72, 79, 79,199,180,105,211,140, 60,207,
- 79,112, 69,115,167,159,223,132, 99,146,116,151,102,167,126,163,126,153,240,206, 75,156, 32, 8, 72, 75, 75,195,140, 25, 51,202,
-212,164,154, 32,242,220,231, 55,224,161, 21,160, 86,106, 16,127, 32, 15, 31, 63,115,167,171, 72,169, 84,226,120,118, 35,112, 94,
- 97,208, 42, 21,136, 73,200,128,232,121,142, 68,142,138, 17,162,151, 53, 47,211, 36, 16, 66,164,180,180, 52, 33, 54, 54, 86, 99,
- 54,155,185,136,136,136, 2,224, 78, 23, 95, 70, 70,134, 82,165, 82,129, 16, 98,177, 90,173,110,197, 46, 51, 50, 50, 20, 87,174,
- 92, 83,139,162, 88,162,166,197, 98,169,112, 60,180,162,233,132,152,229, 60,228,103, 73,171,168,193,138, 39,132,132,218, 62, 87,
- 70,121, 45, 40, 40,240,119,232, 26, 4,165,174,143, 15, 43, 33,130, 85,238,223,157,180, 77, 80,169, 84,184,114,229, 10,252,253,
-253, 97,181, 90,161,215,235,161,213,106,161,213,106, 97, 52, 26,161, 82,169,192,243,188,211, 65,238, 37,161, 82,169, 18, 46, 94,
-188, 88,219,199,199, 7,178, 44, 23, 49, 89,177,177,177,208,235,245, 73,236,212,202, 96,184, 21,240,216,228,104,180, 8, 33,155,
- 38, 78,156, 56,185,188,122, 19, 39, 78,156, 92,209,168, 88,169, 6,203, 54,168,172,248,224,178,230,205,155, 63,227,237, 23,180,
-252,131,217,223, 42,126, 62,206, 33, 43,249, 2,146,182,127,104,149, 44,249,195, 5, 65, 56,116,227,192,178, 85, 28,199, 25, 79,
-158, 60,249,143, 11, 59,133,139,108,243,120, 99, 94,233, 1, 74,141, 40, 72, 60, 2,133, 66,177,176, 50,205,213,196,168,239, 20,
-235, 78, 40,144,145,124, 17,215,255,154, 36, 73,150,252,114,155,171,206,157, 59, 43,114,115,115,199, 54,212, 75, 31,189, 23, 38,
- 42,131, 85, 50,206,127, 61, 1, 23,195,188,208,176,141, 22, 17,117,165, 38, 71,182,153, 14, 70, 70, 70,206, 55,153, 76,115,207,
-157, 59,103,121, 16,133,237,230,205,155,179, 66, 66, 66,254, 72, 74, 74,178,223,209, 97, 48, 24,250, 14, 29, 58,116, 85,167, 78,
-157,184,213,171, 87,163, 95,191,126,152, 58,117, 42, 77, 75, 75,123, 43, 41, 41,233,106,121, 53, 7,188,253,227,207,131,122,181,
- 37,131, 63,248, 28, 83, 94,235,130,239,191,156, 83,166,166,111,175,149, 71, 66, 13,189,248,199,124,141, 24, 51,184,253,157, 43,
-133, 95, 46,224,242,173, 59, 1, 79, 81, 86, 32, 11,129,248,122, 68, 19,112, 28,193,190,227,151,241,227,173, 70, 36, 49,110,207,
- 25,160,121,221,210,210, 41, 73, 18,249,233,167,159,188, 82, 82, 82,184, 58,117,234,220,110,210,164, 73,158, 74,165,146,141, 70,
-163,164,209,104,172,122,189, 94, 46, 40, 40, 80, 93,191,126,189, 74, 98, 98, 34,111,235,134,115,133,237,219,183, 7,213,173, 91,
- 63,189, 89,179,102, 37,106, 38, 37, 37,113,238,104, 58,163,162,233, 44, 49,130,101,169, 88, 4,139, 82, 90,151, 16,146, 95, 17,
- 19,116,175, 40,140,132, 1, 64, 94, 73, 83, 49,184, 19,193,178,141,171, 82,169, 84, 56,120,240, 32,158,126,250,105,200,178, 12,
-181, 90,109,159,150,228,232,209,163, 80, 42,149,224,121,222,173,180, 90, 44,150,213, 95,126,249,229,251,115,231,206,213,219,186,
- 33,117, 58, 29, 84, 42, 21,230,207,159,159,103, 52, 26,127, 97,167, 76, 6,139, 94, 57,247, 32,197, 72, 45, 22,189, 50, 59,124,
- 79,197,157,103, 43,247, 46,252, 12, 39,159,205, 78,150,165, 71, 69, 69,237,118,136, 92,165, 86,102,190, 74,140, 96, 53,107,214,
-236, 9,159,170,134,229,239,207,254, 86,177,226, 8,143,204,228,243, 72,219,253,145, 85, 22,141,195, 99, 98, 98,108,227,173,186,
-185,250, 71,145,145,145,181,194,235,182,214,165,228,200,160,178, 21,214,172,107, 41,199,143, 29, 73,169,104, 6,154, 53,107,246,
-132,143, 95,181,229,227,231,124,167, 88, 29,173, 64,102,210, 5, 36,109,255,176, 66,230,170,105,211,166,221,212, 10,238,251,183,
- 67, 68,223,222, 85,173,144, 40,176,242,166,128, 53, 39,142,252, 99, 33,178,169, 97, 91, 77,183, 70,237, 85,120, 98,136, 78,113,
-245,180,101,194,241, 29,120,163, 89,179,102,195, 79,156, 56,177,245, 65, 20,206,132,132, 4,187, 17, 10, 9, 9, 25, 48, 98,196,
-136,159, 58,119,238, 76,182,110,221, 10, 89,150, 49,111,222, 60,122,234,212,169,183, 29,163, 81,238,106, 14,120,251,199,159, 6,
-246,125,146,124,184, 78,196,237,124, 29, 62,152,254, 57, 53, 39,157, 46, 83,179, 65,168,178,193,215, 31, 13, 3, 0, 28, 62,119,
- 19, 59, 79,101, 32, 49, 45, 31,175,180, 2,206, 1, 80, 16, 17, 85,184,155,152,242,227,105, 52,137,240,192,179, 93, 30, 67,199,
- 22,143, 97,241, 79,127,133, 86,237,254,113,181,180,109,147, 75,156,164, 82,150,229,180,237,219,183,235,166, 76,153,146, 27, 20,
- 20,164,200,205,205,229, 28,199, 48, 41,149, 74, 4, 5, 5, 89, 51, 51, 51, 45,219,183,111,175, 46,203,242,237, 82, 43,131,130,
-187,249,202,199,219, 67, 84,156, 92,240,204, 51, 3,104,213,170, 85, 21, 70,163,209,169,102,122,122,186,101,215,174, 93, 53,100,
- 89, 78, 43,107, 95,242, 82, 78,218,252, 85,251,124, 6,117,107, 34, 84, 55,220, 61,136,223,221,116, 22, 53, 88,183, 69,132,190,
- 84, 21,230,219, 34,204,169, 86, 88,210, 69, 88, 82, 69, 88,243, 30,186,219, 57,202, 59, 0,189,140, 72,152,127,101, 69,176,148,
- 74, 37,226,227,227,177,115,231, 78,180,106,213, 10,158,158,158,200,203,203,195,161, 67,135,112,243,230, 77,123, 4,203, 29,110,
-220,184,177, 64, 16,132,158,111,190,249,102,221,209,163, 71,235,235,213,171,135,184,184, 56, 44, 88,176, 32,255,244,233,211,177,
-190,190,190, 81,236,244,202, 96,184,196,177,127, 91,130, 21,165, 92,213,125,208,246,217, 41,138,229,135, 21,200, 72, 60,139,172,
-253, 83,139,155, 43, 87, 66,121,246,167,109, 75,146,212,180, 97,179,182,184,122,203, 10,107,118, 28, 64,165, 19,229, 12, 15, 22,
-121,130, 55,199,113,239,183,123,118,138, 98,197, 49, 5,178,146,206, 35,117,247, 20,183,205,149, 19,205,137,187, 63,120,214, 23,
- 86, 43, 78,109,249, 5,159,199, 43,243,174, 25,201,132, 19, 39, 98,126,162,148,210,102,205,154, 13, 73,184, 44, 46,104,221, 67,
-227, 53,112,192,115, 24,240,140, 85,255,238,203,203,199, 3,216, 90,146,102, 37,133, 70, 75,213, 52, 24, 12,117,234,215,175,191,
-188,103,207,158,100,195,134, 13,200,201,201, 65, 70, 70, 6, 14, 31, 62,252, 70, 82, 82,210, 79,229,213, 12,106,208,103,249, 51,
-125,158, 36, 83,126,149,112,233,200, 90,120,152,110,192,148,124,196, 37,205, 51,241,150,147, 47,140,255,161,153, 90,163,133,164,
- 13,198,251,253, 12,168,231, 79, 96,204,255,255, 33,123, 45,171,252, 15,185,200,196, 63, 39,170,225,143,191,247,129,151,243,113,
- 35,165, 32, 33,109,231,255,155, 43,103,233, 76, 77, 77, 29,175, 84, 42, 59,142, 24, 49,226,185,199, 31,127,220,115,228,200,145,
- 41, 94, 94, 94,121, 42,149,138,247,245,245, 85, 81, 74, 85,127,255,253,183,225,230,205,155, 85, 0,172, 73, 77, 77,221, 87, 82,
- 58,167, 77, 7,197,244,190,245,206,159, 7, 57,118,204,240,248,240, 93,194,144,199, 31,127,220, 99,228,200,145,169,142,154,146,
- 36,169,254,254,251,239,224,155, 55,111,250, 0, 88,157,154,154,186,191,172,253,121,106, 77, 74,141,218,221, 19,166,126,117, 59,
-231,173,154, 33,254,124,255,110, 13,133, 42, 30,119,158,115,237,110, 58,129, 98,243, 96,189,253,121,227,210,202, 76, 73,243, 96,
- 61,136,242,105, 52, 26, 35,220,141,138,185,146,206,152,152,152,252,226,243, 97,149, 22,193, 42, 73, 83,165, 82, 65,161, 80, 32,
- 53, 53, 21,219,183,111, 47, 50, 23,150, 74,165,178, 79,227,224,142, 38,165, 84, 34,132,116,149, 36,105,220,187,239,190, 59, 60,
- 63, 63, 63, 88,167,211, 37,155,205,230, 85, 85,170, 84, 41,117, 30,172, 7,113,140,152, 38,211,124,144,154,143, 26,165,141,193,
-210,254, 19,125, 25,188, 58, 5, 57, 71, 62,117,219, 92, 57,227,230,237, 2, 36,104,172, 16,111, 95, 2,128,147,149, 20, 90,244,
-220, 31,115, 5,130, 38, 29, 89,135, 63,145,100,209, 88,161, 49, 87,133, 5, 71,132,213, 10,243,222,213,120,251,178, 38,157,112,
-124,171,152,152, 99,183,108,191,159, 56,113,226,151,102,205,154,237,218,182, 34,239,120,183,142,214,170,167, 99,255, 0,199,113,
-150, 7,125, 48, 11, 7,169,207,249,245,215, 95,167,228,229,229,225,246,237,219,244,232,209,163,163, 19, 19, 19, 87, 85, 84,243,
-243, 31, 6, 76,185,124, 41, 11,218,156, 35,212,116,125,227, 24,199,187, 10, 75, 35,115,243,176, 14, 13, 94,221,218,142,100,158,
-105,165,187,188,244,221, 63,210, 13, 62,134,215, 95, 39, 65, 65, 65,168, 82,165, 10,252,252,252,144,155,155,139,171,199,255,162,
-198,228,100,147,213, 35,242,107,115, 80,215,237,169, 59,251,254,227,194,177,167, 0,246, 70, 70, 70, 30,220,179,103,207,211, 7,
- 14, 28,232,219,181,107,215,148,118,237,218,229,198,196,196,132,199,198,198, 6, 0,248, 51, 32, 32, 96,107,153,115, 13, 81, 74,
-167,253,255, 93,105,123, 34, 35, 35, 15, 20,106,246,233,214,173, 91,106,155, 54,109,114, 99, 98, 98,194,227,226,226,252, 37, 73,
-250,163, 86,173, 90,219,246,236,217, 99,117,173,140, 78,147, 1, 76,111,252,212, 7,243, 46,100,234, 23, 92, 77,188, 61,184,241,
- 99,193, 4, 0,113, 59,157, 40, 54, 15, 86, 41,243, 92,149,245,187, 11, 68,223,131, 98, 90, 97,205,226,145,176,230,205,155, 71,
-216,204, 84,241,119, 55,234, 60,154, 52,105, 2,199, 59, 29, 57,142, 43,242,226,121, 30, 10,133,162, 60,109,148, 4, 96, 94,225,
-139,193, 96,252,215, 13,150, 66,161,248, 32, 47,250,139,153,148, 82,127, 0, 19, 99, 98, 98,182, 85,228,143,148, 74,229,129,152,
-191,191,205, 84, 5, 95,240, 41,136,223,151,199, 17,178,162, 50, 50, 64, 8, 25,159, 23,253,197, 76, 0,126,178, 44,127,116,226,
-196,137, 63, 43,170, 41, 73,210,252, 14, 11, 54, 2,208, 18, 73,146, 62, 59, 25, 29,115,171,248, 58, 39, 78,156, 72,107,218,180,
-233,107,239,189,178,194,254, 0,232,135,225,128,218, 6,169,215,168, 81, 99,194,141, 27, 55,138,220, 1, 88, 81, 77,109,181,150,
- 19,196,180, 19,163, 18, 19, 19,127,118,103,251,115,223, 61,125, 16,120,250, 32, 48, 97, 65,157, 58,117, 6, 77,158, 60,249,203,
-250,245,235,107,171, 86,173, 74,142, 28, 57, 66,175, 94,189,106,205,203,203,251,236,204,153, 51,179,203,117,198,190, 99, 74,254,
- 52, 24, 12, 59,183,111,223,254,204,223,127,255,221, 74,150,229,163,178, 44,207, 73, 74, 74, 50, 86, 84,115,219,182,109,207,108,
-221,186,181, 21,165,244, 16,165,244,143,196,196,196,130,242,104,158,254,123, 94, 62,128, 81, 13,159,248,112,234,137,188,196,101,
-188,210,179,241,181,107,215, 46, 84, 32,157,255,171,224,239,101,177,225, 30, 20,209, 10,107,186, 51,253,130,139, 6,136,190,243,
-206, 59,238,108,194,219,166, 40, 97, 48, 24,140,210, 26,151,123,246, 2,208,200,241,123,187,118,237, 60,154, 52,105,210,183, 81,
-163, 70,186,202,210,188, 23,233,124, 20, 52,131,131,131, 27, 61,204,154,117,235,214,125,167,117,235,214, 41, 77,155, 54,253, 26,
-128,130, 29,247,135, 79, 19,128,254, 30,104, 6,178, 99,196, 52,153, 38,211,116, 65,127,228,189,212,191, 31, 47,197,253, 52,115,
- 7, 14, 28,200, 5,240, 7,179,181,247, 30,199, 65,234, 15,163,230,133, 11, 23, 22, 2, 88,200,142,212, 67,125,241,149,119, 15,
- 52,111,177, 61,203, 96, 48,254, 11,112,108, 23, 48, 24, 12, 6,131,193, 96, 84, 46, 4, 64,163, 18,174, 52, 93,142, 86, 16, 66,
- 26,149,227, 74,246, 12,211,100,154, 76,147,105, 50, 77,166,201, 52,255, 91,154,101,105, 83, 74,207, 16, 66, 70, 58,155,201,253,
- 95,101,176,220,189,219,198, 45,113,118, 11, 43,211,100,154, 76,147,105, 50, 77,166,201, 52,221,215,255,215, 27, 44,214, 69,200,
- 96, 48, 24, 12, 6,131, 81,201, 40,216, 46, 96,184, 66,112,112,240,204, 54,109,218,140, 60,118,236,216, 23, 55,110,220, 40,215,
-236,211, 45, 91,182,108,162,211,233,166, 91,173,214, 72,171,213,170,214,106,181, 23,114,114,114,190, 62,126,252,248,154,242,166,
-171,101,203,150, 45,116, 58,221, 84,171,213,218,180, 80,243, 92,102,102,230,151, 39, 78,156,248,237, 97,210,100, 48, 24, 12, 6,
- 51, 88,118, 22,126, 72,170, 41, 77, 80,188, 62,159, 38, 0, 64, 68, 68, 68,184, 40,138,157,100, 89,110,172, 80, 40, 78,243, 60,
-191, 55, 46, 46,238,122, 69, 18,240,111,209,252,183, 64, 8, 9,212,233,116, 47, 18, 66,158,164,148,110,203,207,207, 95, 73, 41,
-173,208, 35,137, 2, 3, 3,253, 7, 13, 26,244,222, 23, 95,124,129, 17, 35, 70, 76,240,247,247, 95,156,154,154,234,214, 29,102,
- 29, 58,116,120, 93,171,213, 78,127,227,141, 55,181, 45, 90,180, 32, 58,157, 14,151, 46, 93,106,190, 96,193,252,133,157, 58,117,
-122,118,223,190,125, 3, 41,165,110, 61,222,229,241,199, 31,127, 87,171,213,126,248,206, 59,239,168,155, 53,107, 70,148, 74, 37,
- 78,158, 60,217, 98,209,162, 69, 75, 58,117,234,212,127,223,190,125, 47, 80, 55,251,192,139,107,106, 52, 26,156, 57,115,166,197,
-252,249,243,203,165, 25, 57, 42, 70, 80,234, 44, 10, 0,176,228, 43,173,209,203,154,139,174, 46, 99,205, 19,131,193, 96, 60,130,
- 6,107,201, 36, 50, 69, 5,124, 0, 37,200,140, 81,170,173,223,108,246,187, 81,167, 78, 29, 50, 98,196,136,219,146, 36, 25, 69,
- 81,244, 95,190,124,249,155, 6,131,129,114, 28,183,199,100, 50,253,147,150,150,150,235,202,159, 86,173, 90,213, 67,165, 82, 61,
- 78, 41,237, 88,167, 78, 29,242,234,171,175,222, 22, 69,209, 88, 80, 80, 16,176,106,213,170,183, 12, 6,131,236,178, 38, 33,100,
-198,116,144, 85,171,170,232, 11, 10, 52, 29, 40,165,157, 42, 43,157,255, 34, 83,165,210,104, 52,125, 4, 65,120,197,207,207,175,
-106,143, 30, 61, 78, 5, 6, 6,158,191,117,235, 86,221,191,254,250,107,139,151,151, 87,170, 40,138, 63, 20, 20, 20,252, 73, 41,
-117,123,198,121, 65, 16,194, 9, 33, 72, 76, 76,132, 32, 8,130, 74,165,138, 0,112,214,213,237, 91,183,110,221, 72,169, 84,206,
-252,250,251,213, 26, 43,239,137,116,171,140,244,108, 64, 89,181, 14,166, 71, 45,212,127, 54,231,163,246,109,219,182,125, 7,192,
- 2,119,162, 76, 90,173,246,195,181,107,215,106, 2, 2, 2, 32,203, 50,114,114,114, 80,175, 94, 61,204,158, 61, 91, 23, 21, 21,
-245, 68,235,214,173, 71, 3,248,186,188,154,148, 82, 88, 44, 22, 52,108,216, 16,243,230,205,211, 77,159, 62,221, 45,205,200,111,
- 98, 4,209,114,177,181, 37, 95,154, 0, 0, 68,224, 63,233, 60,195,247,184,104,185,216,162,172,101,145,223,224, 72,244, 72,102,
-178, 24,247, 23,131,193,208,182,122,245,234,191,220,184,113,227, 48,207,243, 47,197,197,197,153, 42,161,125, 10, 6, 16, 1,192,
- 7,119,110,172,202, 0,112,157,210, 59, 23,238,229,161,106,237, 46, 61,161,210, 13, 3,104, 99, 2, 0, 28,119,154,138,121, 43,
-211, 46,236,222, 82, 33, 77,181,254, 69, 80,169, 49, 1,100,112,252, 25, 34,229,253,152,114,110,247,223,172,100, 48, 42,205, 96,
-173,158, 68,124, 64, 49,110,228,115, 35, 57,158,231,201,178, 95,190,233,185,125,211,183, 95,214,111,214, 35, 3, 64,222,150, 45,
- 91, 10,122,246,236,105,126,229,149, 87, 44,151, 46, 93,226, 62,255,252,243, 38,187,118,237,234, 27, 18, 18,178, 63, 33, 33,161,
-196, 89,190,191,153,170,191, 36,137,249, 33, 83, 95,209,154,210, 85, 35, 23,141, 28,249,122,182,193, 96,176, 22,106,154,122,246,
-236,105, 30, 53,106,148,217, 65,179, 95, 72, 72,200,190,210, 52,103, 76, 7, 81,222,214,109,237,220,132, 40,171,213,121,238,224,
-171, 35,223,206, 54, 24, 12, 86,142,227,114,203,155,206,127, 19,158,158,158,159,234,245,250,222,205,155, 55,191,240,238,187,239,
-238,237,219,183,111, 42, 0, 44, 95,190, 60,228,147, 79, 62, 57, 13,224,224, 31,127,252,225,255,249,231,159, 63, 23, 19, 19, 51,
-203,211,211,115, 83, 78, 78,206,120, 23, 27, 70,174, 90,181,106,147,187,119,239, 62,225,133, 23, 94,128,167,167, 39,134, 15, 31,
-142,130,130,130, 3, 6,131, 97, 86,114,114,242,124, 87,162, 57,106,181,250,195, 49, 99,198,168,101,133, 39, 62,250,233, 10,110,
-231,222,241, 13, 58, 21,135, 55,186,169,241,236,179,131,116, 81, 81, 31, 79,116,199, 96,233,116,186,169,239,188,243,142, 58, 32,
- 32, 0, 0,144,155,155,139,220,220, 92,228,228,228,192,100, 50,161,111,223,190,186,165, 75,151, 78,117,199, 96, 57,106, 94,186,
-116, 9,102,179, 25, 70,163, 17, 5, 5, 5,240,244,244, 68,255,254,253,117, 95,126,249,165,203,154, 65, 55, 33, 92,183,200,159,
-191, 55,102,112, 85, 0,152,255,245,186,207, 1, 99, 39,234,194,178,160,155,120, 28, 0, 51, 88,165,151, 79, 30, 64, 95, 65, 16,
-250,214,170, 85,171,249,149, 43, 87, 78,137,162,248, 7,128,141,148, 82,177,130,218,157,131,130,130,166, 39, 39, 39, 47,165,148,
-174,249,175,236,211,154, 53,107,174,249,249,231,159,125,183,108,217,210,107,246,236,217, 3, 0,252, 92,129,125, 40, 0,104, 93,
-248,245, 82,161,177, 66,161,209,170, 67, 8,169, 14,224,176, 59, 23,125,254, 13, 58,235,101,104,127,106,215,185,123,187, 65,207,
-246,247,240,247,245, 70,158, 73,194,229,184,155,161,127,111,249,253,241,106,141,123, 29,150,164,252,151, 82,207,237,201,115, 87,
-179,235,211,125,219,117,125,162,155,135,183,183, 15,210,115, 68, 92,141, 75, 8,219,187,125, 99,251,192,198,189,254, 1,196, 87,
-111,157,254, 59,159,213, 58,134, 59,184, 52,200,157, 0,212,215, 71,151, 14,224, 38,128, 92, 47, 47, 47, 11,128,124, 0, 25,117,
-234,212,201, 90,178,100, 73,226,198,141, 27,119, 81, 74,159,112,220,174,248, 29, 6,178,100,170, 54,250,133,183,160, 86,202,202,
-201, 19,199,221, 54, 24, 12, 41,101,104,238, 44, 75, 19, 0,188,180,198,118,253, 59,251, 52, 14,229,150,140, 57,189,227,213, 86,
-183,147,163,243, 1, 41,207,203,195, 67, 44, 79, 58, 43,131,251,165,105, 54,155,251,249,248,248,100,221,190,125, 91, 47,138, 34,
-201, 54,138,194,197,132, 2,175, 27,198,160,106, 23, 19, 10,188,178,141,162, 32,138, 34, 73, 73, 73,209,107, 52,154, 44,147,201,
-212,207,213,116, 6, 5, 5, 77,141,138,138,154,244,195, 15, 63,112, 45, 91,182,132,167,167, 39,218,182,109,139,149, 43, 87, 42,
-166, 77,155, 54, 35, 40, 40,232, 3, 87,210, 73, 41,109, 25, 25, 25, 73,100, 0, 25,185, 86,236,142,138,196,129,121, 45,145,111,
-150,145,149,157, 11,142,227,160, 80, 40, 72,243,230,205,107,186,154,119,171,213,218,180, 89,179,102, 4, 0,114,114,114, 10,205,
-213,157, 87,110,110, 30,148, 74, 21,100, 89, 86, 54,107,214, 44,168, 60,154,102,179, 25, 17, 17, 17, 8, 15, 15, 71, 78, 78, 14,
-178,179,179,161, 84, 42,221,210, 52,235, 4, 66, 65, 3,180, 26,181,159, 86,163,246,163,160, 1, 0,224,202, 50,179, 78, 32, 15,
-178,124, 18, 66,170,242, 60,191,180, 86,173, 90, 49, 60,207,127, 75, 8, 9,172,136, 38, 33, 36,146, 16, 50, 67,167,211,109,174,
- 95,191,254,101,189, 94,255, 23, 33,100, 22, 33,164,117,121, 52, 9, 33, 42,157, 78,183,229,227,143, 63, 94,121,226,196,137,129,
- 59,119,238,140, 56,117,234,212, 51,159,126,250,233,114, 15, 15,143,191, 9, 33,218,138,212,205,234,213,171,127,125,244,232,209,
-200,246,237,219, 47, 33,132,168, 43,163,190, 19, 66,120, 66, 72, 19, 98,123,216,225, 67,210,134,216, 8, 9, 9,169,217,172, 89,
- 51, 63,158,231,241,248,227,143, 67,146,164,246, 21,212,108, 13,224, 22,165,244, 31, 74,105, 26,165, 84, 42,124,165, 83, 74, 15,
- 0, 72, 0,208,206, 29, 77, 25,218,159,222,121,119,252,147,239,191,253,154, 71,204,117, 9,223,254,157,140,181,255,164, 34, 49,
- 71,141, 39,251,189,226,213,185,199, 11,221,120, 94,247,147,187,154,147, 39, 77,122,242,213,225, 67, 61,206, 36,113, 88,119, 32,
- 13,255, 92,200, 70, 62,169,130,206,253, 70,250,212,111,217,227,105, 16,229,178,135,225, 24, 61,234,154,255,137, 8,214,243, 81,
- 52,115,201, 36,178, 96,233,154,111, 38,112,132, 80,189,111,163,221, 70, 26,114,190,112,125,111,127,127,127,177,240, 36,148,181,
-121,243,102,107, 76, 76,140,111,141, 26, 53,252, 92, 63, 50, 32,167, 78,157, 52, 86, 13,168,126,171,122,245,234,149,162,217,173,
- 93, 23, 85,129,201,136, 83, 23,207,180,255,243,155,142,237,170, 4,212, 59, 21, 80,247,181, 93,144,218,229,153,173,214,204,114,
-165,243, 95, 0,207,243,198, 95,127,253,245,219,237,219,183, 7,125, 52,117,230,147, 51,191,221, 27,224,213,240,185, 42,162,236,
-229,177,115,225,137,220,204, 51,171, 50,110, 95,220,154, 18,217,180,225,174,254,253,251, 39,127,246,217,103,111,151,165, 25, 18,
- 18,162, 81, 40, 20,143,245,234,213,235,189,151, 94,122, 9,113,113,113,120,255,253,247,141, 39, 79,158,188,221,162, 69, 11,223,
-121,243,230,105, 71,142, 28,137, 67,135, 14,125, 88,189,122,245, 63, 68, 81,140, 79, 72, 72, 40,241,249,124,146, 36,169, 53, 26,
- 13,140,133, 49, 5,139,149, 2,144,237,145, 39,142,102, 66,161, 80, 64,150,229,218,132,144,107,174, 68,197,172, 86,171, 90,163,
-209, 32, 47, 47, 15,185,185,185, 72, 76,205,197,245, 91,121,200,201, 51,193,104, 20,145,159, 39, 66,208,249,193,106,189, 85,143,
- 16,114,211, 29, 77, 73,146, 96, 52, 26,145,151,151, 7,163,209, 8,163,209, 8, 89,150,145,157,157, 13, 65, 16,168,217,108,174,
- 3, 32,185,204, 99,163,210, 90, 1,110,222,210,229, 27, 63, 44,188,158,153,231,129, 2, 57,221,133,101,119,182,125, 96,145, 33,
-117,213,170, 85,183,254,250,235,175,117,107,215,174,141,216,216,216, 58,131, 6, 13,106, 65, 8,105, 71, 41,205,119, 83, 75,199,
-113,220,172,151, 95,126,121,228,243,207, 63, 79, 30,123,236, 49, 40, 20, 10, 88,173,214,224, 43, 87,174,116, 92,187,118,237, 56,
-133, 66,241,163, 36, 73, 19, 93,157, 57,158, 16,194,169,213,234,159,150, 45, 91,214,161,117,235,214,248,233,167,159,112,228,200,
- 17,185, 85,171, 86,220,139, 47,190,136,240,240,240, 86, 47,189,244,210,207,132,144,129,133, 15, 90,118, 55,255, 97, 67,135, 14,
- 13,225,121, 30,109,219,182, 85, 30, 56,112,160, 41,128,195, 21,220,167,250,224,224,224,191,187,116,233,210,100,199,142, 29, 39,
- 9, 33,221,221,153, 41,223, 96, 48,244, 14, 12, 12,156,237,233,233, 89,197,213,109,114,115,115,243, 83, 82, 82, 38, 39, 36, 36,
-172,119,113,147,214,141, 27, 55,134,213,106,133,183,183, 55,130,130,130,218,134,132,132,188,237,229,229,213, 55, 39, 39,103, 98,
-124,124,252,113, 55,242,107, 0,192, 81, 74,175, 20,126, 15, 7,240, 88,225,207,255,163,148,198, 81, 74, 99, 9, 33, 65,132,144,
- 16, 87,186, 11,171,214,238,210,179,125,215,158,237, 30,111,221,136,139,250, 53, 14,146, 44, 67, 1, 9, 10, 94, 70,154, 36,128,
- 16,130,176, 58, 45,249,192, 51,199, 91, 85,173,215,173,103,218,133, 29, 91, 92,209,236,209,167,127,251, 58,143,213,225,230,111,
-184,129,204,196, 51,210,173, 11,187,210, 9,199,161,122,211, 39,253, 34,234, 52,227,107, 53,235, 42,220,140, 59,211,201,175, 78,
-199, 46,233,151,246,237,102,182,129,225,182,193, 34,132, 80, 74,169,253,202,234,245, 40, 58,171,113,189,192,122,107,126,254, 49,
- 41, 79,244, 61,147,158,158,238,151,158,158, 14, 47, 47,175, 44, 73,146,196, 79, 63,253, 84,184,114,229,138,183, 70,163,129, 90,
-173,134, 40,138,110, 13, 38,150,101,153, 84,182,166, 94,231,129,246,145,237,148, 45, 26, 69,226,220,149,243,145, 49,187,199, 54,
- 58,116, 34,251,149,203,151,175,150, 91,243,223,194,147, 79, 62,153,252, 88,100,247,205,139,119,137,227, 23,190,217, 82, 71,101,
-137, 18,142,215,191,245,133, 76, 90,213, 15,249,222, 87,153,149,201,243,124,153, 58, 97, 97, 97,211,187,116,233,242,142, 66,161,
- 16, 94,123,237, 53, 0,192,216,177, 99,115,142, 29, 59,214,248,214,173, 91,169,161,161,161, 65,239,189,247,222,169, 95,127,253,
- 85,247,202, 43,175, 40,140, 70,227, 9, 65, 16,104, 80, 80, 80, 84,114,114,242, 28,103,154, 74,165,242,244,249,243,231, 59,120,
- 5, 55, 66, 85, 79, 14,221, 63,140, 1, 0,120,104, 40, 50,210,110,226,234,141,211, 8, 15, 15,215,134,133,133,253, 18, 20, 20,
- 36,183,105,211,230,179,144,144,144,168,117,235,214,149,120,114,212,106,181,231, 78,158, 60,217,162,126,253,250,200,205,205, 69,
-124, 74, 30,126, 56, 68,144, 95,160, 5,160, 5, 7, 15,120, 84, 9, 86, 11,212,184,166,117,235,214, 92,219,182,109,231, 6, 7,
- 7, 47, 40, 75,243,252,249,243, 45, 26, 54,108, 8, 81, 20, 17, 29, 29,141,188,188, 60,152,205,102,100,100,100, 32, 54, 54, 22,
- 53,107,214,212,200,178,188,177, 87,175, 94, 82,122,122,250,244,163, 71,143, 46, 42,201,188,109,125,187,150,165,211,244, 61,223,
-152,141, 57,191, 1,128,159, 95, 72,198,166,233,205,205,157,166,231,150,185,108,235,219,181, 44,120,235,129, 21,213, 97, 31,126,
-248, 97, 93, 95, 95, 95,140, 30, 61, 26, 51,102,204,192,212,169, 83,107,141, 30, 61,122, 4,128,197,110,156,100,181,213,170, 85,
-219,255,197, 23, 95,212,105,223,190, 61,182,108,217,130,213,171, 87,227,218,181,107,214,234,213,171, 43, 90,183,110,141,105,211,
-166,161,123,247,238, 47,191,245,214, 91, 29, 10, 13,156, 43,166,227,197,169, 83,167,246,238,208,161, 3, 94,126,249,101,211,238,
-221,187, 95, 4,176,115,199,142, 29,157,246,237,219,183,106,229,202,149,218, 57,115,230, 60, 57,110,220,184,215, 0, 44, 45, 71,
-254,251,116,236,216, 17, 0,208,161, 67, 7,124,250,233,167,221, 42, 98,176, 8, 33, 42, 95, 95,223,223, 87,172, 88,209,164, 78,
-157, 58, 24, 54,108, 88,211,193,131, 7,255, 78, 8,233, 67, 41, 53,187,162, 81,173, 90,181, 89,223,124,243, 77, 77,173, 86,235,
-242,255,154,205,230, 42,163, 70,141,154, 9, 96,189,139,109,114,155, 70,141, 26, 97,207,158, 61,232,214,173, 27, 26, 54,108, 88,
-115,212,168, 81, 81,221,187,119,199,187,239,190,187,195, 96, 48,212, 76, 74, 74, 74,119,241,239,195, 0, 92, 46,204,127, 40,128,
-154, 0, 14, 21,254,214,146, 16, 2, 74,105, 92,225, 58,117, 10,163, 89,165,163,209, 15,235,219,167,151,199,239, 7, 83, 32,201,
- 50,234, 5,107, 80, 63,204, 11,113, 41, 5,184,158,152, 14,129, 88,224,169, 85,163,113,187, 94, 62,183,111,197, 13, 3, 80,246,
-120, 44,149,110,216, 51,125,123,233,215, 31, 74, 65,102,226, 89, 26,119,108,237, 94,201,100,124, 3, 0,206,239, 95,185, 40,168,
-138,166,235, 99, 77, 35,249,252,199,251,249,236,217,112,107, 24, 0,102,176,238,221,133, 93, 17, 15,242,200, 70,176,108,220,206,
- 81,152,188, 3, 26,231,228, 37, 38,218,151,101,103,103,123, 95,190,124, 57,229,194,133, 11,222,130, 32, 64,146, 36, 91,229,148,
-203,155,136,202,214, 84, 41, 85,104, 82,167, 49, 31,125,250,184,242,194,133, 11,222, 60,175,164,149,145,206,135,157, 51, 73, 82,
-168, 40,243,122,141, 82, 97, 63,180, 50, 81,234,179, 73,181, 80, 95,100,101,150,181,125,100,100,164,208,181,107,215,119,190,255,
-254,123, 33, 57, 57, 25, 62, 62, 62, 16, 69, 17, 49, 49, 49,137,183,110,221, 74, 5,128,248,248,248,228,144,144,144,100, 73,146,
-106,213,171, 87, 15,163, 70,141, 66,221,186,117,201,123,239,189, 55,142, 16, 18,229,236, 78,192,236,236,236,175,230,207,159,223,
-236,255,216, 59,239,248, 40,138, 62,140, 63,179,123,253, 46,157,244, 66, 73, 2, 1, 66,104, 33, 1, 66,111,210, 5, 20,164,163,
- 40, 69,165,136,160,244, 34, 82,165, 23, 65, 16,164,131, 34,189,247,222, 9, 61,212,132,244,222,235, 93,174,236,206,251, 71, 18,
-222,128,129, 92, 2,190,250,234,124,225, 62,185,219,219,125,110,118,103,118,246,217,223,148,253,110,206, 98,117,255,134, 4,185,
-121,122,228,228,228, 32, 46,226, 41, 20, 38,138,217,179,103, 67,169, 84, 2, 0,159,154,154,202,207,159, 63,111,252,157, 59,119,
-218, 0,104,241,186,180,102,100,100,172, 92,186,116,233,170, 31,126,248, 65,173,213,106,161,213,233,144,173,149,227,218,226,192,
-130, 91,241,175,175, 99,222,252, 31,224, 87, 73,163,138,141,141,197,244,233,211,199, 61,127,254,188, 49,128,238,111,210, 92,176,
- 96,193,170, 69,139, 22,169, 45, 44, 44, 64, 41,133, 40,138,136,142,142, 6, 0,124,255,253, 44, 20, 94,224,248,248,248,120,126,
-206,156,217,179, 20, 10, 69,107, 0, 93, 95, 19, 66,167, 0,242, 9, 65,130,155,155,167,151, 66,193, 77,118,115,203,191,124,118,
-122,204,118, 66,144, 80,176, 14,168,235, 90,215,222, 81,155,228, 65,122, 61, 86,198,199,135, 63,163, 20, 20,211,255,186,251, 0,
-123,123,251,207,187,117,235,134,121,243,230,225,192,129, 3, 19,236,236,236,230,125,247,221,119,112,113,113, 25, 70, 8, 89, 89,
-134, 81,148,179,151, 44, 89,226, 83,163, 70, 13, 12, 26, 52, 72,127,242,228,201, 25, 0, 14, 0,136,186,112,225,130,199,198,141,
- 27, 59,253,246,219,111, 51,151, 46, 93,170, 92,177, 98,133,215,135, 31,126,184, 0,192,231,165,137, 58, 57, 57,141,236,219,183,
- 47, 22, 46, 92,136, 51,103,206,244,163,148, 30, 43,252,234, 56, 33,164,231,156, 57,115, 14, 79,153, 50, 5, 75,150, 44,249,178,
-172, 6,139, 16,162,169, 81,163,198,132, 14, 29, 58,224,194,133, 11,104,214,172, 25,130,130,130, 70, 18, 66, 86, 81, 74, 83,203,
-113,209,224, 44, 45, 45, 55,109,220,184,177, 73,229,202,149, 49,107,214, 44,124,243,205, 55, 88,191,126,125,147, 1, 3, 6,108,
- 34,132,244, 53,103,244,172,149,149,149,133, 74,165,194,188,121,243,104, 84, 84, 84,169,231,178,139,139,139,205,212,169, 83,137,
-149,149,149,181, 25,105,228,221,220,220,172,156,157,157,155, 56, 59, 59, 99,217,178,101,112,116,116,196,215, 95,127,141, 10, 21,
- 42, 32, 55, 55, 23, 61,122,244,144, 94,189,122,181, 23,128, 85,102,238,186, 29,128,162,136, 87,117, 0, 87, 40,165, 57,133,191,
-119, 29, 5, 77,131, 17, 40,232,151,101, 86, 84,142,163,212,215,214,198, 26,113,247, 18, 33,129, 9, 53, 42, 90,226,102,104, 46,
- 12, 2,133, 74, 99,129,220,236, 12,212,245,118, 64, 86,158, 59, 64, 69, 95,115, 52,101, 60,169, 39, 87,168,144,148,149,137,132,
-135,167,210,140,162, 97,100, 70,216,249, 24, 0,176,243,110, 57,242,254,245, 35, 23,123,116,108,230,144,148, 94, 17,148, 10, 13,
-152, 13, 98,148,133, 50, 77, 52, 42,138, 34, 73, 75, 75,147,104,181, 90,222,104, 52,114,197,221,166,209,104, 44,151,113,249, 51,
- 52,139,243,103,104,254, 93,169,234,200,197,243, 60, 94,106,170, 35,160, 58, 11,146, 18,111,206,246,193,193,193,198,243,231,207,
-111,155, 56,113, 34, 22, 47, 94,140,176,176, 48, 72,165, 82,212,168, 81,195,217,193,193, 65, 3, 0,158,158,158, 86,126,126,126,
-142, 60,207, 35, 52, 52, 20,219,183,111,199,140, 25, 51,104,112,112,240,166,215, 93, 40,110,221,186,117, 48, 63, 63,255,240, 15,
-179,167,230,229,167, 60,129, 90, 72, 6,205, 10,135,154,215,226,147,161, 35,241, 60, 89,192,237,240,108,220, 14,207, 70, 92,174,
- 2, 95,126, 61,153,171, 82,165, 74,253,192,192,192, 79, 95,151,214,219,183,111,239,202,203,203, 59, 53,115,230,204,188,231,207,
-159, 67,171,213, 2, 0, 12, 38, 17, 6,211,203,201,112,115,115,195,188,121,243, 52, 26,141, 38,200,223,223,191,239,155, 52,115,
-115,115, 79, 77,155, 54, 45, 47, 52, 52, 20,153,153,153, 72, 72, 72, 0, 33, 4,159,125, 49, 22,207,147,197, 23,233, 76, 53, 88,
-226,171,111,167,115, 30, 30, 30, 45,234,213,171,247,193,155,142,171,155,155,187, 87,141, 26, 94, 91,174, 94,189,218,223,203,203,
-107,104,145,177,162, 20, 20, 0, 42, 85,170,244, 89,112,112,240,192,186,117,107,108,117,113,113,173,246, 23,223, 69, 54,239,221,
-187,119, 53, 81, 20,177,115,231,206, 7,148,210, 21,123,247,238, 13,206,207,207, 71,223,190,125, 43, 3,104,103,166,142,127,191,
-126,253,134, 54,107,214, 12,163, 71,143, 54,156, 60,121,178, 9,165,116, 57,165, 52,146, 22, 16, 69, 41, 93,117,246,236,217, 70,
- 35, 71,142,204, 15, 12, 12,196,199, 31,127, 60,144, 16,210,164, 20,221, 70,125,251,246,245, 17, 69, 17,219,183,111,191, 95,204,
- 92, 21,153,218,115, 59,119,238,188,174,215,235,209,191,127,255, 42,132,144, 22,101,216,119,153, 82,169,220, 58,107,214, 44,235,
-216,216, 88, 12, 28, 56, 48,255,241,227,199,152, 62,125,186,202,218,218,122, 15, 33, 68, 83,214,227,169, 84, 42, 87,174, 90,181,
-170, 75,237,218,181,241,249,231,159,235, 87,173, 90, 53,238,139, 47,190,208,251,251,251,227,199, 31,127,236, 34,151,203, 87,150,
- 69, 47, 33, 33, 33,243,236,217,179,238,165,189, 18, 19, 19,205,154,154,165,114,229,202,214,181,106,213,186, 30, 16, 16, 16, 93,
-167, 78, 29, 79, 0,120,240,224, 65,202,206,157, 59,105,133, 10, 21,112,244,232, 81,172, 93,187, 22, 77,155, 54,133,165,165,101,
-207, 50, 36,149, 22,190, 80,236,239,171,223,191,186, 94,169,154,153,121, 38, 72, 56, 14, 82,158, 34, 50, 81, 11,131, 64, 33,147,
-114,144,242,128,132,163,168, 96, 41,133, 84,202, 3,132,152,165,201, 17,130,244, 92, 35, 36, 60,129, 84, 46, 37,188, 32, 42,139,
-190,227,165,162, 82, 46, 87, 18, 71,107, 25,228, 18, 2,142,128,193,120,119, 17,172,194, 74, 71, 72, 73, 73,145,134,135,135, 43,
-245,122, 61, 87,185,114,101, 29, 0,152, 76, 38, 46, 61, 61, 93, 38,151,203, 65, 8, 49,152, 76,166, 50,221,114,167,165,165, 75,
- 35,162,158,190, 83,205,146, 48,153, 76, 92, 94, 94,186,252, 93,106,254, 29,121,252,248,177,197,179,240, 56,141, 19, 95, 51,120,
-228,138,224,134, 20,144, 18, 74,141, 10,237,227,171, 41, 73,119,100,176, 86,168,221,221,221, 75,237, 63,243,252,249,243, 47, 93,
- 93, 93,231, 83, 74,107, 80, 74,119, 45, 94,188,152, 44, 95,190,220,230,139, 47,190,120,224,234,234, 26,231,227,227, 83,113,241,
-226,197,150, 0,176,101,203, 22,241,200,145, 35, 93, 21, 10,197,227,136,136,136,196, 55,233,158, 59,119,238,147,192,192,192, 79,
- 87,175, 94, 61,211,100, 50, 41, 28, 28, 28, 20,155, 55,111, 70,108,134, 30, 83, 54,255,119,100,161, 70,193, 99,116,123, 13, 90,
-182,108,205, 69, 69, 69,141, 3,176,254,117,154,231,207,159,239,215,176, 97,195,225, 63,254,248,227, 52, 88, 84, 82, 40,170, 15,
-150,181,158, 88,208,252,232, 98,167,120, 81, 33,102,102,102, 34, 61, 61, 29, 61,122,244, 80,111,221,186,245,115, 0,219, 75,211,
- 92,177, 98,197, 52, 65, 16,100, 14, 14, 14,138,109,219,182, 33, 60, 69,143, 9, 27, 67,145,173, 43, 72,167,133, 66,130,145,109,
- 21,104,221,186, 53, 31, 23, 23, 55, 30,192,238,146,244,220,221,221,189,107,212,168,177,101,219,182,109,213,151, 46, 93,154,254,
-244,233,211, 60, 23, 23,151, 41,175,172,166,159, 59,119,110,218,230,205,155,171, 14, 28, 56,112,171,139,139,203,128,248,248,248,
-199,127, 69, 57,178,182,182,254,126,216,176, 97,248,245,215, 95,145,158,158,190,178,240,248,173,220,182,109,219,198,207, 62,251,
- 12,155, 54,109,250,158, 16,114,194,140, 40,214,123,125,250,244,193,145, 35, 71,112,250,244,233,153,148,210, 71,175,137,242,133,
- 18, 66,166,238,219,183,111, 65,223,190,125,241,203, 47,191,180, 3,112,233, 13,186,173,219,183,111,143,195,135, 15, 35, 45, 45,
-173,196,142,199,153,153,153,107, 15, 28, 56, 16,216,190,125,123,204,157, 59,183, 13,128,115,102,212,115, 62,214,214,214,107,150,
- 45, 91,230, 95,187,118,109,244,235,215, 79,103, 48, 24,186,143, 27, 55,238,247, 29, 59,118, 88,108,218,180,169,254,144, 33, 67,
-206, 19, 66,190,160,148, 94, 55,231, 88,242, 60,255,221,138, 21, 43, 6,181,108,217, 18, 99,199,142, 53, 29, 59,118,172, 23,165,
-244, 20, 33, 36,108,252,248,241,187, 23, 46, 92,200, 47, 92,184,112, 16,207,243, 41,130, 32, 76,255, 43,242, 91, 20,197,185,139,
- 22, 45,170,238,235,235, 11,157, 78,135,176,176, 48, 36, 36, 36,252,154,148,148,116,234,254,253,251,179,227,227,227,247, 58, 59,
- 59,127,242,245,215, 95,187, 53,104,208,192,191, 98,197,138, 54,230, 68,208,138, 69,166,146, 1, 60, 6, 16, 88, 24,185, 2,128,
- 0, 0,207, 10,223,219, 0,200, 48, 43,177,132,123,240, 52, 60,182,138,173,133, 21,210, 69, 57,194, 99, 83,161,210,104,192, 81,
- 14, 38,109, 58,170, 86,114,132, 72,129,172,148, 88,112, 28, 49,107, 26, 25,163, 72,111, 71, 68, 39,186,218,104,148,168,234,223,
-217,238,206,153, 95,214,219,120, 55, 31, 33,225, 5, 94, 34,183, 90,209,175,239,160, 10, 38,129, 34, 39, 61, 30,132,231,111,130,
-193,120, 87, 6, 75, 16, 4,178,105,211, 38,171,164,164, 36,206,199,199, 39,173, 78,157, 58,185,114,185, 92,212,106,181,130, 82,
-169, 52,105, 52, 26, 81,167,211,201, 35, 35, 35,109, 99, 99, 99,249,162,102, 56,115, 56,119,238,130,179,119,181,218, 73,239, 82,
-243, 53,119,144, 38,149, 74, 34,188, 75,205,191, 19,162, 40,202,103,207,158,221,200,206,206, 46, 55, 48, 48, 48, 54,200,219,225,
- 64, 92, 46, 46, 46, 94,242,243, 64,223,154, 21, 55, 91,243,233, 25,185,114, 42,141,137,137,113,126,246,236,153,154, 82, 42, 43,
- 77, 51, 46, 46, 46, 26, 64,180,139,139,203,218,150, 45, 91, 14,235,210,165, 11,206,158, 61,235,144,155,155,235,160,209, 20,220,
-196,239,218,181, 11,123,247,238, 93,158,144,144,112,214,220,180, 94,191,126,125, 61,128,245,245,234,213,243,183,182,182, 62,107,
-101,101,197, 69,103,230,190, 24, 89, 40,147,112,104,242,205, 13,164,166,103, 64,202, 17, 40,149, 74, 55, 66, 8,247,186,200, 88,
-225, 69,126, 53,128,213,129, 29, 63,235,102, 21,185, 99,253,162,197,139, 21, 69,119,166, 78,182, 50,100,100,100, 32, 57, 57, 25,
- 41, 41, 41,144, 72, 36,208,233,116, 53,222,120,139, 92, 76,179,118,237,218,173, 42, 84,168,176, 79,173, 86,243, 52, 37, 23,233,
- 57,134,151,154, 32,211, 51,242, 33,149, 74,161,209,104,188, 75,210,178,183,183,183,144,201,100,107,214,173, 91,231, 99,105,105,
-201, 15, 25, 50,196,122,200,144, 33,141, 1, 52, 46,105,125,181, 90,205,255,242,203, 47,222,117,235,214, 93,227,233,233,217,229,
-249,243,231, 89,255,195,200, 21, 15,224,179,113,227,198,213, 87, 42,149, 88,177, 98, 69, 56,128, 95, 11,191,222,189,106,213,170,
-137,125,250,244,169, 54,122,244,232,154, 83,166, 76, 25, 73, 8,249,241, 77, 29,200,101, 50, 89,189,154, 53,107, 98,207,158, 61,
- 64, 65,179,224,155,216,115,249,242,229, 5, 93,186,116,129, 74,165,242, 47, 45,232,226,225,225,129,125,251,246, 1,192,221,215,
-172,115,247,209,163, 71,232,209,163, 7, 56,142,171,100,198,190,119,121,239,189,247,182,206,157, 59, 87, 98,105,105,137, 79, 63,
-253, 84,127,237,218,181, 30,148,210,139,132,144, 14, 3, 6, 12, 56,182,101,203, 22,205,249,243,231,125,102,207,158,125,154,231,
-249, 5,130, 32,124, 87,138,230,192, 89,179,102,141,235,222,189, 59,190,251,238, 59,250,235,175,191, 14,166,148,158, 42, 44, 99,
- 39, 9, 33,159,217,218,218,254, 50,105,210, 36,146,153,153, 57,142, 16, 18, 75, 41,253,249,117,122, 57, 57, 57, 89,130, 32, 56,
-105,181, 90,179,250,108,153,187,190,183,183,247,123,190,190,190,216,183,111, 31,186,118,237,138, 19, 39, 78, 64, 34,145, 28,141,
-137,137, 57, 15,224, 20, 0,184,184,184, 88,133,134,134,142,106,222,188, 57,119,250,244,233,110, 0, 54,152,145,132, 8, 0,181,
- 0,156,166,148,198, 20, 14,156,108,132,130,121,176, 30, 83, 74,163, 11,215,243, 5,240,220,172,186,206,152,179,237,212,225,223,
- 91,180,251,240, 11, 43,158, 39,144, 64,134,188,236, 44, 64, 16,224, 93,201, 9,129, 53,157,112, 55, 66,139,203, 39,118,102,230,
-229,229,154, 53,189,132, 96,204,221,114,234,216,222,102, 1,237, 62,182, 82,120,215,132,135,211, 87,117, 30, 92, 63,126, 80, 41,
-151,145, 15, 62,236,101,221, 42,176, 42, 78,221,203,194,149, 83,123, 50,180,185, 25, 91,152,101, 96,148,203, 96,149,212,185, 76,
- 20,197,148, 19, 39, 78,168,167, 78,157,154,227,226,226, 34,201,201,201,225,138,247, 97,146,201,100,112,113,113, 49,101,100,100,
- 24, 78,156, 56, 81, 69, 20,197,180, 55,134, 99,121, 69,194, 79,219, 86,184, 11, 68,173,111,223,177,171,232,238, 94,249,173, 53,
- 1, 64,167, 87,164,252,126,116,143, 77,139,192,166, 82, 39,123,167,146, 42,251, 50,107,254, 31, 17,255,236,217, 51,251,217,179,
-103,223,117,115,115,211, 1, 64, 5,141,144,144, 26,178, 59,221,162,114,151, 4,169, 66, 1, 7, 7,135,124, 11, 11, 11,211,225,
-195,135,219, 80, 74, 19,204, 21,182,181,181,157, 48,108,216, 48,238,194,133, 11,159, 13, 24, 48,128, 84,169, 82, 5,183,111,223,
-198,150, 45, 91,232,206,157, 59,127, 76, 72, 72, 40,215, 93,183, 66,161, 8, 55, 24, 94,158,250,166,248,200,194,244,244,116,112,
-217, 41, 16, 4,193,100,238,236,238, 66,242,221,235,249, 42, 21,106, 85,252,111, 43, 78,122,122, 58,146, 83, 82, 94, 24,172,164,
-164, 36,240, 60,175, 51, 55,157,114,185, 60, 82,175,215,191,146, 78,177,120,164, 4, 66, 70, 10, 12,175,238, 76, 33, 41, 41, 41,
- 57,110,110,110, 63,173, 88,177, 98,238,204,153, 51, 29,150, 44, 89,146,254,232,209,163,108,142,227,116,175,156,103, 74, 47, 47,
- 47,139, 69,139, 22, 57, 46, 95,190, 60, 29,192,234,255,177,185,234,234,231,231,183,182, 83,167, 78, 22, 95,124,241, 5,150, 47,
- 95,142,132,132,132,105,148, 82, 83, 97,221, 32, 18, 66, 38,175, 90,181,106,215,248,241,227, 97, 48, 24,230, 30, 62,124,120, 10,
- 33,100, 20,165,244,215,146, 52, 29, 28, 28,220, 36, 18, 9,130,131,131,179, 41,165,207, 75, 49,181,137, 62, 62, 62, 73,132, 16,
- 71,103,103,231, 42,111, 90,215,206,206,206,211,210,210, 18,177, 5,253, 66, 35, 94,179, 90, 84, 92, 92, 28,149,203,229,196,197,
-197,197,187,180,253,183,177,177, 25,179,110,221, 58,201,153, 51,103, 48,125,250,244,216,200,200,200, 79, 11,167, 17, 0,165,244,
- 14, 33,164, 93,171, 86,173, 54,142, 31, 63,190,234,252,249,243,201,163, 71,143,134, 0,120,163,193,170, 84,169,210,103,131, 7,
- 15,198,138, 21, 43,176,102,205,154,209,148,210,221,175,236,243, 78, 66,136,173,157,157,221,162, 97,195,134, 97,195,134, 13,189,
- 1,188,214, 96, 37, 36, 36, 76,233,221,187,247,196,244,244,244, 5,230,228,169, 57,235,187,185,185,117,238,223,191,191, 35,165,
- 20,203,151, 47, 79, 92,177, 98, 69, 94,102,102,230,175,241,241,241,231, 95,137,196,237, 59,122,244,232,168, 47,190,248, 2,103,
-207,158, 93,236,230,230, 70, 99, 99, 99, 55,150,146,167, 9,132, 16, 79, 66, 72,117, 74,233,227,194, 81,130, 49,175,148,187,170,
-133,235,198,154,179, 79, 41,143,206, 28,118,172,213,233,202,157,235,103,219, 84,169,213, 76,234,104,107, 9,183,106,246,176,211,
-200, 64, 1,220,143,212,226,234,249,227,198,164,196,168,171,230,140, 32, 44,210,116,174,221,249,170,186,194,133, 54,158,190, 65,
-146, 42, 85,171,161, 93,147, 58, 54, 21,172,164,208, 27, 41, 78,220,201,196,149,243, 71,140,201, 73, 49,231,216, 8,194, 63,151,
-127, 90, 7,247, 82, 35, 88,201,201,201,223,202,100,178,230,131, 7, 15,238,211,172, 89, 51,203,161, 67,135, 38, 89, 89, 89,229,
-202,229,114,222,206,206, 78, 78, 41,149, 31, 63,126,220, 53, 33, 33,193, 22,192,142,228,228,228,243,175,156, 64, 47, 61,109,123,
-232,204, 92, 31, 66, 8,113,115,179,105, 46,217,241,121,159,102,205,154,105,222, 86,115,198, 12,208, 25, 45,116,222, 87,156,201,
-212,212,140,195, 35,220,157,157,249,230, 1, 65, 82, 11,181,166,208, 36,216,201, 69, 17,178,178,104,190,163,139,214,255, 68, 83,
-175,215,183, 9, 11, 11,251,104,192,128, 1, 99,253,253,253, 67, 38, 77,154,116,205,198,198,198, 88,120,167, 8,189, 94, 47, 61,
-113,226, 68,195,152,152, 24, 95,163,209,184, 8,192,111,230,166, 51, 36, 36,196, 0,224, 43, 87, 87,215, 67, 73, 73, 73,251,251,
-244,233,131, 13, 27, 54,224,242,229,203,237,226,226,226,174,148,119,223,175, 92,185,146,222,161, 67, 7,237,227,199,143, 53,188,
-198, 3,206,182, 50,116,152,122, 27, 84,164,176, 80, 82,228,102,103,194,152,150,134,188,188,188,135,230,106, 6, 7, 7, 39, 52,
-109,218, 84,247,252,249,115,133,167,167,103,129,185, 42, 52, 86,201,201,201, 72, 75, 75, 67, 86, 86, 22,149, 74,165,193,230,106,
-222,184,113, 35,188,125,251,246, 66, 68, 68, 4,207,243, 14,112,178,145,161,245,196,130,205,109,213, 64,118, 86, 38,180, 41, 41,
-208,106,181,175,213,140,141,141,221,233,230,230, 6, 0,115,167, 77,155, 86,161, 67,135, 14,161,215,175, 95,111, 95,252,119, 26,
- 52,104,240,235,204,153, 51, 59,204,158, 61, 59,117,211,166, 77, 83,226,226,226,118,252, 47,203,146,157,157,221,168,195,135, 15,
- 91, 24, 12, 6, 44, 95,190, 28,139, 23, 47,222, 68, 41,221,251, 74,229,119,148,231,249, 53, 28,199, 13, 27, 49, 98, 4,134, 13,
- 27,166,110,208,160,193,168, 98, 81,174,151, 52, 99, 99, 99,191,171, 95,191,254,196,228,228,100,179, 12,193,211,167, 79, 71,212,
-175, 95,127,124,114,114,242,146, 55,237,187, 70,163,209, 8,130,128,240,240,240, 12, 74,105,214,107, 42,106,157,143,143, 79,156,
- 32, 8,110, 26,141,198,182,180,242,153,145,145,177,192,223,223,127,114, 82, 82,210, 41, 0,243, 41,165,186, 87,244,238, 17, 66,
- 26,140, 30, 61,250,243,185,115,231,190,159,152,152,248,123,105,154,145,145,145, 11, 90,181,106, 53,225,201,147, 39, 91, 41,165,
-235, 95,147,206,159, 8, 33,134,173, 91,183, 14, 9, 15, 15, 95,248, 38,205,152,152,152, 35, 0,142,152,155,191,175, 91,255,149,
-124,255,122,228,200,145, 56,114,228, 8,114,114,114,126,140,141,141, 93,252, 26,173,235, 85,170, 84, 57,212,184,113,227,206, 11,
- 22, 44,144,117,234,212,105, 8,128,141,102,148,207,107, 0, 26, 21,246,131,123, 2,160,232,198,214, 22, 5, 83, 54, 16,188,102,
-116,230,235, 52, 41,213,126,124,251,194,158,141,209,207,238, 54,244,111,217,195, 38, 51,207, 29, 50, 9,135,156,244,120, 92, 57,
-185, 59, 35, 46, 54,236,154,193,144,251,113, 89, 52, 5, 33,111,208,221,139,123, 54, 37, 68,132, 4,230, 53,233,100,147,145, 93,
- 9, 50, 9, 65, 70, 74, 12,174,157,221,151, 30, 31, 29,126,201, 40,228, 15,251, 43,235,249,127,139,230,191,202, 96, 21, 54,151,
-156,243,247,247,191,124,246,236,217, 14,151, 46, 93,122,191,117,235,214, 73, 65, 65, 65, 57,183,110,221,170, 20, 30, 30,238, 8,
-224,128,163,163,227,209,224,224, 96,179,102, 78,126,215,154,133,122, 38,128,204,248,238, 75,251, 5, 49,247, 82, 22,199, 39,253,
-222,203,187, 82, 21, 2,128, 4, 7,223,174, 20, 30, 30,238, 80,214,116,254, 31,185,126, 10,224, 87, 66,200,158,107,215,174, 13,
-249,224,131, 15,134,181,110,221,250, 26,165,148, 92,190,124,217, 63, 50, 50,178,161, 32, 8,235, 69, 81, 28, 86,158,199,228, 20,
- 53,185,200,100, 50,234,227,227, 67, 84, 42, 21, 20, 10,197,195,183, 77,119, 70, 70,198,216, 69,139, 22,173,154,253,195,114,254,
-203,247,172,145,146,154,138,212,212, 84,164,167,165, 65, 6, 45,238,132, 60, 16,114,114,114,198,150, 69,211, 96, 48, 76,154, 58,
-117,234,130,133, 11, 23,106,178,179,179, 95, 24,172,180,180, 52,104,181, 90,156, 61,123, 54,223, 96, 48, 76, 41,139,102, 86, 86,
-214,180, 5, 11, 22,204, 25, 57,118, 50, 55,164,153, 20, 25, 89, 90,100,100,100, 32, 39, 59, 27, 10,162,197,245, 7, 15, 4,189,
- 94,255,205,155, 52, 10, 77, 22,141,142,142,158,146,157,157,253,172,132,223, 72, 24, 49, 98, 68,252,229,203,151,191,143,137,137,
-217,254,191, 46, 67,105,105,105, 63, 52,106,212,104,126,114,114,114,184,193, 96,216, 77, 41, 45, 49, 13,130, 32,124, 77, 8,185,
-182,114,229,202,158,246,246,246,142, 9, 9, 9,139,222, 80, 46,203,100, 8,204, 93, 63, 42, 42,106,154,191,191,255, 55, 73, 73,
- 73,139, 74, 49,108, 99, 10,215, 91, 98,198,111, 31, 5,112,180,148,117, 76, 40,152,162, 98,133,153,251,115, 16,192, 65, 51,214,
-251, 5,192, 47,127, 69,221,145,158,158,190,176, 75,151, 46, 83, 19, 19, 19,207, 37, 36, 36, 44,123,211,186, 70,163,241,227, 97,
-195,134, 77,117,118,118,110,152,148,148,180,220,204, 99, 96, 2,112,177,240, 81, 57, 94, 0,138, 70,225,101, 0,136, 40,207,163,
-114, 10,103,104,255,208,190, 70,219, 78, 39,127, 95, 54, 0,130, 80, 27, 32,224,164,252, 61, 93, 94,238, 22,115, 35, 87, 37,104,
-126, 96, 95,163,109,167,180,196,136,129,162, 32,212,230, 8, 68,194,243,247,243,117,185, 27,146, 66, 78,178, 71,229, 48,202,103,
- 66,203,242, 44, 92, 87, 87, 87,149, 84, 42,237, 78, 41, 13, 20, 69,241,186, 40,138,123,227,226,226,180,111,227,112,223,189, 38,
- 33, 99, 6,168,156, 44, 84,248,201, 66, 5,191,149,123,108,167,154, 76,226,158,183, 77,231,255,203, 29, 3, 33, 68, 35,147,201,
-198,138,162,216, 79, 20,197,109,162, 40, 46,122,211,220, 66,230,166,179,106,213,170,171, 90,181,106, 53,224,216,177, 99,107, 35,
- 35, 35,199,190,139,125,111,214,172,217, 6, 15, 15,143, 15, 90,182,108,201, 43,149, 74,196,199,199, 35, 45, 45, 13, 79,158, 60,
- 49,165,166,166,206,185,120,241,226,252,114,104,254, 44,151,203,223,239,218,181,171, 90, 38,147, 33, 45, 45, 13,153,153,153,244,
-226,197,139,122,142,227, 38, 94,190,124,121,109, 25,143, 39,105,214,172,217,110, 15, 15,143, 54, 65, 65, 65,188, 76, 38, 67,122,
-122, 58, 82, 83, 83,241,248,241, 99, 33, 57, 57,249,219,171, 87,175,254,100,142,166,183,183,183, 60, 52, 52,180,196, 62, 49,254,
-254,254,210,215,153,127,118,151,204, 52,153, 38,211,252,183, 69,176, 8, 33, 67, 41,165,107,255,177, 17,172, 87, 41, 52, 41,219,
-240, 22,207,167,250,243, 53, 41, 93,178, 5, 9, 0,233,246,221,119, 32, 81,209,218,130, 1,241,255, 18, 10,205,212,119, 40,165,
-143, 72, 89,121,246,236,217, 23,174,174,174,227,222,100, 84,203,202,133, 11, 23, 62,169, 95,191,254,111, 49, 49, 49, 83, 84, 42,
- 85,117, 65, 16, 76,122,189,254,142, 94,175,159,124,237,218,181, 91,229,212, 28, 82,191,126,253, 93,123,247,238,253, 74, 16, 4,
- 95,142,227,242, 41,165,193,148,210,239, 47, 95,190,252,168,156, 17,194, 30,245,235,215,239, 17, 27, 27,251,141, 66,161,168, 38,
-138,162, 49, 63, 63,255,166, 94,175,255,246,218,181,107,102,107,190,206, 92, 1, 5, 83,100,176,251, 61, 6,131,193,248,231, 32,
-249,231,238, 26,165,211,167,131, 98, 58,203,228,119,108,134,223, 41,183,110,221, 58, 6,224,216, 59,214, 60, 14,224,248, 59,214,
-220, 3, 51,103,196,102, 48, 24, 12, 6,131, 99,135,128,193, 96, 48, 24, 12, 6,227,221, 66, 0,248,149,244, 69, 89,218, 86, 9,
- 33,126,101,253, 97, 51,250,190, 48, 77,166,201, 52,153, 38,211,100,154, 76,243, 31,166, 89, 76,123,230,107,190,138, 45,212,249,
-191,238,131, 69,254,204,238, 73,172, 3, 32,211,100,154, 76,147,105, 50, 77,166,201, 52,255,141,176, 38, 66, 6,131,193, 96, 48,
- 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,131,193, 12,
- 22,131,193, 96, 48, 24, 12,198,223, 6,242, 47,154,228,156,193, 96, 48, 24, 12, 6,227,127,194, 75, 17, 44, 66, 8,115, 91, 12,
- 6,131,193, 96, 48,254,231,252,211, 60, 8,107, 34,100, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,227,255,192,
- 96,177,166, 65, 6,131,193, 96, 48, 24,127, 5,255, 84, 15, 82, 20,193,106, 89,184,131, 45, 89, 86, 51, 24, 12, 6,131,193,248,
- 31,242,143,244, 32,108, 20, 33,131,193, 96, 48, 24, 12,198, 59,134,245,193, 98, 48, 24, 12, 6,131,193,248,127, 50, 88,132, 16,
- 63,166,201, 52,153, 38,211,100,154, 76,147,105, 50, 77,102,176, 24, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193,
- 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24,140,191, 8,
- 2,160,196,145, 0,148,210,251,102,139,148, 99, 52, 65,105,250, 76,147,105, 50, 77,166,201, 52,153, 38,211,252,231,105,150,166,
- 93, 22,255,241,183, 54, 88,127,230, 68,163,132, 16,191,119,125,160,152, 38,211,100,154, 76,147,105, 50, 77,166,249,207,211,252,
-167, 33, 97,135,128,193,248, 63,231,119,194,195,190,102,101, 16,234, 12, 34, 75,196,217,187,207, 49,157,138,111,173,233, 92,171,
- 34,244, 70, 71,168, 84, 41, 56,113, 59,252,173, 53, 25, 12, 6,131, 25, 44, 6,131,241,127,131,187,111, 85, 24,197,153, 0,156,
- 1,125, 24,154,251, 45, 4, 16,242, 86,154,142,190, 85, 33,138,211, 33,227,220, 96,200,127,134, 86, 53, 23, 2,120,196, 14, 54,
-131,193, 96,152,199, 95,210,201,189, 65,131, 6,151, 2, 2, 2,166,181,108,217, 82,193,178,128,193,120, 11,238,215, 86,195,104,
-124, 47,223, 32,186, 30,189,156,230,144,171, 19,170,129, 51,180,199, 35, 95,205, 91,105,114, 98, 91,157, 65,240,216,114, 50,215,
- 49, 71,103,170, 14, 81,120, 59,205, 66,234,214,173,107, 29, 24, 24,184,207,223,223,191, 2,203, 60, 6,131,193, 12,214, 59,134,
- 82, 90,215,209,209,113,164, 86,171,125, 92,191,126,253,206,255,166, 3,222,176, 97,195,211,141, 27, 55,142, 8, 10, 10,138, 8,
- 10, 10,186, 92,218,242,127, 42, 13, 26, 52,168,219,180,105,211, 35,190,190, 5, 23,237,218,159,239,117,168,255,217,113,175,134,
-163,142,186,177,211,178, 12,100, 83, 71,128,111,241, 40, 60, 79,149,152,110,114, 12,126,156,107, 1,202, 55, 71,170,232,252, 86,
-154, 34,105,113, 59, 84,167,190, 18,230,224,120,233, 65,190, 37,192,183,120, 43,205, 66, 36, 18,201, 16, 0,173,121,158, 31,193,
- 50,239,223, 13, 33,196,151, 16,210,153, 16,226,255, 14, 53,103,213,172, 89, 51,148, 16,242, 37, 59,194,140,255, 27,131,213,211,
-139, 52,238,231, 69,142,245,241, 36, 73,125,189, 72, 82,127, 47,114,178,103, 53,210,180,188, 63,188,107,215, 46,213,230,205,155,
- 29,252,252,252, 54, 54,108,216,240,100,195,134, 13,189,203,163, 19, 24, 24,184,175, 65,131, 6, 31,188,186,204,223,223,191,231,
- 43,203,110, 6, 6, 6, 38, 4, 4, 4, 60, 48, 71,215,223,223,255,158,191,191,127,114,131, 6, 13,238,189,178,188,103, 96, 96,
-224,190, 87,204,194, 7,175, 46,123, 29, 60,207,187, 29, 56,112,192,225,208,161, 67, 14, 82,169,212,241,213,229, 7, 15, 30,124,
-105,121, 89, 9, 8, 8,248, 36, 32, 32,224,116,241,101,245,235,215,255,248,213,101,165,236,251,233,250,245,235,127,252,138,238,
-233,128,128,128, 79,222,145,201,172, 47,151,203,143, 25, 12,134,166, 26,141, 70, 13, 0, 18,163,202, 82,148, 73,122, 26,168,164,
- 94,237,111, 78, 56,176, 83,211, 12, 30,249,202, 32,154,154, 8, 34,181,127, 16,174,115,232,216,165,167,228,238, 51,173,189, 81,
- 16,108, 33,162, 57,206, 85, 86,148, 75, 83,208, 7, 9, 84,116, 60,117, 91,234,208,178,243, 8,254,204,125,169,189, 81, 16,236,
- 32,136, 77,203,165,249,223,114, 37,229,121,126,212,208,161, 67, 57, 66,200,112,111,111,111,249,191, 41,187, 26,215, 33,174,109,
- 26, 72,206, 7,212, 34,141,223,161,161,168,105, 97, 97,113,145, 16, 82,245,255,204, 92,213, 5,160,166,148, 30, 2,224, 72, 8,
-145,188, 3,205,249, 51,103,206, 28,115,239,222, 61, 23, 79, 79,207, 41,132, 16,158, 85, 18,140,191,189,193,234, 93,133, 76,118,
-113,118,219, 63,121,201,182,166, 63,159,123,174,249,241,192, 45,205,216,241,115, 26,187, 88, 59,236,233,239, 69,190,127,221,118,
-111, 26, 97, 32,151,203, 17, 22, 22,134, 21, 43, 86, 40,103,204,152,209,200,194,194,226, 90,195,134, 13,127, 40,138,104,152,171,
- 73, 41,109, 36,147,201, 86, 53,108,216,112, 77,177, 10,187,145, 82,169, 92,217,176, 97,195,245, 69,205,144,254,254,254,149,175,
- 95,191,110, 73, 8,113, 52, 39,157,129,129,129,206,193,193,193,106, 66,136, 51, 0,180,108,217, 82, 17, 24, 24,184,206,221,221,
-125, 5,128, 70, 0,224,237,237, 45,111,216,176,225, 26, 15, 15,143, 31, 9, 33,141,204,217,119,142,227, 96, 99, 99,131,109,219,
-182,129,227,184,226,149, 3,108,108,108,176,117,235, 86, 16, 66,202,124, 60,125,125,125, 53,129,129,129,219, 92, 92, 92,126, 16,
- 69,177, 33, 0,212,174, 93, 91, 29, 24, 24,184,213,221,221,125, 65,209, 50, 51, 53, 27, 42, 20,138, 31, 2, 3, 3,183,214,174,
- 93, 91, 13, 0,162, 40, 54,148, 74,165,243, 3, 3, 3,183,149, 53,143, 90,180,104,241, 69,163, 70,141,210, 3, 2, 2,178,155,
- 53,107,182,149,231,249, 35,179,103,207, 86, 43,149, 74,189,201,182,146,198,127,216, 41, 15,153, 84,110,162,132,203,167, 2,102,
- 74,179,101,182,222,163,142,202,205,221,247,242,242,127,175,153,204, 59,128,160,213,147, 72,173,178, 74,213, 6,106,199, 26, 61,
-225, 96, 35, 85, 92,125,152,107, 1, 9,105, 9, 78, 99, 95, 46, 77, 72, 91, 61, 8,211,170,236,188, 58,170, 2, 26, 55, 7,212,
- 85, 21,231,238,228, 90, 66,194,151, 79,243,191,223,119, 15, 10, 10,146,181,109,219, 22,174,174,174,156,149,149, 85,239,127,124,
- 30, 21, 51, 87, 22, 10,249,185, 69, 51,199,212,119,182, 83,255,102,142,201, 50, 99,248,124, 77, 71, 71,199,163, 43, 87,174,172,
-103,105,105,121,194, 28,147,245,119, 56,158,133,230, 74, 70, 41,189, 94,100,235, 1, 4,189,165,230,252, 25, 51,102,140,152, 56,
-113, 34,178,179,179,241,241,199, 31, 91, 2,152, 91, 30,205, 94,189,122,241,189,122,245,226,255, 21,117,200,223, 76,179, 20,228,
- 0, 90, 1,232, 12,160, 13,128,192,194,247, 1,133,175,206, 0,218,190,242, 55,160, 40, 70, 80,248,185,225,107, 52, 58,151,176,
- 93, 64,177,229,197, 63,191,250,254,205, 6,139, 16, 66,139,255,125,169,176,121,147, 70,246, 46,110, 99,230,237,185,161, 18,159,
-222,193,173, 79, 91,227,241,232,238, 80, 61,187,131,241, 35, 39,168,172,172,108,134,247,242, 38,205,203,115,180,158, 62,125,138,
-237,219,183,195,222,222,158,172, 95,191, 94,241,209, 71, 31, 13,177,178,178,122,218,160, 65,131,222,230,106,112, 28, 39,254,242,
-203, 47,154,110,221,186,245,180,179,179,187, 17, 16, 16, 80,133,227, 56,113,211,166, 77,154, 62,125,250,244,208,235,245,193, 13,
- 27, 54,244,190,117,235,150,112,227,198, 13,240,188,121, 55, 53,193,193,193,194,145, 35, 71,138, 34, 46,222, 0,130,231,205,155,
-215,115,207,158, 61, 22, 86, 86, 86, 52, 32, 32,160,138,135,135,199,141, 31,126,248,161,247,174, 93,187, 44, 44, 45, 45,169,153,
- 21, 1,116, 58, 29,148, 74,229, 75, 70,170,104,185, 66,161,120,173,193,122, 67,212,170,102,133, 10, 21,110,205,157, 59,183,203,
-222,189,123, 85,150,150,150,104,212,168, 81,117, 27, 27,155,219, 11, 22, 44,232,186,111,223, 62,149,165,165,165,217,122, 50,153,
- 12, 91,182,108, 81,247,235,215,175,179, 66,161,184,213,168, 81,163,234, 50,153, 12,219,182,109, 83,247,235,215,175,163, 90,173,
- 14, 14, 8, 8,168,105,174,158, 32, 8,227,151, 44, 89, 34,255,237,183,223,248, 74,149, 42,181,155, 61,123,182,218,223,223,159,
- 80, 74, 65,229, 85,173, 77, 18,218, 83,199,153,220,120,189,225, 32, 7,146, 40, 72, 12,253,109, 4,158, 69,177,222,196,239,132,
- 7, 49,212, 5,136, 87,240,211,188, 10,117,155,245,151, 32,105, 63, 2,107, 88, 72,206, 4,103, 59, 82, 17, 21, 33,152, 26,224,
- 92, 75, 73,153, 52,101,198,218,224,168,247,137, 59, 92,133,160,182,253, 37, 81, 81, 81,168, 82,179, 37,127,224, 6, 28, 41, 69,
-101, 16,161,126,153, 52, 95, 46, 87,147,122,245,234,165,137,136,136, 64, 80, 80,144, 90,161, 80, 76,124, 39, 81,188, 43, 53, 42,
-226, 66,141,102,184, 88,195,185,188,105,251,179, 35, 87, 22, 10,249,217,109, 91,126,117,169,221,236, 51,178,102, 76, 37,219, 10,
- 22,178,223,222, 38,146, 85,104,174,142, 92,187,118,205,238,189,247,222,195,140, 25, 51,236,173,172,172, 78,252,221, 35, 89,197,
-205, 21, 33, 68, 85,216, 60, 24, 7,192,237, 45, 52, 23,204,152, 49, 99,196,164, 73,147,112,245,234, 85,252,240,195, 15,232,216,
-177, 35,108,108,108, 2,205,213,104,208,160, 65, 64,139, 22, 45,182,183,104,209, 34, 62, 58, 58, 58, 43, 50, 50, 50,171, 89,179,
-102,241, 45, 90,180,216,222,160, 65,131,128,183,217,229,194, 23,227,205,121,248, 90, 15, 82,140, 58, 19, 39, 78, 12, 36,132, 28,
-156, 56,113, 98, 3, 0,246,132,144,131, 0, 28, 0, 56, 20,190,151,191,242,215,161,208, 52, 21,125, 95,161, 36,141,162,215, 43,
-219, 57, 20, 91, 94,252, 55, 94,125, 95,122, 4,139, 16,210, 2,192,249, 87, 87,144,138,152, 58,236,235,239,149,225, 27, 23, 35,
-126,203, 18,144,148, 88,240, 25, 9,200, 63,191, 31,198, 11,251, 49,176,113,144, 74, 5, 50,189, 60, 7,213,194,194, 2, 50,153,
- 12, 79,159, 62,197,195,135, 15,209,177, 99, 71,217,242,229,203,173,253,252,252, 86, 54,105,210,228,106,195,134, 13,253,204,200,
- 24, 84,171, 86, 13,125,250,244,145,143, 30, 61,218, 83, 46,151, 95,166,148, 74,170, 84,169,130,143, 62,250, 72, 54,126,252,248,
- 74,114,185,252,162, 40,138, 50,181, 90,109,182,121, 33,132, 64,173, 86, 3,128,212,203,203,235,210,246,237,219, 43, 55,105,210,
- 68,114,252,248,113,100,103,103,243, 85,171, 86,189,186,125,251,118,175,198,141, 27, 75, 46, 94,188, 8,173, 86,107,182,193,202,
-205,205, 45,209, 96,229,228,228,252, 97,185, 25,230,234, 19, 79, 79,207, 11, 59,118,236,112,107,218,180, 41,127,230,204, 25,100,
-103,103,195,221,221,253,226,142, 29, 59,220,130,130,130,248,203,151, 47, 35, 59, 59,187, 76, 6,171,240,248, 73,199,142, 29,235,
-198,243,252, 5,153, 76,134, 74,149, 42,225,163,143, 62,146,125,253,245,215,110, 50,153,236,156,185, 77,134,130, 32,200, 29, 28,
- 28, 96,109,109,141,207, 62,251, 76, 93,189,122,117, 98, 50,153, 64, 41,133,220,144,107, 32, 34,173, 70, 8,247, 1,225,121,131,
- 0,178,149, 80,190,153,104,146,200, 88,181,243, 6,172,252,236,192,147,214,145,241,249, 10,165,198,195, 66, 99, 95, 29, 72, 59,
- 15, 79, 55, 5, 8,225, 20,215, 31,229,104,192,147,214, 16, 82,237,202,164, 41,160,245,243,216,124,133, 65, 85, 75,227,234, 86,
- 17, 41, 41, 41,240,168, 82, 3, 58,206, 65,126,249, 65,142, 6,180,140,154,133,248,251,251, 55,241,240,240,112,174, 92,185, 50,
- 82, 82, 82, 80,181,106, 85, 88, 88, 88,216,212,171, 87,175,117,185,143,193,185,202, 10,100,113,141, 32, 96, 46,128, 41, 0, 55,
- 19, 36,165, 46,110,249, 75,255,110,230,106,251,214, 95, 93, 43,184, 84, 7,238,127, 6, 39, 59, 57,214, 79,172, 99, 91,193, 66,
- 81, 46,147, 69, 8,169,233,228,228,116,228,218,181,107, 21,148, 74, 37,130,131,131,225,235,235,139,197,139, 23,219,219,216,216,
-252,109, 77,214, 43,230,202,150, 82,170, 5, 32, 2,232,133,114,140,122, 37, 5, 44,254,254,251,239,191,152, 52,105, 18,174, 92,
-185, 2, 55, 55, 55, 36, 37, 37,161,121,243,230, 81, 25, 25, 25,243,205,137, 86, 53,111,222,252, 71, 91, 91,219,131, 67,134, 12,
-233,178,109,219, 54,171,189,123,247,146, 22, 45, 90,144,138, 21, 43, 90, 13, 25, 50,164,139,173,173,237,193,230,205,155,255,104,
-110, 84,171, 16, 9, 0, 37, 0,117,209, 43, 44, 44, 76,238,237,237, 45, 39,132, 40, 11,205,165,130, 16,194,158,166, 82,138, 7,
- 41,134,253,188,121,243,230, 80, 74,187,204,155, 55,111, 78,177,237, 14,190, 65,179,184,105, 2, 0,188,170, 65, 41,237, 82,252,
-111,241,109, 41,165, 93, 40,165, 93,138,111,255,166,223,123,173,193, 2,112,150, 82,218,226, 15, 97, 64, 2, 63,103,207,234,200,
- 56,177, 19, 42,158,188,244,226,158,223,135,135, 82, 2, 19,165, 53,203,115, 64, 45, 44, 44, 94,188, 56,142, 67,124,124, 60,120,
-158,199,180,105,211,148, 35, 70,140,168, 37,145, 72,206,180,104,209, 98,102,105,134, 5, 0,174, 95,191,142,170, 85,171,146, 73,
-147, 38, 89, 54,111,222, 92, 2, 0,119,239,222,133,183,183, 55,153, 53,107,150, 69,215,174, 93, 73, 89, 12, 22,199,113, 80, 42,
-149,104,217,178, 37,217,176, 97,131, 70,161, 80,224,208,161, 67, 72, 73, 73,193,123,239,189, 39,217,176, 97,131, 70,169, 84,226,
-220,185,115,200,204,204, 44,147,113,203,207,207,199,171,105,121, 93,100,235, 77, 52,105,210,100,181,179,179,243, 15,155, 55,111,
- 86,168, 84, 42,156, 57,115, 6,153,153,153,232,219,183,175,105,235,214,173, 74, 43, 43, 43, 92,190,124, 25,153,153,153,229, 42,
-240,197,142,169, 42, 40, 40,200, 8, 0,183,111,223,134,143,143, 15,153, 52,105,146,202,202,202,106,126,179,102,205, 86,155, 17,
- 74, 70, 94, 94, 30,116, 58, 29,158, 61,123,134,180,180, 52,196,196,196, 64, 20, 69, 16, 36,101,139, 50,233,111, 68, 20, 62,224,
-165, 10,133,132, 35,143, 64, 80,131, 74, 68, 25,249,238, 59, 86,249,188,174, 16,201,242,171, 66, 36,117,175,132,228,216, 54,125,
-175,159, 12,201, 71, 0,106, 4,136, 4,173, 26,186, 75,246, 95,206,115, 4, 37,126, 80, 17, 31,192,140, 2, 69, 8,129, 84,239,
- 13, 74,234,159, 8, 54,217, 53,109,255,185, 44, 38, 38, 6, 50,153, 12, 10,133, 2,245, 27,127, 40,217,126,214,232, 12,160, 54,
-148,164,154, 89,154, 47,155,246, 9,131, 7, 15, 86,199,198,198,190,208,236,216,177,163,198,194,194, 98, 82,185,205, 21,111, 17,
- 8,147, 48,226,193,115,109,197, 89,155,227,171,135,198,104,125,192,209, 81,208, 11,117,222,214,100, 85,169, 82,165, 89,245,234,
-213, 67,188,188,188,130,222,198, 92, 89, 42,228,103,118,108,253,213,213,206,185,192, 92, 65,200, 3,120, 21,156, 29,109,177,126,
-122, 75,219, 10,150,170, 50,153,172, 66,115,117,248,234,213,171, 21,148, 74, 37,110,222,188, 9,185, 92, 14,165, 82,137,218,181,
-107, 99,237,218,181,246,182,182,182,127, 11,147, 69, 8,177, 33,132,180, 37,132,244, 32,132,116, 47,102,174, 42, 3,104, 73, 8,
-105, 13,192, 9,192, 69, 74,233, 61, 51, 53,131, 36, 18,201,238,186,117,235,134, 73, 36,146,224, 57,115,230, 12, 27, 63,126, 60,
-150, 45, 91,134,150, 45, 91, 62,159, 48, 97, 2, 30, 63,126,108,202,205,205,237, 69, 41, 61, 82,154, 94, 92, 92,220, 20, 47, 47,
-175,158,123,247,238,213, 84,170, 84,137,203,205,205,197,137, 19, 39,176, 96,193, 2,228,231,231,195,221,221,157,219,187,119,175,
-198,203,203,171,103, 92, 92,220, 20, 51,210,103,111,111,111, 95, 21, 5,205, 89, 10, 0, 42, 0,234,136,136, 8,205,153, 51,103,
-108,235,214,173,107, 99, 97, 97,161,158, 50,101,138,235,232,209,163,187,148, 22, 1,249,151, 81,162, 7,121,141,105, 42,126,125,
-233,242, 58,211, 83,244, 93, 73,230,169,188,137,124,211,239,189,201, 96,181, 36,132,156, 43,105, 37, 67, 90, 34, 20, 16,160,230,
- 9, 84, 18, 82,240,151, 39, 80, 17, 17,146,244,196, 50, 86,181, 47, 27, 44, 75, 75, 75, 88, 90, 90,190,100,180,180, 90, 45,114,
-115,115, 95,234,163,244, 58,138,154,252,108,109,109,145,157,157, 13,147,201,132,162,230, 48, 59, 59, 59,228,231,231,131, 16, 2,
-141, 70, 3,141, 70, 83,102,131, 5, 0, 87,174, 92,193,165, 75,151, 32,145, 72, 96,103, 87,112,243,126,243,230, 77,220,187,119,
- 15,114,185, 28, 21, 42, 84, 40,147,174, 94,175,135, 82,169,252, 67, 31, 44,189, 94, 15,133, 66, 97,118, 51, 38,199,113,208,233,
-116,244,230,205,155,184,127,255, 62, 20, 10, 5, 28, 28, 28, 32,147,201, 16, 29, 29,141, 71,143, 30, 65, 46,151,195,193,161,124,
-231,176,149,149, 21, 50, 50, 50, 32,138, 34, 84, 42,213,139,101, 57, 57, 57,224, 56,206,172,252, 41,226,246,237,219,184,114,229,
- 10,194,195,195,113,247,238, 93, 60,126,252, 24, 47, 61, 69,128, 22,134,209,141,162,145, 2, 28,111,228,185, 25,152,206,170,156,
- 18,171,161, 58, 86,224, 36,109,146, 51,140,138,148, 28,185,149,147,119, 27, 32,229, 8, 64,120, 64,106,131, 70,245, 60, 17,149,
- 32,168, 31,199,228, 43, 97, 16,218,225,120, 77, 27,179, 52, 37,146,214, 73, 25, 70, 69,120,166,131,101, 77, 63,127, 36, 37, 37,
- 65,161, 80, 64,161, 80,160, 65,195, 54, 8, 75, 16, 85, 15, 34,180,106,136, 98, 91,179, 52,255, 27,189,242, 84, 42,149,129,245,
-235,215, 39,137,137,137, 80, 40, 20, 80, 42,149,104,220,184, 49, 56,142,171,229,239,239,239, 83,166,253, 15,243,150, 67,102, 17,
- 0, 8, 35, 30, 62,207,115,217,119, 73, 91,245,253,247, 63,180, 93,250,123,178,207,195, 8, 93,101,152, 12,163,145,109,172, 87,
- 94,147, 85,165, 74,149,166,106,181,122,215,148, 41, 83, 42, 75,165,210, 61,158,158,158, 77,202,163,163, 86,240,203, 39,143,238,
-235,106, 91,100,174, 76,185, 0,175, 2,120,117,129,201,114,178,199,172,209,109,109, 85, 82,217,118,115, 53, 85, 42,213,198,149,
- 43, 87,218, 23,153, 43,153, 76, 6,165, 82,249,226, 85,191,126,125, 76,159, 62,221,222,214,214,118,195, 95,108,174,108, 1, 52,
- 1,112, 31,192, 94, 0,103,138,153, 43, 47, 0,251, 10,163, 86,119, 40,165, 81,102,106, 54,234,208,161,195,145,176,176,176,246,
-119,238,220,113, 78, 72, 72,240, 25, 59,118, 44,150, 46, 93,138,241,227,199,255, 70, 41,173,187,115,231,206,198,215,175, 95, 15,
-164,148,134,152, 89,135,126,218,191,127,127,181, 74,165,130, 82,169,196,230,205,155,241,249,231,159, 67,161, 40, 24,203,161, 86,
-171,161, 82,169,208,191,127,127, 53, 33,100,176, 25,146,105, 89, 89, 89, 22, 61,122,244,240, 40,140, 92,105,244,122,189, 69, 74,
- 74,138, 21,199,113,214,181,106,213,114,156, 62,125,186, 79, 78, 78, 78,157, 3, 7, 14, 36, 1, 72, 97, 21, 90,233, 30,228, 85,
-131, 99,206,178,242,174,111,174,201, 42,147,193,162,148,158, 3,208,188,132, 21,238, 71,221, 56, 7, 59,223,250, 47, 71,176, 36,
- 4,106, 75, 43, 60,143,141,134, 20,228, 97, 57, 18,248, 82, 4,171,232, 21, 31, 31,143, 9, 19, 38,228,109,217,178,229,129,193,
- 96,104,117,238,220,185,105,230, 68,176, 28, 29, 29, 17, 21, 21, 69, 23, 44, 88,144,125,244,232, 81, 83,209,178,232,232,104, 58,
-117,234,212,156, 95,127,253,149,150,181,137, 80,165, 82,225,220,185,115,116,218,180,105, 89,177,177,177,212,206,206, 14, 21, 42,
- 84,192,169, 83,167, 76, 19, 39, 78,204, 10, 13, 13,165,118,118,118,176,179,179, 43,147,174, 32, 8, 80,169, 84, 47,109,195,113,
- 28,140, 70,227, 31,150,191,137, 11, 23, 46,124,158,153,153, 57,254,155,111,190,209,134,132,132, 80, 7, 7, 7, 56, 56, 56, 96,
-227,198,141,146,143, 63,254, 88,123,247,238,221, 23,203,202,131,189,189, 61, 30, 63,126, 76,231,206,157,171, 61,121,242,164, 20,
- 0, 28, 28, 28,240,248,241, 99,250,253,247,223,107, 51, 50, 50,198, 95,184,112,225,115,115,242, 58, 45, 45, 13, 41, 41, 41,136,
-137,137, 65, 74, 74, 10, 82, 83, 83, 33,138, 34, 40, 28, 45, 57,131,241, 35,240,220, 30,193,152,159,111,148,144,106, 0,125, 46,
-136, 6,253,244,233, 96, 51,135,151,132, 92,112, 2,104,227,139,247,114,172,219,117,234, 45, 39, 89,215, 1, 99, 14, 32,181, 5,
-164,182,144, 40, 43,160, 67,235,122,252,134,227, 89, 78, 32,104, 8,107,121,233,253, 91,164,162, 35,168, 24,116,242,150,206,166,
-105,199,145,242,180,180, 52,112, 28,247,194, 96,169, 53, 26,180,237,212,159,251,229,132,206, 9, 34,109, 4, 21, 49,187,207,140,
- 76, 38, 27, 51,120,240, 96,217,171,154, 42,149, 10,221,186,117, 83,104, 52,154,241,102,239,251, 35, 95, 25,146, 84, 1, 16,133,
- 17,143, 35,180, 46,123, 47,107,171,142,157,254,139,170, 86,157,134, 24,254,190,131,106,238,150,228, 26,119,194,242, 42, 67, 98,
- 26,137, 28, 99,125,172, 45,155,201,242,244,244,108,162, 86,171,119,239,221,187, 87,221,170, 85, 43,140, 27, 55, 78, 35,147,201,
-246, 84,169, 82,165,204, 35,166,181,217,194,215,223, 47,221,156,116,247,183, 14,128, 41,187,208, 92,253,247,149,148, 41, 98,234,
-202, 51, 89,122, 42,126,108,182,166, 86, 59,228,179,207, 62, 75,219,181,107,215, 31,204,149, 82,169, 68,120,120, 56,102,205,154,
-149,158,158,158, 62,244, 47, 46,165,117, 0,220, 5,160, 3,208, 20,128,186,112,164, 96, 96,161,217, 18, 40,165, 73,148,210, 4,
-115, 5,121,158,255,122,213,170, 85, 18,173, 86,139, 33, 67,134, 32, 58, 58, 26,113,113,113,152, 60,121,114,132, 40,138, 67, 10,
- 53,239, 81, 74,159,152,171,153,155,155, 59,124,230,204,153,218,216,216, 88,248,249,249, 33, 41, 41, 9,157, 58,117, 66,231,206,
-157,161, 86,171, 81,187,118,109, 68, 71, 71,227,187,239,190,211,229,229,229,153, 83,215,137, 70,163,241,225,153, 51,103,148, 93,
-186,116,169,182,112,225,194, 42,103,206,156,241,206,203,203,171,156,159,159, 95, 35, 62, 62,222,247,192,129, 3, 21,215,174, 93,
- 27, 29, 17, 17,113,131, 82, 42,176, 10,237,205, 30,228, 29,112,232,109, 34, 85, 37, 69,192,204,133, 43, 20, 34,197,255,190, 20,
-189, 34,248,126,211,239, 27,117,242, 74,213, 96, 93,163, 46,212, 74, 37, 84, 10, 57, 84, 54,118,208,137, 34,214,133, 39,228,229,
-130,126,247,182, 6, 75, 20, 69,172, 89,179, 70, 55,107,214,172,204,248,248,248, 81,231,207,159,111,116,237,218,181, 82, 71, 41,
-112, 28,135,172,172, 44,236,220,185, 83,187, 97,195,134,231,249,249,249, 65, 82,169,212,164,215,235,177,109,219, 54,221,178,101,
-203, 34,117, 58, 93, 83,169, 84,106, 40, 75,243, 91,145,193,146, 74,165,198,252,252,252,160,223,126,251, 45,236,224,193,131, 90,
- 43, 43, 43, 72, 36, 18,147, 78,167, 11,220,188,121,243,211, 29, 59,118,104,173,172,172,202,164, 43,138, 98,137,125,176, 4, 65,
-120,113,231,100, 46, 55,110,220,216, 96, 52, 26, 91,108,223,190, 61,118,195,134, 13, 58, 43, 43, 43, 0,128, 32, 8,205, 54,109,
-218, 20,251,211, 79, 63,229,151,165,131, 59, 0, 24, 12, 6, 8,130,128, 77,155, 54,229,239,216,177, 35, 86, 20,197,102, 69,203,
-126,249,229, 23,221,230,205,155, 99,141, 70, 99,139, 27, 55,110,108, 48, 51,175,245,113,113,113,136,143,143,199,221,187,119,245,
-143, 30, 61,162, 41, 41, 41,160,148,194, 40,209, 72, 40, 71,158,138,148,254, 78, 5, 65,198, 83,244, 38, 32,231, 9,207, 27, 88,
-149,243, 26,114,160, 6, 33,170, 39,209, 58, 75,165,204, 72,144,176, 27,144,217,190, 48, 88,144,218,194,213,205, 29, 55, 30,231,
- 89,128, 64, 14,157,177,116,135,157, 71, 53, 32, 68,253, 32,130, 90, 74,100, 42,146,152,152,248,226,162, 93,100,136,170,120,249,
-226,246,211, 60, 13, 8, 20, 16, 97,246, 84, 34,162, 40,118,180,176,176,144, 20,105, 22,233, 41, 20, 10,120,122,122,242, 70,163,
-177,157,217,251,158, 40, 58, 67, 48, 13,127, 18,169,115,217,123, 81,235,253,245,212, 95, 84, 42, 46, 29,136, 88,134, 90, 85,157,
-241,245,160, 58,242,201,235, 83,106,222,120,152,231, 9, 78,248, 12, 53,115,237,205,149,246,242,242, 10, 82,169, 84,123,246,238,
-221,171,214,104, 52, 8, 11, 11, 67,157, 58,117, 48,107,214, 44,181, 74,165,218, 93,165, 74,149,102,101,201,166,203,143,104, 84,
- 94,142,208,234,219, 53,209,137,119,195,133, 2, 99,197, 21,152,171,228, 44,138,207,166,238,207, 76,207,209,245,189,122,199,120,
-174, 12,245,230,221,204,204,204,174, 83,167, 78, 77, 75, 73, 73,121,201, 92, 69, 70, 70,162, 79,159, 62,233, 41, 41, 41,237, 41,
-165, 15,255,226, 82,170, 65, 65,231,117,159,194,136, 85,109, 74,169, 9, 64, 78,121, 77, 69,205,154, 53,235, 86,170, 84, 9,171,
- 87,175,198,186,117,235, 50, 22, 47, 94, 12, 74, 41,170, 85,171,102, 85, 94,205, 59,119,238, 28,209,106,181, 19, 6, 14, 28,168,
-221,186,117,171,240,241,199, 31, 35, 32, 32, 0,254,254,254, 24, 56,112, 32,214,173, 91,103, 26, 48, 96,128, 78,167,211,141,191,
-115,231,206, 17, 51,243, 40, 63, 43, 43,235,206,161, 67,135,238,173, 90,181, 42,230,171,175,190,202, 25, 58,116,168,108,206,156,
- 57, 41, 59,119,238,188,115,225,194,133, 99, 58,157,238, 6,165, 52,159, 85,102, 47,142,217,107, 61, 72, 49,146, 11,141,142,254,
-149,191,201,165,124,103,238,182, 37,190, 55, 99,189,215, 82,234,136,155,157,161,244,106,127, 47,178,228,251, 95,126,250,106, 64,
-237,154,170,202, 85,106, 66,200,201,192,189,132, 4,108,138,207,204, 51,136,116,205,206, 48,122,190,188, 6,139,231,121, 28, 59,
-118, 76,216,182,109,155, 1,192, 47,153,153,153, 51, 67, 66, 66,114,203, 80,121,115,131, 7, 15,206, 77, 75, 75,219, 23, 31, 31,
- 63, 42, 52, 52, 84,223,172, 89, 51,174, 95,191,126,185,169,169,169,135, 8, 33, 95, 94,187,118, 45,191,105,211,166, 40,203,131,
-173, 9, 33,144,201,100, 32,132,224,250,245,235, 17,190,190,190, 1, 87,175, 94, 93,242,244,233,211, 15, 41,165,220,141, 27, 55,
- 98,252,253,253, 27, 94,190,124,121,209,163, 71,143, 62, 18, 69,145, 51, 87,151,227,184, 63, 68,170, 8, 33, 47, 76, 93, 89, 71,
- 17,222,184,113,227,161,175,175,175,255,213,171, 87,215, 12, 29, 58,180, 45, 0,245,213,171, 87, 31,215,174, 93,187,254,213,171,
- 87,215, 12, 26, 52,168, 93, 97,184,218,108,131,213,189,123,247,188,204,204,204, 19,217,217,217,195,238,221,187,151,231,239,239,
-143,238,221,187,231,101,100,100,156,204,200,200, 24, 86,150, 60,162,148,206,191,120,241,226, 44, 74,169, 68,165, 82, 29,185,115,
-231, 78,219,188,188, 60, 53,165, 20, 68,120,158,197,233, 27,238, 18,136,132,163, 18,190, 51, 8,170,130,199, 52,153, 92,205, 66,
-231,175, 67, 97,202, 6, 33,241,189, 90,219, 41,150,173,252, 69,250, 73, 87, 79,165, 95,141, 74, 5,230, 74,102,139, 27, 15, 51,
- 48,125,241, 78,113,238, 80,251, 8,136, 52, 6, 6,250,180, 84, 77, 43, 62, 27,249, 98,242,224,246,114,197,188,159,191,170,220,
-164,243, 55,138,154,126,129, 47,140,208,163,144,155, 88, 58,111,148, 56,119,136, 77, 4, 68,196, 67,143, 39,101, 56, 71,251,207,
-155, 55,111,239, 39,159,124,162,169, 85,171,214, 11,205,240,240,112,252,240,195, 15, 90,157, 78,215,215,220,179, 18,210, 26,117,
- 4, 19,117,216,122, 34,213,123,204,200,225,106, 21,151, 6, 60, 95, 88, 96, 94,164,214,168, 87,203, 30,211,190,116,150,142, 93,
-112,160,198,197,101,158, 57, 16,229,213, 1,196,155,117,183,201,113,187,231,204,153,163, 86,169, 84,120,250,244, 41,138,154,141,
-252,253,253,177,116,233, 82,245,136, 17, 35,246,182,108,217,210,241,236,217,179,166,178,152,172,160, 26,164,213,183,171, 66,207,
-252, 48,218,198,169, 78,117, 7,164,100, 3,159, 77, 63,144,145,154,163,235, 95, 22,115, 85,220,100, 17, 66,186,142, 30, 61,250,
-192,198,141, 27,237,106,214,172,137,232,232,104,244,233,211, 39, 45, 37, 37,165,195,223,192, 92, 1, 64, 46, 0, 87, 0, 79, 81,
-208, 23, 41,140, 16, 34,199, 91, 60,158,237,225,195,135,119, 34, 35, 35,157, 63,253,244, 83,100,101,101,217,244,238,221, 27, 97,
- 97, 97,120,242,228,201,221,183, 73,232,245,235,215,215, 55,106,212,232,202,134, 13, 27,198,114, 28,215, 36, 63, 63,223, 1,128,
-120,252,248,241, 4, 65, 16, 46,104,181,218,229, 55,111,222,124, 90,198, 60,162, 0, 82, 11, 95, 79, 89,165,245, 78,184,241, 23,
-109, 91,110,204, 42,236, 91,195,232,236,158, 94,228,236,186,171,215,167, 25, 40,173, 11, 0, 50,142,220,207, 33,116,230,239, 97,
-244,226, 27,204,196, 27,159,182, 29, 30, 30,142,101,203,150,229,229,228,228,220, 51,153, 76, 95, 92,187,118, 45,212, 12,131,242,
-146,166, 68, 34,185, 26, 29, 29,189,229,230,205,155,187,139, 47,139,137,137,217,118,253,250,245,223,139, 45,139,110,213,170,149,
- 27, 33, 36,213,156,116, 18, 66, 18,186,117,235,198,243, 60, 31, 11, 0, 33, 33, 33, 6, 0, 95, 6, 4, 4, 28,179,176,176,248,
- 24, 0,130,131,131,141, 0, 70, 5, 6, 6,158,208,104, 52,159,152,179,239,132, 16,240, 60, 95, 98, 4, 11,192, 27, 59,185,191,
-233,120, 22, 26,158,126, 1, 1, 1,159,168,213,234,254, 0,112,239,222,189, 60, 0,253, 3, 2, 2, 62, 86,171,213, 3,204,213,
- 84,171,213,215, 18, 19, 19,183,220,184,113, 99,227, 43,203,182,154, 19,181,122, 85,243,198,141, 27,171, 0,172, 42,250,220,176,
- 97,195,250,207,158, 61, 59, 34,138,162, 74,146,250, 60,239,246,161,142, 73,254,195,206,120, 10, 28,213,128,208,169, 38,142,164,
-221, 94,220, 72, 87,150,178, 84, 30,254,111, 53, 43,112, 81, 72, 37, 75,189, 93,149, 99,135,118,181, 35,243,119, 60,175, 60,178,
-191,179,188,126, 93, 91, 92, 11, 73,199,184, 89, 91,197,121,195, 28,158, 55,241,181,136,128,136, 85, 16,242,147, 75,213,180, 48,
- 70, 65,103, 92, 92,205, 67, 49,118,236, 7, 34,153,182,121,118, 21,165,114,150,172, 65,195,150,120,248,224, 58,230,207, 24, 38,
-206, 31,102,243,188, 73, 77,203,104, 16,238, 71, 8,186,100,115,247,253,198,141, 27, 87, 2, 2, 2,186,111,220,184,113,239,232,
-209,163, 53,181,107,215, 70,120,120, 56,102,206,156,169,205,203,203,251,240,246,237,219,231,205,222,119, 74, 40, 64, 33, 10, 16,
- 38,204,248, 81,175,213, 11, 68,107,160, 68,167, 7,167,205, 23, 73,142, 94, 36, 70,163, 72,220, 28,212, 5, 17, 13,238,143, 55,
- 62,175, 75, 39,199,113,153,163, 71,143,182,120,173,175, 85, 40,114,203,147,239, 47, 76,214,178,224, 51,227, 63,147, 57, 45,223,
-118, 51, 61, 37, 75, 55,160, 52,115,245, 38,205, 34,147,245,201, 39,159, 28, 88,176, 96,129,221,196,137, 19, 83,147,146,146, 58,
-150,102,174,254,135,101,254, 46, 10,230,182,186, 70, 41,189, 64, 8,209,160, 96, 14,162, 7,229,213, 20, 4, 97,241,240,225,195,
-219,205,153, 51, 71, 50,125,250,116,132,134,134,226,251,239,191, 23, 76, 38,211,130,183, 61, 55,175, 94,189,250, 24,192,103,255,
-154, 58,228,111,170,249, 79,131,148, 37,170,243,174, 50,192,223,223, 63,175,125,251,246,218,115,231,206,229,234,116,186,145,183,
-110,221, 58,244,111, 41,124,173, 91,183, 62,205,243,124, 21, 66, 8, 40,165,241, 39, 78,156, 8, 2,128, 86,173, 90,157,150, 72,
- 36, 85, 10,239,248,227, 79,157, 58, 21,244, 79, 62,241, 26, 52,104, 80, 23,192,108,157, 78,215, 43, 36, 36, 36,183,222,168,163,
-246, 68,203, 89, 17,158, 55, 4,175,105, 19,205, 42,157, 82, 52,143,122,203,161, 86,212, 7,232,216,123, 97,121,149,167,110, 76,
-173,210,165, 93, 99,233,166,223,207,139,243,134,191, 48, 87,139, 65,181, 55,209, 34, 34,223,108, 77, 37,215, 0,188,100,236,237,
-103,121, 21,199,173, 73,247,106,215,229, 51,254,224,238, 53,226,252, 97,118, 69,230,106, 17,132,156,235,102,107, 22, 35, 32, 32,
-160,177, 76, 38,219,219,183,111, 95,205,142, 29, 59, 74, 53, 87, 37,106, 94,246,245,128,137,206, 0,161,165,247, 1,163, 92, 24,
-140,152,135, 54, 33,209,127,135,124, 15,170, 65, 42,170, 44,148,187,114, 13,198,111,204,137, 92,153,163, 73, 8,169, 99, 99, 99,
-179, 62, 35, 35, 99,160, 57,145,171,255,229,190, 19, 66,236, 1,248, 23,222,200, 19, 0, 15, 41,165,207,223, 82, 51,136,231,249,
-175,189,189,189,253, 66, 67, 67, 67, 4, 65, 88, 66, 41,189,192,140, 11, 51, 88,204, 96, 21,210,172, 89,179, 75,162, 40,158,144,
- 74,165, 63,156, 61,123, 54,159, 21, 62,166,201, 52,203,161, 89,204,100,221,124,154, 91,101,222,142,116,143, 49, 61,173, 99, 74,
- 51, 87,165,106, 22,154,172,235,143,243, 42,205,255, 45,203,227,235, 15, 45, 98, 74, 51, 87,230,238,123, 64, 64, 64, 99,185, 92,
-190, 54, 47, 47,239,203,210,204, 85,137,154,143,124,101, 72, 53,185,130, 18, 95, 80,250,250, 71,237, 16, 62, 15,132, 11, 65, 18,
- 77, 66,207, 16, 3, 43, 75, 76,147,105, 50,131,245,191,230, 47,153,245,248,194,133, 11, 77,216,161,103, 48,222,146, 14,161,122,
- 28,245,190, 5,181, 98, 81, 3, 31,213,240,221,223,169,243, 64, 73, 44, 68,250,227,155,204,149, 25,154, 55,161, 52, 45, 10,172,
-166,250,114,207, 12,117, 30,128, 68,128, 91,241, 38,115,101, 46, 55,110,220,184, 2,192,183,220, 2, 53, 66, 12, 0, 34, 0, 18,
-137,239,222, 48, 67,246,116, 80,224, 79,188,123,100, 48, 24,140,191,163,193, 98, 48, 24,239,208,100, 61,242, 13, 70,178,116, 18,
- 8, 42, 67,106,140, 70,150, 49, 17, 29, 34,244,111,169,121, 3,201,124, 36, 40,170, 66, 98,124,142, 44,221,219,105,190,115, 40,
- 45, 48, 81, 12, 6,131,193, 12, 22,131,193,248, 51,168, 17, 98, 64, 13,196, 2,136,253, 91,107, 50, 24, 12,198,191, 8, 2,192,
-175,228,251, 67,243,219, 86, 9, 33,126,101,253, 97, 51, 58,111, 50, 77,166,201, 52,153, 38,211,100,154, 76,243, 31,166, 89,154,
-246, 63,165,111,215, 95,210,201,157,105, 50, 77,166,201, 52,153, 38,211,100,154, 76,243,159, 12,123,152, 46,131,193, 96, 48, 24,
- 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 96, 6,
-139,193, 96, 48, 24, 12, 6,227,111,195,159, 58,138,144,193, 96, 48, 24, 12, 6,227,223, 8, 7, 0,132, 16,230,178, 24, 12, 6,
-131,193, 96,252,207,249,167,122, 16,214, 68,200, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,
-131,193, 96, 48, 24,255, 78,131, 69, 8,161,172, 47, 22,131,193, 96, 48, 24,140,255, 53,255, 68, 15,194, 70, 17, 50, 24, 12, 6,
-131,193, 96,188, 99, 88, 19, 33,131,193, 96, 48, 24, 12,198,255,147,193, 34,132,248, 49, 77,166,201, 52,153, 38,211,100,154, 76,
-147,105, 50,131,197, 96, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24, 12,102,
-176, 24, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96,252, 69, 16, 0, 37,142, 4,160,148,222, 55, 91,164, 28,
-163, 9, 74,211,103,154, 76,147,105, 50, 77,166,201, 52,153,230, 63, 79,179, 52,237,178,248,143,191,181,193,250, 51, 39, 26, 37,
-132,248,189,235, 3,197, 52,153, 38,211,100,154, 76,147,105, 50,205,127,158,230, 63, 13,214, 68,200, 96, 48, 24, 12, 6,131,241,
-142,145,252,211,118,200,215,183,151, 44, 83, 74,223,183,181,181, 26, 11, 74,145,158,145,189,200,218, 72,246,135,132,236, 52,252,
- 89,191, 73, 8, 33, 0, 64,255,161,207, 29, 34,132, 40,107,213,170, 21, 0, 0, 15, 30, 60,184, 65, 41,213,189,237,241,114,240,
-237,241,181,165,149,106,128,201, 40, 80,157, 54,127, 67,226,131, 61,203,217,233,248,239,192,202,183,189,173, 74,102,201, 39,220,
-222,153,194,142, 6,131,193, 96, 6,171,144,138,126,253,108,242,137, 97, 50, 47,225,187, 83, 42, 90, 36,220,222,233,240,119,216,
- 17,199, 90,221, 61,109,108, 45, 71,214,106, 84,163,103,191, 15,219, 43,107,215,242,145,231, 27, 76,216,127,248,252,143,191,237,
- 63,190,208,167,249,160,189, 25,233,217, 43,146, 30,236,125,254,142,205,135, 98,242, 39,213,222,179,179, 80,200, 9, 33,123, 40,
-165,166,146,214,115,170,223,239, 52, 1,169, 82,176, 13, 7,194, 1, 4, 52, 62,246,198,150,160, 18, 52,213, 0,156, 1, 68,190,
- 78,175, 36, 84,174,181,220,101,156,124, 58,151,135,177,233,233,193, 89,239, 96,223, 28,189,189,189,131,170, 85,171,230, 56, 98,
-196, 8, 41, 0, 44, 94,188,184, 70,213,170, 85,147, 66, 67, 67, 47, 83, 74,147,202,149, 87,190,221, 38, 76, 29,255,249,148,247,
-219, 55, 69,122,142, 17, 43,214,255, 54,215,201,175, 7,159,120,127,207,146,119,149, 47, 22,206, 53,107,242, 82,213,215,162,104,
-106, 79, 56,217, 41, 65,175, 93,148,155,244,224,173,195,217, 85,218, 78, 26, 7,160, 65,225,199,155,225, 39,231, 44,100,213,136,
-217,229,201,170, 78, 53, 27,223,238,117,235,253,126,241,105,174,133,131, 95,247,221,224,177, 52,249,206,222,187,230,106,184,215,
- 8,186, 44,225,120, 23, 65, 20, 98,163, 31, 93,110,250,103,164, 83,227, 84,179, 53, 8,214, 19, 74,165, 20,116, 5, 47,146,221,
-217, 41,143,195,222,246, 6,202,202,221,215, 86, 16, 13,239,201, 57,117, 93,131,168,189, 37,145,169,142,103, 68,220,201,124, 71,
-199,150, 87, 59,249,244, 87, 42,212, 95,121,251,212,168, 26, 30,254,236, 89,110,118,230,242,188,196,167,155, 40,165, 98, 89,180,
-188,218, 76,252, 72,128, 56, 81, 52,233, 57, 9, 37,243,159,159, 95,178,141,149, 94, 6,227, 79, 54, 88, 14,190,189, 52, 68, 66,
-111, 52, 15,106,100, 55,233,203, 30,242,165, 91,207,195,185,238, 71,161, 9,119,126,243,254, 43,119,194,165,222, 7, 21, 9,193,
-189, 49,195,250,226,211,143,218,145,148,108, 19,178,180, 2,136, 20,232,245, 97,103,245, 7,221, 59,168,231, 47, 91,255,217,161,
-163,103, 62,115,169,247, 65,205,248,219,187,163, 74,211,116,246,239,119, 12, 32,213,138, 62, 83,193,164, 36,188, 68, 7,160,208,
- 28,113,208,216, 56, 94,152, 54,216,231,192,140, 79,107,205,216,120, 52,114, 21,128, 10, 0, 18, 75,172, 0, 57,137,219,230,181,
-139, 29,220, 42,200,193,113, 28, 50,114,141,232, 61,120,140, 80, 66, 69,169,249,105, 92,189,110, 31,119,174,220, 71,209, 98,247,
- 20, 66,200, 61,115, 42, 72,141, 83,245, 90,114,165,213, 65,175,186,109,109,194,239,158,244,181,112,170,241, 89,174, 82, 23, 70,
- 35, 34,242,203, 90, 81,107, 52,154,106, 86, 86, 86, 13, 58,116,232,160, 26, 63,126,188,180,121,243,230, 47,190, 31, 58,116,168,
-244,252,249,243,110,243,231,207,239,225,230,230,166,205,202,202,186,153,155,155,251,148, 82, 42,152,251, 27,182,182,182, 31,127,
-208,185, 57,186,244,249, 18, 20, 28,198, 77,152,138, 35,135,143, 14, 2,240, 78, 12,150,165,171, 79, 53,143, 74,158,231,166,126,
- 55, 87,233,227, 89,145, 28,187,120,247,131, 53, 75,102,118,208, 56,214,106,243,182, 38, 75,202,147,128,121, 95,125,216,201,104,
- 2, 38, 44,251,189,212,245,157,235,247,189, 8,194,185, 21,149, 25, 66, 0,142, 0, 4, 4,148,138,177,209,215,183,188,181, 73,
- 32,132,240, 42,167,234,237, 57, 42, 14, 0, 0,145,112, 91,180,137,143,143,149, 37, 79, 0,192,169,206,135, 17, 84, 20,254,112,
-195,196,243,210,228,248, 59, 59, 43,191, 69,250,236, 59, 4, 57,249,159,251,177,101,219,198,181,108,253,214,156,200,183,242,239,
- 56, 18,177, 25,232,185,111,207,238,158, 14,126,221,207,115,160,139, 19,239,239, 59, 85,154,150, 82,161,112, 60,112,224,128, 67,
-135, 14,157,108, 28,253,186,239, 21, 9, 18, 56,138, 4, 34,114, 9,132,152, 18, 76, 28, 77, 0, 79, 18, 83,189,228, 73,238, 33,
-113,231,120,142,119, 51,137, 66,124,204,163,203, 65,230, 39, 24,235,143,158,188,104,175, 51, 82,252,240,227,182,169,121,153,137,
- 83, 35, 30,218, 71,170,157,170,143,207, 75,124,124,168, 44,251,174,114,175,227, 42, 17,117, 29, 92, 92, 61, 63, 28, 57,250,219,
-192,118,173,155, 75, 61, 61,156,200,243,232, 68,122,226,244,121,131, 79, 96,199,171,241,177,225,187, 69,163,228, 72,110,114, 72,
- 98,249,142,111, 75,137,133, 99,141, 13, 93, 63,250,180,199,251, 31,244,133,141,149, 5,244,134,252,170,103, 78, 28, 94,249,243,
-202,121,141, 9, 33, 67,203, 98, 14, 5,106,154,248,243,220, 47,189, 1, 17,131, 70,205,154, 76, 8,217, 81, 86,147,198, 96, 48,
-202,104,176, 8,111,154,214,184, 97, 35,187,175, 70, 12,150, 15, 95,126, 22, 81,215,143,104,223,149,185,210, 56,214,114,148,200,
- 36, 3, 57,142,183, 33,224,148,162, 32, 68,103,146,228,159,104, 76, 76,169,205, 81,241,183,119, 71, 57,215,235, 22,176,108,205,
-175,211,110,222, 9,105, 62,124, 80, 15,141,187,155, 43,103, 52, 81, 92,190,121, 79, 88,185,118,123, 86, 90,122,214,101, 34,161,
- 51,205, 49, 87, 0, 64, 41,188, 22, 45,252,193,193,173,130, 2,153,121, 38,124,249,245, 84,204,159, 61,221,162,162,163, 18, 58,
-189,136, 85, 71, 99,146,125,211, 23, 6,207,232, 81,107,198,254, 75,241,235, 7,207,186,121, 23, 64,222, 27, 13,170,181, 28, 35,
-127,122, 2,149, 82, 2,107,181, 12, 60,225,254, 96,174, 86,127, 91,239,253,161,239,123, 78,154,179,233,209, 70, 0, 82, 0,114,
- 0,186, 55, 71,107,124, 91,170,173, 42,108,237,248,201, 76,107,181,181, 19,250,247,236,232,123,225,248,174, 19,209,209, 17,240,
-168,217, 84,103, 50,137,167,179,179,210, 87,228, 38, 62,126, 80,218,126, 87,174, 92,185,111,231,206,157, 53,223,126,251,173,212,
-205,205, 13,191,237, 63,237,214,230,195,209,237, 98, 19, 83,157, 1,192,205,169, 66,194,144, 1, 93, 79, 28, 57,114, 36, 54, 54,
- 54,214,106,238,220,185, 77,119,239,222, 93, 7,192,118,115,243,154, 82, 17, 38,129, 66, 16, 41, 68, 42, 34, 53, 91, 95, 46, 83,
-241, 90, 3, 65, 84,147,191,157, 56, 67,149,160,181,196,143,107,159,192,223,203,145,116,236, 51, 82,181, 99,205,188,177, 0, 6,
-189,109,180, 74,103, 4, 22,158, 50,211,183, 18,206,109,237,170, 37, 14, 21, 44,101,224, 9, 1, 47,225,192,115, 64,142, 78,192,
-192,207, 70,189,213, 57,163,114,173,229,206, 83,227, 32, 75,215,154,131, 62,248,160,183, 75,223, 62,189, 40,207,115,216,185,231,
- 96,151, 95,183,111, 76,176,112,241,217, 40, 16,233, 38,109,220,131, 24,179,242, 69, 20, 28, 14,252,190, 17, 21,172,100,224, 8,
-144,154, 45, 32, 60, 81,139, 81, 95, 14, 43, 87,148,154, 16, 98,243, 69,183, 42,237,239,110,110,211,194,167,162,165,247,221,103,
- 25,143, 62,249, 62,248,199,227, 49,213, 27,205, 88, 80, 3,121,186,124, 12,255,122, 10, 82,226, 34,154, 31, 59,188,191,121,133,
-234,237,159, 18,125,214,244,148,240,171, 7, 95,167,169,211,233, 50, 58,118,232,108,229,236,236,168, 90,191,110,109,187,180, 76,
- 45,210, 50,178,145,156,150,133,148,212,116,196, 39,166, 32, 54, 46, 30, 49,209,177, 98, 26,159,140,163, 71, 15,115, 93,187,118,
- 21,202,154,118,173, 65,196,157,231, 57,168,228,211, 0,118,142,238, 8,120,239,147, 74,119,206,237,248,205,194,185,230,194,156,
-132,135,211,205, 50,250,142, 62, 63,244,238,247,201,144,222, 61,123, 72,170,123,187,115, 9,201, 25,244,210,213,224,244,165,139,
-151, 61,108,210,162,101,205,174, 29,219,218, 14,251,184, 87,139,199,161, 49,205,182,255,190,119,145,133, 67,245, 45, 57,201,143,
- 71,149,245, 60, 80, 59, 85, 95,223,234,253, 79,122,248, 53,108,135,208,208, 80, 60, 11,185,137,150,109, 58,160, 67,231, 15,160,
-207,215,245,221,180,110,105, 48,128, 53, 37,110,239,239, 47,181,201,176, 81,189, 84, 23,187,250, 72, 0, 10, 74, 41, 76,218, 76,
-153,198,169,174,157,173,103, 91, 3, 0,100,216,100,104,105,112,176,145, 93, 58, 25,140,119,108,176, 56, 94,222,113,204,224, 78,
-242, 9,171,175, 32,234,250,175,218,132,219,191,217, 23,125,231,238,223, 39, 36, 38,120,135,239,203, 23,210,210, 71, 24, 16,226,
- 47,181,113,195,215,142, 46, 46,195,250,127, 58,146,175,228,238,196,229,232, 76,166,196,184, 24,122,244,192,246, 47,172, 43,214,
-253, 33, 51,234,206,207,175,211, 36,222, 29,229, 52,244,136, 62,225,246,190, 71, 0,122, 59,214,234,235,120,233,250,253,113,182,
- 54, 86,189, 76,130, 9,217,217,121, 59, 51, 50,140, 11,147, 30,108, 79, 42, 86, 41,145,226,119,116,175, 75,167,173,133, 12, 95,
-175,127, 10,157, 94, 0,165, 20, 14, 54,114,204,219, 21, 9, 9, 79,146,107,101, 44, 92, 60,179,135, 97,232,111,151,244, 59, 39,
-239,241,104, 2, 92, 94, 79, 41,205,121,109, 58, 1,240, 28,160, 81, 73,161, 81, 74, 96,169,146,162,160,231,214,127,205,213,143,
- 99,235,188, 63,236,125,207,201,115,183, 62,222, 48,101,237,195,203, 0, 66,139,247,119, 42, 41,157, 86, 46,126,253,108, 29,220,
- 22,118, 27, 58,203, 50, 34,157,131,212, 4,216,187,122,146,233, 51,102, 89, 41,229, 28, 84, 82,106,117,239,241,243,126, 95,126,
-249, 85,103,181,107,141,206,121,113,143,110,191, 41,143,180, 90,173, 98,192,128, 1, 82,157, 78,103,248,116,204,188,102, 17,209,
-137,239,205,158, 62, 78, 81,209,205, 17,130, 72,113,255, 73,180,247,140,217,139,220, 15,157,184,122,180, 87,251,218,199, 93, 92,
- 92,108,180, 90,173, 88,150,124,207,204,204,218,182,117,207,201,241,203, 22, 47, 64, 68, 98, 46,182,110,255, 29,130, 32,110,122,
-179, 41,123, 89,115,198,140, 25,206,126,126,126,178, 7, 15, 30, 36, 82, 74,181,175,172,221,177, 82,165,138,216,176, 35, 18,105,
-217, 70, 60, 79,200, 71,147,234,190,132,138,134, 54,101, 44,159, 13,198,125, 53,188,179, 72,129,197,203,126, 42, 48, 92, 4,254,
- 83,150,239, 4, 8, 73, 2,112,179,180,116, 18, 14,176,183,148, 97,206,239, 17, 80,201, 37, 80,201,121,168, 20, 5,127, 9,136,
-153,134,244,143,233,212, 56, 87, 31, 91,167, 86,221, 25,159,125,246, 41,215, 36,168, 33,229,121, 9, 18, 51,141,132, 35,192, 87,
- 35,134, 99,228, 23, 67,157,194,194,163, 38,174,254,105,205,120, 11,167, 26,243,114, 18, 31,205, 54,103,223, 43, 88,202, 48,109,
-107, 56, 84,138,130,116,214,171, 98, 97,118,253,240,170,166,107,157, 78,135,207, 36, 73,125,178, 15,233,174, 63,123,122,123,254,
-141,123,145, 55, 41,165,233,142,126,221,161, 55, 81,228,104,141,120, 16,101,130,168,147,162,123,135, 0,212,177,177,175,182,108,
-211,153,117,132, 16,167,162,243,243, 85,205,152,199, 87, 26,216,250,247,178,162,185,234,123, 11,246, 68,216, 87,114,178,130,179,
-173, 37, 28, 92, 43,160, 70, 13, 31,216,106,164,176, 82,241, 80,201,121,174, 69,135, 94,104,223,190,163, 86, 16, 77, 73,101,201,
-119, 66,201,224, 15, 58, 53,223, 68, 0, 25,199,203,226, 92, 42, 85,245, 8,236,240,153,178, 65,187, 79, 96,212,235,198, 90, 56,
-251,158,203, 73, 8, 57, 91,154,166,141,131,235,192,193,159, 14,149,121, 58, 41,112,250,220, 21,211,164,201,147,239,103,230,164,
- 47,202,137,127, 22,114,234,244,113,103,107, 91,187,201,147,166,206,106,220, 58,168, 30,223,182,115, 31,217,209,163,199,123, 2,
- 24, 85, 90, 58, 9, 33,156,202,177,234,224,170, 53,234,140,249,124,234,154, 74,177,169,122,216,186, 86,195,189,219, 55,113,116,
-231,138, 59,249, 57,153,203,142, 31,218, 53,102,250,156,229,181, 59,119,235,141,131,123,119,140, 34,132,172,165, 5,188,208,180,
-171,218,162,109,237, 74,126,235,157,171, 59,218, 21,215, 23, 41,143, 25,243,150, 67,151,147,142,202,174, 54,206,150, 53,189, 35,
- 41, 71, 64, 69, 32, 57, 57, 65,111,239,211,226,131,148, 39,231,206,150,165,158, 47, 43, 76,243,223,169, 89, 10, 1, 0, 28, 0,
- 36, 3,184,241,202,103, 20,190, 71, 9,159, 83, 10, 47,193, 21, 0,232, 11,131, 22, 69, 20,125,126,221,242,162,237, 67, 0,212,
- 44,212, 20, 0, 92, 7,144, 94,170,193, 42,244, 26,164,216,201,251,210,231,151,239,112,141,110, 14, 78,206, 16,104,228, 75,151,
-134, 74,129,125, 83, 70, 15,237,165,114,169,215, 51, 57,254,246,239,102,223,237,170,220,171,185,218, 84,180, 58, 60,226,171,111,
-173,191,248,184,171,197,163,232,188,236,144,200,188, 44,168, 40,108, 61, 42, 72,252,218, 59, 8, 73,191, 45,156,108,237, 86, 59,
- 35, 51,246,222,174,146, 52, 28,173,236, 66,220, 27,125,154,174,207,203,253, 46,229,193,206,163,133,253,130,190,113,111,220,107,
- 26, 0,196, 92,217,249,194,160, 56,214,235,209, 72,161,176,153,225,218,160,127, 5, 0,245, 75, 75, 95, 90,142, 1,130, 80,224,
-195, 56,142, 32, 87, 39, 64, 41,227, 82,124, 82, 23,188, 48, 87,151,232,144,143,141,116,135,172,184,185, 42,185, 82, 4,210,178,
-141,208, 40, 37,176, 80, 74, 96,161,146,128, 43,116, 88,132, 16,205,138, 49,117,186,126,222,195,123,242,188, 45, 79, 54, 78,254,
- 41,228, 50,128, 39,148,210,140, 55,105, 90, 57,213,104, 40,183,182, 95,252,217,183, 75, 52, 23,159,228,194,213, 78, 14,191, 74,
- 86,176, 86,203, 17,155, 86,208,167, 63, 46, 85, 7,157,193, 18,221,135,204,176, 58,178,115,229,121, 91,247, 58,155,210, 99,238,
-142, 40,109,223,119, 31, 58, 95,229,121, 84,194,123,191,253,178, 80,145,150, 7, 68,166,137, 72,203,214, 67,207,219, 98,202,244,
-153,138, 9, 19,198,119, 64,126,106,108,213, 74,118,241,101, 62, 49, 73,222,162,157,123,142,127,227,231,223,156, 59,123,230, 12,
-238,222,188,176, 51,249,254,222, 50, 53, 15, 86,172, 88,209,180,124,249,114,235,165, 75,151,182,176,181,181,141, 78, 79, 79, 15,
- 41, 60,150,238, 21, 42,250, 37, 30, 61,115,163, 82,157,202,158, 36, 58, 85,143, 26, 30,150,120,122,255,170,200, 75,100,199,222,
-164,233, 88,235,253,233, 32,124,189,130, 68, 10,183,213, 78, 53, 97, 52, 81,172, 57, 86, 16, 0,226, 9, 23,240,205,216,225,142,
-130, 64,177, 96,201,106,179,250, 95, 17,112,224,121, 2,181, 66,130, 59,199,215,102,230,231,101, 25, 72, 97, 19,161, 72,133,216,
-114, 87, 53, 34,233,127,116,223, 22, 46, 62,195,132,167, 9,249, 36, 38, 53, 23, 28, 40, 42, 88,242, 48, 24,165,200,206, 72, 34,
- 59,118,108,199,221, 91,215, 57, 66,184,143, 1,204, 54,235, 38,138, 3,148,114, 30, 74, 57, 15,149,140, 71, 78,126,129,119,118,
-244,235,190,133, 2,153, 18, 94,146, 19,127,231,247, 73,102,157,223,106,155,218,155,215, 46,192,241, 11,193,205,206,134,110,170,
-239, 84,171,246,234,138,126,253,150, 2,128,193, 36, 34, 47, 39, 19, 26, 99, 36,154, 85, 78, 65, 5,181,128, 39,233,174,184, 27,
- 35,209,148,214,156,149, 30,188, 51,203,201,247,253, 81,119, 46, 30,222, 33,105,249, 1, 50,114, 5, 68, 42,244, 80, 43, 36,133,
- 47, 30, 15,239, 94, 67, 66,150,120,209, 82,175,126, 63, 50,244, 72,153, 66,164, 57,137, 33,103, 0,184,255, 55, 66,236,109, 31,
-191,106,236,207,189, 70,175,104, 27,208,254, 83,242,244,198,137,111, 1,156, 45, 53,130,101, 99, 39, 9, 75, 20, 16, 30,241, 92,
- 12,108,216, 88,114,245,226,233,122, 39,206, 92,222,180,101,235,214,252, 78, 31,126,172,108,211,164, 46, 31,157,170,199,242,221,
- 15,233,131,120, 74,228,154, 10, 82, 51, 34, 86,156,131,119,192, 47, 27, 55,110,235,233, 91,205, 3,137, 25, 70,196,165, 27,112,
- 62,248, 25, 54,173,157,144,153,145, 20, 54, 24,250,156, 92, 17, 66,230,169,227,251,247, 13, 31, 57, 1,190,126,245, 42,229,196,
-229, 90, 2,120,185, 95,166, 40,126, 50,123,246, 15,118, 26,141,230, 15,191,147,156, 24,135,220,156, 92,200,213, 86, 80, 91, 85,
-128,201, 36,192, 40, 80,100,103,103,203, 39,142,236, 63,196,156,253,103, 48,202, 16,137, 53,199,135, 56, 16, 66, 14, 82, 74,187,
- 0,104, 11, 64, 94,236, 51, 8, 33, 7, 11,141,223, 75,159, 39, 76,152, 48,105,238,220,185, 15,138,214, 45, 90, 94,180,238,155,
-150, 23,219,190,194,196,137, 19,253,230,205,155, 55,167,113,227,198, 59, 46, 95,190,252,220, 44,131, 85,124,103, 8, 33,175,173,
-216,156,235,118,109, 0, 81,194,187, 59, 88,160, 74,101, 15,216,168, 7,169, 92,235,247, 78,150, 72,120,110,195,210,137,202,136,
- 12, 25, 36,156, 36,175, 44,230, 74,193, 91, 29, 95,253,243, 38,139,134,181,171, 40, 22,237,137, 9,143, 73,203,215,139, 38, 35,
-167,203,203,145,165, 39, 60,149,102, 37, 69, 88, 90, 57, 87,231,117, 89,201, 83, 0,148,104,176,228,114, 57,183,108,193,119,190,
-103,207, 93,218,120,192,194, 42,211,165, 94,255,197,188,194,176,169,200, 88, 17,242, 29,231, 84,247, 73, 15,185, 82, 61,190,122,
-237, 22, 46,174,213, 2,173,175, 29,217, 24,106,134, 61,231,199, 79,154,241,194, 92, 25,181,105,248, 97,237,129,236, 54,118,231,
- 22, 21,153,171,237,201,125,251,181,111, 94,205,233,200, 1, 89, 90,233, 23, 90, 83,236,128,207,190,146, 17, 14,224, 64, 10,250,
-113, 81, 49,137, 16,162, 94,254, 85,221, 46, 95,126,232, 53,101,254,214, 39,155, 38,253,244,160,200, 92,149,154,121,217,188,234,
-190, 85,190, 54, 49, 34,244,126,165,145,157,154, 72, 42, 57, 91, 67, 37,151, 32, 35,215,132,140, 60, 1, 49,201, 58,132, 37,228,
-226,126, 88, 50, 4,109, 22,250,127,249, 61,183,225,135,145,239,153,147, 63,135, 78, 7,183,251, 97,206, 36, 69, 90, 46,144,146,
- 35, 32, 46, 77,135,216, 20, 45, 98, 82,180, 80,201,128,198,237,250, 40, 46, 30,222,208,190,106, 37,187, 95,202,122, 50, 37,222,
- 59,158,231,232,215,253, 90,108,124,114, 99,239,106,190,224, 14,239,171, 81,161, 78, 47,215,212,187, 59,227,204,213, 56,114,228,
- 72,138,187,187,187,227,234,213,171,147, 23, 47, 94,236, 87,177, 98,197, 26,209,209,209,251,237,237,237, 7,125, 51,242,211,139,
-171,126, 89,236,218,234,253, 79, 37,117,170,250,113,161, 15,206,136,199,119,255,172,213,107,115, 23,191, 57,147,248,122,209, 55,
-119,180, 1, 0,175,150,163, 42,129,192, 98,217,202,159,138,206,248, 6, 32,128,201, 68,177,243, 82, 98, 25, 42, 14, 64,194,113,
- 80, 43, 36,200,207,203, 50, 68, 94,221, 84,249, 29,213, 73, 84,164, 20,193, 97,121,200,203, 55, 65,111, 20,225,110, 39, 65, 90,
- 82, 52,214, 44,219,140,144,123, 55, 16,208,172, 51,190, 91,178, 9, 19, 70,244, 49,123,212, 39, 71, 72,161,185,146, 64, 41,231,
-145,111, 44,168, 18,150,205,157,192,215,242,173,137,150, 93, 6,152, 29,210,178,180, 80, 33, 91,107,128,198,198, 5,193,167, 54,
-169, 15,157,186, 62,238,135,229,191,124,149,159, 77, 17,243,228, 10, 26,219,166,194,219, 94,143,235, 81,150, 56, 30, 85, 9,213,
-188, 60,193, 73,246,154, 87,134, 66,246, 31,112,172,219, 99,127, 86,205,122,239,219,122,249, 64, 33,227,161,144,113,144,203, 56,
-132, 61,121,128, 95,183,108,124,100, 82,170,123,133,222,219,171,127,219, 3,157,147, 16,154,162,116,242, 25,243,236,214,241,144,
- 38,239,127, 1, 27,231, 74,181,203,178,253,220, 89,147,243, 5,147,209,216,111,208,112,117,215,142,173, 36,141,155, 4,105,110,
- 62, 73,199,252, 13,103,132,139, 71,183,196,203, 20,214, 42,183,160, 97,118,230,152, 43,187, 74,245,126,222,188,229,183,158,158,
- 21,157,113,226,122, 56,110,133,102,192,202,210, 26, 18,141, 11,124, 90,124, 98,125,255,232,210,238,121, 41, 57,219,164, 82,229,
-199, 13, 26, 54, 5,165, 20, 79, 67, 66,210, 51, 50, 44,254, 80, 55,115, 18,238,231,169, 83,190,105,239,232,224, 84,252,206, 29,
- 94,222,213,208,233,253,158, 56,117,118, 39,158,135, 62,133, 72, 41, 68, 10, 80, 74,145,154,146,156, 6,142,219,192, 44, 1,227,
-207, 50, 89,111,242, 33, 69,198,233, 85, 67,244,170,209, 42,122, 95,180,222,220,185,115,187,188, 18,125,235,242,154,168,220, 31,
-214, 43,218,126,222,188,121,115,138,125,111,150,215,145, 20,138,144, 55,237,156, 99,221,110,141,229, 82,139,253, 63, 46,252,138,
- 75,202, 52, 66, 37,231,161,169,232,137,170,131,191, 82,247,107,230,128,184,124, 91, 28, 56,248, 75,182,145,154,142,152,107,174,
-228,156,197,177, 69, 43,127,145,121, 87,118, 37, 51,182, 71,132,234,140, 5,221, 36,244,249, 58, 73,228,221,163,234,152,144, 83,
- 58,152,140,155,121,185,194, 31, 84,116,124,147, 94, 37,103, 27, 4,181,104,171,110,209,162,133,250,248,153, 75,179, 14, 29, 58,
-244, 5, 10,103,168,119,241, 15, 63,229,223,164,147,175,171, 87,109,117,182,158, 64, 46,229,204,205,109,225,135, 57, 51, 80,209,
- 81, 9,173, 94,196,247, 63, 29,206,110, 97,113, 98, 78,113,115,229,228, 94,213, 93,166,208,188,212,212,247, 58, 98,111,108,107,
- 93, 66, 65, 81, 47,249,202,175,235,136, 94, 94, 83,126,216,250,100,243,196,213, 15, 46, 1,120,108,142,185, 2, 0, 26, 23,172,
-181,174,232,215, 98,255,198,133, 83, 14,111, 95,214,146, 3,181,171,225, 83, 77,210,174,221,123,138,186, 1, 65,138,228, 76,138,
-135,225,201,208,229,164,163, 77,227, 26, 56,186,103,139,144,152, 16,109, 86, 31,143,228,244, 44,231, 74,110, 78, 8, 79, 17, 17,
-149, 92, 96,172, 98,146,243, 16,155,170, 69,122,142, 30, 1,158, 78,200,205,213, 59,151,251,100,162,228,224,149, 43, 87, 26, 55,
-106,222, 14, 31,246, 27,230,123,112,247,150,235, 78,181, 62, 24,155,248, 96,247,111,230,108,191,115,231, 78,193,213,213, 53, 52,
- 49, 49,177,233,130, 5, 11,146,125,124,124, 60,102,204,152, 49,201,213,213,213,238,155,177,163, 34, 26, 53,106,180,253,135, 21,
-235,131,246,109, 93, 92, 17,192, 49,163, 33,111, 70, 78,194,147,167,102,156,228, 72, 78, 78, 6, 47, 83, 88,141, 27, 61,220,222,
- 82, 37, 1,199, 1, 25,185,130,227,162,101,171,147, 22, 46, 93,125, 8, 4, 13, 64,208,160, 74,219, 73,191,161,148,145,132, 28,
- 33,224,121, 64,163,148,188, 40, 39,142,117, 62,140, 64, 9,157,201, 11, 60, 30,159,156,120,103, 87,101, 51, 14,160,104, 18, 40,
-116, 6, 1,249, 6, 1, 60,161,200,206, 72,198,236,169, 99, 17,212,186, 27,190,233,245, 57,178,242,121, 60,142, 23, 96, 50,154,
-136,185,249, 18,155,166, 71,199,250,118, 72,201, 54, 33, 61, 87,128, 76, 82,112,190, 28,186,149,138,208,220,204,178, 5,217, 68,
- 10,123, 59,107,168, 83,129, 78, 95,239, 65,171,250,238, 56,179,111,173,228,210,245,123,248,126,254, 10, 56,118,107,132,245,119,
-188,161,176,242,128,194, 90, 1, 35, 45,219,180,124,212, 40,249,250,246,185, 61,173,189,189,198,107,228, 82, 25,228, 82, 30,241,
-209,207,177,101,227,154, 88,147, 20, 93,211,174,109,205,126, 87,149,191,148,227,221,172,237, 28,160,144,114,160, 38,125,110, 89,
-183, 79,136, 75,172,189, 96,214,248, 65, 23,174,246,152, 20,216,113,184,252,236,158,101,249, 33,215, 15,126,153, 27,111,177,219,
-171,169,253, 77, 0,118,165,148, 75, 98,237,226,183,230,167,245, 91,123,187, 56, 59, 98,207,169,187,216,184,238, 71,184,213,106,
-143,208, 91,199,225,225,223, 13, 22,158,173, 33,181,220, 57, 88,195, 73,107, 13, 29, 61,185, 91,253, 6, 65,184,114,241, 52,146,
-146, 99,214, 81,250,248, 15,163,145, 83,158,156, 59, 75,252,253, 29,109,194, 98, 95,244,193,226,120,131,139, 40, 34,184,141,129,
-226,121,232, 83,220,189,117,213, 95, 20,100, 47,162,212, 25, 54, 25, 90,250,140,245,193, 98,188,123, 74,243, 33,165, 69,157,202,
-104,230, 14,150,100,178, 94, 93, 78, 8, 57, 56, 97,194,132, 73, 0,232,132, 9, 19, 38, 21,125,158, 59,119,174, 22, 64,169, 1,
- 1, 73,241,157, 43,177,217,164,110,183,198,114,137,122,255,198,229,147, 85,219,175, 11, 88,112, 36, 24,245,124,156, 32,149,242,
-208, 40,157,113,234, 65, 38, 46,159,223,159, 19,124,243,154,142,151, 10,211,204, 49, 87, 50,162, 58, 60,111,233,234, 12,223,106,
- 30,242,149,135, 19,238,232,140, 34,161,148, 72, 9, 37, 60,165,162, 85,108,200,233,154, 89, 36,165, 49,141, 53,103, 4, 28, 17,
- 13, 38,138,136, 36, 61, 8, 1,154, 52,109,161, 60,126,252,132,234,191, 23, 44,169,109,197,234,254,234,135, 81,185,144, 73, 56,
- 56,218,200, 97,238,112, 26, 7, 27, 57,230,254, 30, 1,169,132, 75,110, 97,113, 98,113,113,115,229,236, 94,213,221,210,202, 10,
-162, 72, 64, 8, 41, 79, 6,171, 23,143,242,235, 50,186, 87,181, 41,139,183, 63,219, 50, 97,213,131,139,230, 70,174,138,147, 25,
-117, 63, 3,192,216,162,207,214, 21,253,108,110,220,188,214,214,218,214,113, 65,243,143,166, 84,200,201,212,163,109, 80,129,185,
-186,123,225,183, 62,121, 9,143,142,154,171,109, 48,137,136, 76,204, 67,120, 66,222,139,232, 85, 76,138, 22, 42, 57, 15,157, 94,
-120,171,147,201, 34, 63,127,205,209,195,251, 58, 26, 5, 52,173,233,223, 2, 31, 14, 30,111,115,114,223,198, 95,156,124,223,215,
- 37,134,236, 63, 96,142, 70, 92, 92,156,214,206,206,238,106, 86, 86, 86,215,173, 91,183,166, 7, 4, 4,240, 54, 54, 54,105, 0,
- 20,132, 26, 12, 87, 79,237,142,200,201,202,250,204, 96, 48, 4,151,225, 36,135,193, 80,208,188,106, 52, 81, 44,216, 19, 9,153,
-132,123, 97, 52,138,248,126,242, 72, 71, 81, 68,231,233,115, 86,148, 26,193,202,205, 23,160, 86, 72,254, 91, 78, 68,193, 97,245,
- 79, 63,193,206,162,160, 69,136,231, 9,210,114,140,136, 79, 51, 96,198,132,145,230, 54,177, 83,147,137, 34,223, 32, 20,152, 44,
-163, 9,214,142, 21, 48,101,225, 22,196,164,234,113,234, 65, 22, 34,147,116,168,231,109, 9,136,230, 21, 80,158,151, 38,247,248,
-232,227, 63,252,190, 82,109,161,147,241, 18,104,148, 5,199,192,177,102,183, 97,132,112, 89,188, 84,154, 31,119,231,183,125,175,
- 79, 33, 32,151,203,225,238,108, 7,131, 81,192,177,107,145,232,220, 38, 16,141, 2,253, 65, 36, 50,220,204,170, 7,133,149, 5,
- 40, 79, 96, 18, 41,244,198,178,149,169,228,144,157,137,206,126,221,199,223,185,114,252,199,247, 58,127,128,244,148,120,108,254,
-121,101,150, 81, 16, 58,167,220,217,157,240,174, 42,126, 11,167,218, 14,106, 43,235, 31,252,131,218, 65,155,153,128,228,216,240,
-125,101,213,200, 77,188,147, 1, 96,181,201,160,159,196,113, 4,196,164, 71,110,252,179,189, 0, 68,160, 94,169,219,107,156,125,
-134,206, 94,178,186,175,135,135, 7,142, 94,124,136,185,147,135,223, 81,171, 45, 43, 59,217, 89, 91,139, 62,117, 17,126,255, 4,
-236, 42,103,192,218,169,154, 91,231,182,131,221, 58,116,234,129, 7,119,131,177,124,225,204,107,185,156,122,193,107,179,168,160,
-195,250,139,166, 67, 59,175, 22, 51, 27, 55,111, 7,189,209,132,192, 38,109,113,231,230,181,225,233,207, 79,142,102,151,127,198,
-255,202,100,153,185, 94,151,183,252,157, 46, 40,232,171,229, 96,110, 4,107,238,220,185, 15,230,206,157, 91, 98, 68,172, 84,131,
-245, 38,115,181, 97,217, 36,213,214,107, 38, 60,138,200,192,123, 13, 92, 16, 31, 23,139,131,219, 87,136,160,128, 92, 41, 79, 52,
-153,196,227,249, 28, 38,167, 95,223,147, 85,154,185,146, 82,197,129, 89, 11,150, 62,172, 87,179, 26,191,234,104,210,229, 60,189,
- 64, 41,136,132, 0, 82,145, 18, 9, 56,165, 70, 20,141,213, 33,216,153, 27,106,162, 38,145, 22, 30, 12,192, 32, 80, 80,136, 47,
-101,146,209, 36, 66, 16, 1,145, 2, 69,235,150,110,128, 10, 70,122,169,100,124,138, 79, 90, 65,159,171,223,139,204,149, 71, 85,
-119, 75, 75, 43, 40,101, 60,104,225,186,101, 52, 87,170,197, 95,250,117,249,170,119,181,169, 75,126,125,186,117,220,202,251, 23,
- 29,124, 58, 57, 74,148, 54,118,174,245, 6, 20, 94,237, 0, 8,162, 54,238,246,182, 83,101,209, 46, 52, 92, 59, 53,206, 62,149,
-227, 67,111, 78,107,215,169, 15,142,236,217, 92,100,174, 14,155,171, 99,111,107,149,112,243, 65,132,183,129,218, 32, 34, 33, 23,
- 49, 41, 90, 36,102, 20,248, 93, 7,107, 25, 98,162, 35,161,209,200,205,190,136, 57,251,245,248,146, 18,124, 2,138,109,137,247,
-247, 44, 9, 13, 61,162, 39,254,195,186,156, 58,178,123,222,243,176,167,195, 27,182,233,133,122, 45, 63,196,209,173, 11, 38, 0,
- 56, 96,174,110, 90, 90, 90,182,173,173,237,133,177, 99,199,190,191,126,253,250, 52, 0,146,172,172, 44,117,143, 30, 61,220, 83,
- 83, 83,199, 80, 74, 35,203,120,226,193, 96, 48, 64, 48,104, 85, 75,150, 44,126, 49, 17, 38, 39, 81, 42,167, 79, 28,229, 40, 82,
-116,254,126,254, 10, 80, 17, 56,117, 55,195, 12, 65, 49,182,223,224,209, 5,101, 68, 20, 95,244,185,178,179,144,226,203,159, 30,
- 65,243,162,223,144, 4,109,235,217,149, 41,169, 70, 65,132, 78, 47, 64,167, 23,144,167, 23,112,237, 73, 38,158,198,230, 32, 75,
-107, 68,190,161,192,172, 24, 12, 34, 0,243, 42,173,226, 83, 49, 56,214,238,190,121,229,220, 73,252,193, 91,169,144,241, 60, 44,
-213, 50, 81, 41, 47, 48,132,171, 22, 79,145,248,212,168,137,214, 29,250, 41,222, 28,193, 18,113,254,198, 83,172,248,253, 14,150,
- 78,234, 5, 9, 71, 48, 98,214,111,232,223,190, 58, 68,145, 34,254,233, 77,184, 84,111, 4,133, 92, 89, 16,189, 54,136,230,156,
- 59, 1, 40, 28, 89, 75, 41, 13, 78,184,191,119,163,123,245,230,243,159,223, 62,168,209,233, 12,162, 65,162,121, 63,249,206,129,
-208,194,117,125, 1,200, 0,228, 83, 74, 31,149,181, 18,182,114,247,181, 21, 5, 83,175,138, 94,190,223,126, 58,122,166,163,218,
-218, 30,187, 54, 45,167,144,114,219,203,148, 81,130,129, 67, 65,159,174, 76,177,176,254, 33, 28, 65, 97,218,236, 68,193,192,151,
- 22,189,242,240,107, 61,166,122, 13, 95, 92,125, 16,131,249, 83, 63,191,163, 75, 10,255, 68,111,105, 59,216,144, 19, 63,170,166,
- 95, 61, 56, 57,217, 35, 49, 62, 30, 45,186,182,199,123,237, 59,224,193,221, 96,204,158, 62,246, 26,151,151,255, 62, 77, 14,209,
-154,147, 78,219,234,205,107,213,174,215, 96,176,119,141, 58, 72, 78, 77,131,167, 79,109,248,248,213, 27,108, 91,189,249,186,244,
-199,231, 31,128,193,248,251,112, 8, 64,231, 87,141,208,171, 38,169, 88, 4,170, 36,110, 20,215, 40, 90,255,117, 6,174,120,159,
- 44, 0,102, 13, 35,151,188,234, 24,139, 62, 59,214,237,214, 88, 38, 85,237,255,101,201, 68,213,150,107, 38, 60,137,204,196,123,
- 1, 46, 72, 73, 73,197,177,223,127,206, 37,156,169,115,194,157, 3, 55,205, 61, 26, 42,247,106,174, 18, 65,186,103,242,204,153,
- 71,155, 53,108, 96, 92,125, 44,254,124,182, 17,162, 40,145, 72,249,124, 81, 66,120, 42,161, 28,149, 42, 84,106,137, 67,149, 64,
-107,132, 93,221,167,113,172, 53, 46, 47,185,194, 35, 74,207,190,113,178, 77, 83,177, 27, 95, 65,160, 40, 30,162,162, 0, 76, 2,
- 5, 45, 26,118,108, 50,207, 96,113, 4,216,124, 42, 62,185, 86,214,194, 23,230,106,107, 74,129,185,178,178,180,130, 66, 86,208,
- 17,152,154, 61, 22,236,191,230,106,193,151,126, 93,191,234, 87,109,234,178,157,161, 91,199, 46,191,127, 1,192, 83,137,210,198,
-238,151,117,139, 21,174, 21,148,224, 0,100,228, 10,232, 51,168,124, 55,142, 22, 78,213, 62,242,111,214,101, 74,235,206,189,112,
-120,215, 47,194,189, 75,187,203,100,174, 0,160, 75,107,255, 19,115,127, 88,230, 62,118,210, 52,133, 92, 74,145,173, 53, 66, 33,
-227,224,104, 45,135,157,154,195,133,163,187,243,155,249, 58, 30, 51, 71,203,174, 97,127, 75,175,138, 21,231, 78,156, 60,145,255,
-229,231,159,191,119,173,253,254,145,184,123,251,159,210,224, 53, 70, 0, 99, 29,253, 62,120,230,230,126, 99,113,197, 90,205, 97,
- 99,239, 86,219,222,231,125,139,148, 39,251,115,204, 77,107,122,122,122,116,229,202,149,159,173, 92,185,178,198,136, 17, 35,242,
- 71,140, 24,225,174,213,106,119,150,213, 92, 21,153, 2,131,193,128,135,199, 22,169,101, 50,153, 26, 0, 76, 38, 19,124, 59, 79,
- 78, 17, 41,213, 28,186,153, 6, 16,146, 52,109,206,138,162,178,255,198,115, 32,234,218,107,230,185, 34,120,201, 92, 89, 40, 37,
-208,230,151,101,170, 33, 66, 13, 38, 17, 70,147,136,124,131,128,124,189, 9, 90,189,136,124,131,248,162,248,243, 28,129,177,160,
-188,151, 57,196, 74, 41,178, 60,171, 87,135,119, 78, 38,212, 74, 14, 42,185, 20, 42,121,193, 61,207,177, 91,105,136,208,103,152,
-119, 44, 11,163, 82,249, 6, 1, 26, 69,193,253,156,222, 88, 48, 42, 55,246,209,217,109,137,161,215,123, 59,251, 4,242,238, 62,
- 65,200, 87,152,149, 76, 27, 74,233,113, 66, 72, 91, 66, 72, 27, 0,180, 98,205, 38,226,190, 61,187,209,165,115,151,188,232,187,
- 7, 85,132,144,102,133,167, 62, 40,165, 23, 9, 33,165,206,129,101,233, 82,179,169, 72,177,153, 0, 42, 80,241,161,147, 75, 69,
-117,243, 86, 93,171, 55,109,221,137,175,236,229, 3,189, 81,192,150,117, 75,233,213, 51,187,199,229,198, 63,185, 91,150, 99,233,
- 90,169, 58,226,163, 35, 71,136,144,252,128, 2, 99, 5, 90,240,148,178, 92, 11,231,170,109, 84,182, 30,111,140, 90,218,216,212,
-183,172, 29,208,210, 61, 50,197,128, 35, 71,142, 32, 47, 43,105,166, 94,159,157,135,124,186,241,244,222, 53, 31,127, 52,236, 59,
-203,192, 6,254,176,177,210,160,130,141, 21,110,221,188,140, 5,179, 38, 93,227,242,242,223, 79, 78, 14, 49,187, 57,147,163,220,
-247, 93,123, 13,230,210, 82,211,177,100,206,183, 24, 62,110, 14,218,190, 63,144,123,250,232,206,247, 0,186,177,107, 58,227,127,
- 21,185,122, 77, 36, 43,185, 88,228,233, 15,159,139,153,162,146, 62,147,194,207,250,215,104,232, 95, 49, 85,250, 87,150,235, 95,
-209,187,243, 86, 17, 44, 30,210, 3,235, 23, 79, 80,238,189,207,227,121,108, 58,222, 11,112, 65, 82,114, 50, 14,109, 91,153,107,
- 20,117,221,147,202, 96,174, 0, 64, 98, 68,199,138,238,206,227,191,232,253, 62,217,121, 47, 53, 56,142, 83, 11, 10,165,132,227,
- 37, 57,188, 84,153,199,229,104,229,188,132,242, 28, 53, 24,248,186,109,199, 92,189,101,204,173,147, 26, 21, 50,217,194, 41,165,
-178,149, 75,141,237, 89,241,143,150,150,164, 43, 8, 38, 36,166,164,193,197, 86,141,196, 12, 35,140, 2, 45, 97, 29, 10, 66, 8,
-212, 10, 30,121,185, 89, 16,133,210,187, 16,168, 45,157, 14,214,202, 90, 24, 94,100,174,182,165, 20, 52, 11, 22, 55, 87, 74, 25,
- 15,142, 16,179, 35, 88,132, 16,213, 15, 35,124,187,140,237, 91, 96,174,198, 44,189,123, 17,192, 83, 74,105,170,107,189, 1,176,
-183,148,225,203, 21, 33,208,104,100,176, 85,203, 32, 41,199,131,140, 44,156,170,125, 84,191, 89,151,117,109,123, 12,231,246,109,
-252,193,244,232,238,165,190,101, 49, 87,130, 32, 16,163,209,136,214, 77,106,199,222, 10,137, 56, 63,107,250,212,230,129,109,123,
- 43,154, 85,119, 70,158,222,132,216,168,104, 92, 56,182, 51,223,197, 86,122,174,106, 37,187,120,163,209, 88,234, 5, 60,221,195,
-144,151,159,161,211, 73, 36, 50, 77,207, 30,157,200,205,224,224,173, 78,181,186,239, 1,200, 3, 16,209, 23, 4,221,234,250,122,
- 33, 29, 20,250,124,173,206, 81, 34, 47,115,199,228,200,200,200,211,203,151, 47,175, 37,149, 74,157,142, 30, 61, 42,230,230,230,
-238, 42,231,137, 14,131,193,128,176,176, 48,240, 60, 15,142,227,192,113, 28, 4,131, 86,245,221,172, 31, 82, 0, 64, 48,228,231,
- 24,114, 18, 31, 37, 61,216,255, 93,121, 43, 20,158,227,160, 86, 72,161, 81,242,208, 40, 36, 80, 41, 36,208, 27,205,159, 40,156,
-128,134, 95,184,114,203,183, 89, 13, 95, 4,135,229,226, 97,180, 30, 58,131, 0, 10, 10, 82, 24,101,180, 86, 73,145, 20, 31, 9,
-145, 10,101, 54,154, 18, 94,146,211,254,253, 63,118,104, 87,107, 44,140,114, 5, 7,141, 76, 86,170,134, 81, 16,208,196,191, 42,
-108,157, 42, 98,194,194,221, 0,128,149, 83, 62,130,163, 21,143,237, 27, 40,146,238,239, 27,234, 88,171,251,252,232,251,103, 39,
-196,220, 61,245, 81,155,134,206,188,147, 50,221,140,211,136,116, 7, 32, 2, 56, 76, 41, 53,121,212, 8, 10,235,208,190,131,155,
- 73, 20,226, 41,165,231, 11, 87,146, 3,104, 78, 8,105,135, 82,230,145, 43,200,119,242, 75,240,141,235, 14, 6, 19,197,169, 75,
-119, 2,155, 54,170, 7,189,145, 34, 55,223,128, 91,193,119,176,111,215,150,188, 71,247,111,124,146,151,240,196,236,115, 41, 49,
- 58,226,100, 76,196,211,206, 3,134, 79, 82,212,111,220,102,200,254, 29,171, 63,162,133, 33, 44, 66,128,202,141, 6, 92,119,174,
-221,189,186,196,194,153,131, 33,131,230, 38,133, 95, 41, 73, 39, 35,195, 34,239, 73,200,237,140,231, 9,122, 27,137, 77, 85, 72,
-101, 22,159, 18,107,247, 31,121,133,122,146, 91,163,143, 45,207, 94,186,138,144,219, 23,225,106,175, 65,120,216,211,188,144,187,
- 55,127,206,133,108, 14, 77, 14, 49,123,208,145,131,111, 75,167,106,213,107,183,182,180,113,192,238,237, 63, 35, 51, 61,117,201,
-233,163,187,199,180,233, 58, 8, 30, 94,190,173, 29,124, 91, 58, 37,135,156, 77, 4,131,241,215,113,163,148,207,239, 66,243,157,
- 34,121,253,133,214,164,180,119,174,132, 93, 95, 12,194,180,185, 43,112,239,113, 36,142,236,248,177,208, 92,237,187, 98,166,161,
-120,241,180,237,236,196,167, 47,230,178, 26, 28, 84, 1,131, 95,220, 83,218,151,188,241,228, 45,113, 0, 14,191, 73, 19, 0,242,
-115,179,250,141,249,246,187, 85, 77, 26, 5,184, 53,107,211,222,210, 36, 40, 65, 95,105, 18,161, 0, 28, 52, 20,207,239,158,204,
- 72,142,121,244, 68,212,166,127,249, 38, 77, 66,136, 98,218, 96,159, 75, 51,122,212,154,241,251, 37,253,206,115,194,103, 31,183,
- 9,170,234, 36, 85, 88, 20, 94,190, 72,193, 63,142, 64, 46,231, 75,116, 23, 37,105,206,251,210,183,243,184,190,213,167, 45,255,
- 61,116, 91,161,185,122, 66, 41, 77, 45, 90, 71,198,243,176,210,200, 96,165,150,193, 86, 35, 45, 85,243, 15, 23, 63,231, 26, 29,
- 27, 20,153,171, 77,230,153,171, 18,210,121,179, 71,143, 30,245, 62,255,252,115,249,216, 33, 93,206,157,187, 26, 18,246,235,209,
-223,218,165,165,102, 57, 11,130, 0,141, 70,158, 16, 84,195,254, 68,181, 74,118,177,247,238,221, 19, 79,157, 58,149, 47, 8,194,
-173, 55,105,210,157, 59, 5,251,218,221,119,223,188,125,111, 80,253,186,181,176,106,197,162, 26, 79,195, 34,106,132, 62,143,130,
-155,155, 27,220,220,220,144,101, 82, 35,236,218,125,228,101,167, 30,136, 8,217,103, 40,235,190, 83, 74, 77,132,144, 77, 83,167,
- 78,157,156,150,150, 54,223,156,153,167, 75,210, 44, 50, 88, 69,198,170,200,100,133, 28, 93,168,150,201,100,106, 66, 8, 76, 38,
-147,189,103,227,129,245,204,213, 44,209,116,230, 20, 76,217,161, 41,156,111, 74,163,144,192, 32,152,159, 78,169, 65, 61,124,244,
-151, 67,158,215,242,243,255,242,163,143,135,203, 2,171, 85,198,141,103, 89,176,179,144,194,217, 86,142,148,228, 84,220,220,187,
-216,148, 17,115,239,103, 78,138,185,101, 77,103,241,169, 24, 28,107,246, 24,190,106,241, 36,254,216,173, 52,200, 21, 28, 52,114,
-133,168, 86,243,165,166, 51, 61, 35,251,202,194,229, 63, 55, 30,216,167, 27, 58, 54,174,140, 11,119, 99, 33,210,130,166,122, 65,
- 44,200,158,228,144,125,250, 81,125, 60, 47, 13,123,191,154, 99,166, 54,185,234,180, 8,195, 53, 66, 8, 87,148,127,127, 40, 75,
-148, 30, 35,132,240, 0, 2, 1,180, 35,132, 92,160,148, 54,125, 37, 29, 30, 0,106, 1, 8, 47,188,129, 17,205,216,119, 98, 48,
- 81,132, 39,106,113,249,242, 37,232,242,178, 16, 26,250, 12, 39,142,236,189,153,157,153,186, 81,105,162,187,243, 82,158,228,148,
-165, 44,105,197,156,177, 11,167, 12, 21,253,155,183,111,223,233,131,193,242,241,179,215,217,132,134, 62, 19, 68, 17,208,120,117,
-148,187,121,105,106,114,212, 64, 83, 31,237,215, 71,221, 58,112, 82,224,184,113, 37,105, 82,122,214,100,225, 92,253,231, 75,151,
-206,125,171,116,245, 71,141,206,147, 58,199,222,217,223,217,217,183, 61,236,189,131, 16,119,103, 31,238, 94,222,126,236,150, 32,
- 76, 85, 10,136,206, 73,126,156, 91,150,116, 2,128,152, 47,244,172, 85,191, 41,167,213,233,241,224,214,149,232,140,231, 23,166,
- 61,212, 88,126,208,232,189,190, 30,222, 53, 27,113,209, 79,238,245, 4,176,226,109,202,124, 89, 96,154,255, 78,205,127, 26,146,
-215,223,193, 74,243,111,220,125,162,232,244,233, 28, 4, 63, 8,199,201, 93,171,203,100,174,254, 87,164,134,236,190, 9,160,129,
-147, 95,239,247,175,222, 8,158, 91,187,126, 67, 59, 81,252,239,112, 36, 42,138,252,221, 27, 23,115, 83, 35,130,227, 76,186,220,
-177, 9,119,127, 43,117,254,150, 97,221, 61, 91,204,248,180, 96,134,246,241,123,220,252, 76,194,118,254,168, 84,150, 76, 64, 80,
-248, 31,132, 16,112, 92,193,123,163,201,152,105, 70, 82,157,191,234,233,243,201,202,221,161,219,190, 90,114,247, 66, 81,228,234,
-165,139,110,158, 1, 86,106, 25,172, 52, 82,104,172,100,224,203,120, 44,228, 82,229,144,214, 93, 63, 53,219, 92,149, 68,114,114,
-242, 29, 66,200,163, 69,139, 22, 5,172, 93,187,214,123,220,184,113,145, 63,207, 30,246, 11, 0, 28, 59, 86,208, 34,248,228,201,
- 19,172, 92,185, 67,151,159,159,255, 44, 55, 55,247, 26,165,180,212,136,147, 32,149, 78,220,244,243, 79, 53, 18,186,124,216,160,
-146, 87,117,216, 56, 87, 71, 99,183,234,200,200, 51,226, 65,116, 26,194,158,221,198,253, 43, 7,239,201, 69,217, 56, 51, 79,238,
- 32, 0, 29, 81,208, 73,209, 1,128, 35, 0,135,148,148, 20, 7, 0,239, 19, 66,146, 11, 67,185, 69,175, 19,148,210, 82,243, 94,
-171,213,194,104, 52, 22,230,239,127, 13,214,179,103,207, 94,138,104,189, 45,241,233,122,180,173,107, 7,109,190,128,124, 35,133,
- 65,192,139, 38, 52,115, 40,124,214,228, 20,149, 91,237,159, 30,140, 25, 50,205, 47,160,105,159,102, 29,251,115,170, 10,150, 56,
-119,112, 61, 13,191,125,116,183,132,136,223,229, 38, 61, 13,127,251,138, 20,153,222,213,106, 34, 66,159, 1, 43,133, 12,106, 37,
- 15,141, 82, 90,122, 89,178,203,236,112,250,244,249,254, 39, 78,157,159,217,182, 85, 83,187,105,131,187, 97,231,161, 75,176, 80,
-201, 64, 69, 1,189, 91, 85,234,241,112,251,123,157, 60, 28,212,174,187,207, 69, 95, 28,177,244,254,196,220, 92,195,179,210,204,
-113,225, 12,254, 87, 8, 33, 53, 0,116, 37,132,152, 0,168, 0,228,162, 96,110, 26, 21,128,203,165,205, 35,247,242, 62,210, 79,
- 26, 55, 14,220, 66, 64,229,160, 88,119,106, 31, 14,139,144,134,231, 36,222, 75, 46,239,113,203,139,126, 18, 15,160,159,165, 75,
-205,166,119,175,156,158,209,188, 67,207,122,205, 59, 15,144, 70,164, 24, 33, 74, 44,144, 27,118,209, 16,113,243,215,123, 38,189,
-110, 70, 78,194,227,115,111,210,202,229,212, 11,110, 31, 92,208,172, 90,235, 81, 13, 43,120, 7,193,182,146, 63, 0, 32, 51,230,
- 1,162,111,236, 58,152, 21, 39, 29, 64,233,189,114,143,238,147, 40,149,125,171,214,172,143,199, 33,119,160,205,203,254,149, 82,
- 42,218,121, 55,255, 53,236,241,221,111, 93,189,234,129,147, 43,251,190,206, 96, 49, 24,140, 50, 26, 44, 19, 12, 93,102,124,191,
- 96,191, 40,154, 84, 60, 47,209, 10, 48,254,237,204,213, 75,225,248,251,191,238, 39,189,122, 29, 50, 94, 61, 63, 84, 34,145,180,
-254,111,244, 74, 12, 78,121,122,233,124,220,237,237,155,204,125, 30, 87, 98,138,206,180,236,183,167,203,198, 44,191,255, 16,192,
-250,210, 38, 17, 53,247,154,170,104,177,107, 60, 0, 11, 0,207, 40,165, 41,175,220, 67,106,251,127,242,245,139,102, 65, 30,128,
- 8,170, 45,203, 15, 24,141,218,165,139, 38,244,210,155,140,194,250,188,164, 71, 39,203,155,208, 66,195,116,145, 16,114,123,226,
-196,137,141,157,157,157, 93,167, 76,153,162,138,141,141,149, 28, 57,114, 68,151,157,157, 29,155,157,157,125,129, 82,106,118, 19,
- 68,122,240,206, 44,210,178,101,155, 3,191,111,255, 0, 60,109,103,231,224,218,218,206,222,217, 62, 45, 37, 62, 45, 53, 57,225,
- 52, 17,133,147, 73, 50,199,223,105,200, 26,163,153,105,188, 12,224,242, 59, 45, 68, 84,184, 93,171,205,112,179,215, 45,183, 97,
-225,249,228,233,227, 75, 30, 45, 40,145, 74,203,116, 65,215,198,222,139, 5, 48,212,194,185,230,178,251,183, 46, 79,226, 40,164,
- 38, 34,206,207, 75,122,124,235, 93, 29, 22, 94, 42,205,111,215,249,143, 29,218,101, 10,233, 27, 59,122,210,179,103, 77, 0, 54,
-146,150, 45,183,158, 57,123,177,255,201, 51, 23,103, 6,181,236,100,167,168,226,141, 74,182, 6,108,250,198,255,243, 19,183,146,
-130,187,125,123, 97,109,104,172,238,126,241,167, 22,152, 89, 6, 30, 17, 66,210, 1,116,164,148,254, 66, 8, 25, 12, 32, 20,192,
-185,178, 62, 59, 47, 59,254,225, 69, 0,149,254,140,186, 41, 59,254,225, 69, 66, 72,155,147, 7,243, 62,184,122,238,232,252,166,
-157,250,219,221, 57,184, 33, 91,175,203,252, 38, 55,254,217,239,230,164,149,198, 5,107,137, 83,237,174, 79,142, 45,156, 96, 23,
-122,113,168,202,206, 67,147,155, 18,145,158, 30,121,115,105, 94,162,211,178,210,250,169,150,134,189,163,171,187, 72,100,184, 27,
-124, 17,156, 68,186, 3, 0, 56,137,116,199,163,219, 23,191,173,224,238, 11,107, 59,151, 26,175, 62, 1,131,193, 96,148, 94, 73,
-253,105, 47, 0,126,255,143,154, 40, 8, 76, 57, 0,176,120,215,233, 4, 32,251,127, 59,158, 0,108, 84, 42, 85, 7,107,107,235,
-247, 81,208,201,248,157,164,211, 54,176,159,229, 63,189, 44, 49,205, 98,223,183,104, 33,113,170,213,237, 99,251, 90,239, 71,124,
-212,163, 69, 72, 83, 63,199,214,165,157, 99,102,150,207, 94, 0, 6, 3,232,245,119, 63,158, 64, 11,137,218,181,110,109,184,184,
-168,202, 93,135,212,172, 41, 83, 59,248, 58, 2, 45, 36,239, 42,157,182,158,205,198, 85,107, 58, 48,193,198,171,197,188,226,203,
-109,188,154, 79,242,108, 50, 32,198,214,179,217, 56, 86,230,153,230,159,173,249, 79,123, 73,152,197, 44,209,116, 82,252,119,148,
-193,187,214, 54,252, 31, 30,143, 12, 0, 71,223,181,238,187,156, 8,146,241,127, 80,142, 10, 35, 90, 0, 54, 22,239,103,245, 14,
-202,231,206,255,159,115,233,172, 9,192,189,183,210, 8, 9, 49, 0, 72,122,167,231, 98,216,249,133, 0,254, 48, 97,110,122,232,
-185, 57, 0,230,176,210,203, 96,148, 29,142, 29, 2, 6,131,241, 23,152,118,145, 29, 5, 6,131,241, 79,134,160,240,145, 50, 37,
- 84,128,102,143, 14, 32,132,248,149,163,130,189,207, 52,153, 38,211,100,154, 76,147,105, 50,205,127,151,102,105,218,255,148,209,
-137,228,207,236,179,200,134,176, 50, 77,166,201, 52,153, 38,211,100,154, 76,243,223, 8,107, 34,100, 48, 74,175, 72, 28, 9, 33,
-142,236, 72, 48, 24, 12, 6,227,111,107,176,204,189, 88,189,205, 69,141, 93, 16,255,148,124,147, 16, 66,190,182,181,181,189,234,
-233,233,153,100,109,109,125,149, 16, 50,150, 16, 34, 45,175,166,155,155, 91, 67, 87, 87,215,149,206,206,206,171, 93, 93, 93,131,
-254,196,180,187, 18, 66, 92,203,185,237, 76, 66, 16, 86,240, 34, 51, 89, 73, 96, 48, 24, 12,134, 57,188,118, 20, 97,179,102,205,
- 46, 74, 36, 18, 55,137, 68, 98,238,115,204,168,209,104,140, 61,123,246,108,211, 82, 46, 86, 99, 10,223, 47,161,148, 78,123,155,
-245,204,216,118, 37,165,116, 98,121, 46,200, 0, 64, 41,141, 3, 0,119,119,119, 47, 81, 20,155, 75,165,210,234, 70,163,241, 49,
-199,113,231, 99, 98, 98,194,254,102, 6,136,175, 89,211,123, 0, 79, 72, 19, 0, 54, 0, 50, 76, 34,189,236,224,224,186,229,236,
- 89,243,231,200, 33,132, 72, 0,140,210,104, 52, 61,213,106,117,149,156,156,156,231, 90,173,118,175, 92, 46,111,189,124,249,114,
-183,198,141, 27, 91, 38, 39, 39, 19,142,227, 28, 15, 30, 60,216,111,249,242,229,109, 9, 33,157, 41,165,101,158,135, 71, 16,132,
- 1,251,247,239,175, 5, 0,157, 58,117,250,132, 16,114,149, 82, 42,190,122,252, 75, 72, 35,113,113,113, 9, 2,128,248,248,248,
-203,148, 82,234,234,234,218, 68,161, 80,124, 2, 0,249,249,249, 27,226,226,226, 46,189,131,178,228, 72, 8,198, 20, 77, 92,203,
-113,228,107, 75, 75,203,109,217,217,217, 79,139,190, 47, 76,103, 18,171, 74, 24, 12, 6,131, 97,150,193,226, 56,206,109,221,186,
-117, 14, 42,149, 10,164,240, 97,123,164,216, 67,247, 8, 33, 47, 62, 27,141, 70,104,181, 90,124,249,229,151,166, 50, 92,172,198,
-182,107,215,238, 61,165, 82,249,210,196,146, 58,157, 78, 74, 8,124,139,158, 58,207,113,100, 12, 33,228, 71,115, 46, 98, 69,191,
-161,215,231,115, 82,169, 28, 60,207,141,170, 91,183,110,189,228,228,228,179, 0,214,197,197,197,165,154,161,241, 43,128, 46,132,
- 16, 88, 88, 88,220,240,242,242, 74,253,236,179,207,156,219,180,105,131,202,149, 43, 35, 62, 62,190,225,153, 51,103, 62,105,208,
-160, 65, 66, 66, 66,194,105, 74,233,217,184,184,184,167,111,105,142, 28,236,236,236, 58,202,100, 50, 25,199,113,233,113,113,113,
-151, 41,165, 9,101, 49, 87,126,190,213, 22, 13, 29, 54,188, 70,143, 30, 61, 92, 84,106, 75,101, 84, 84,104,220,207,107,127,178,
-190,120,225, 82, 93, 66,200,152,194,217,175,205,137, 82, 29,152, 62,125,186,107,211,166, 77, 45, 83, 83, 83, 97, 50,153, 42,236,
-221,187,119,104,253,250,245, 45,221,220,220,228,155, 55,111, 70, 78, 78, 14, 4, 65,176,245,242,242,178,237,219,183,175,126,243,
-230,205,163, 0, 44, 46,235,126,139,162,200, 23,254, 37,130, 32, 72, 1,240,132,144, 25,165, 25, 34, 55, 55,183,128,110,221,186,
-205, 83, 40, 20,216,190,125,251, 78, 0,203, 1,244, 62,121,242,100, 53, 0,104,218,180,105,111, 0,151,108,108,108,234, 18,130,
-175, 69,177,224,209, 73,101, 41, 75, 37,209,185,115, 23, 16, 66, 86, 58, 59, 59, 95, 74, 73, 73,113, 35, 4,189,203, 99,220, 24,
- 12, 6,131,241, 47, 54, 88, 0,160, 82,169,112,224,192, 1, 80, 74, 95, 60, 54,164,232, 17, 34, 55,115,252,160, 51, 73,145, 19,
-127, 23, 31,212,151,162,126,253,250, 47, 25,176,215, 93,195,139, 27,180,209,163, 71,195,201,201,233,165, 21, 18, 19, 19,113,250,
-244,169, 18,183, 49,215,111, 20,255, 48,107,214, 44,235,180,180,180,206,235,215,175,111,235,226,226,242, 93,124,124,252,133, 82,
- 34, 87, 93,138, 58,254,191,247,222,123, 1,107,214,172,121,152,157,157,109,184,118,237,154,225,167,159,126,138,107,213,170,149,
-107,207,158, 61,101,163, 70,141,114,126,254,252,121,255, 3, 7, 14,244,183,181,181,221,159,158,158,190,160, 60, 25,160,209,104,
-252,186,117,235,214,246,151, 95,126,145,171,213,106,132,133,133, 85, 24, 48, 96,128, 19, 33,228,215, 87, 31,165,243, 58,106,214,
-244, 30, 48,100,232, 80,159,225,159,143,240, 55, 24,244,121,119,131,207,158,150,200, 56,254,203, 47, 63,181, 78, 77, 77,180, 19,
- 69, 58, 0, 5,243, 15,149,198,168, 41, 83,166,184,120,121,121, 85,220,182,109, 27,114,114,114, 0,192,193,211,211, 19,213,170,
- 85, 19,206,157, 59, 7, 31, 31, 31, 88, 90, 90,226,220,185,115,184,114,229, 10,252,253,253, 45,100, 50,217,135,111, 50, 88,110,
-110,110,181,221,220,220,166, 58, 21,102,118,209,241,173, 87,175, 30, 70,143, 30, 13,157, 78,135,170, 85,171,122,170, 84,170, 75,
-231,206,157, 53,199, 92, 43,237,237,237, 49,124,248,112,228,228,228,244,114,115,115, 11,167,148, 74, 10,211, 11, 74,169, 99,181,
-106,213,182,180,108,217,178,234,254,253,251, 72,121, 79, 14, 74,105, 18, 33,100, 73,215,174, 93,190, 6, 8, 90,183,110,157, 54,
-122,244,104,225,225,195,135,205, 62,248,160, 71,224,147, 39, 79,223,137,113, 99, 48, 24, 12,198,191,200, 96, 21, 69,168, 78,158,
- 60, 9,189,254,143,143,154,179,109, 81, 31,227, 62,168,132, 79, 70,110,194,142,103,161,168, 93,187, 54, 94, 29,145,248,202, 67,
- 90,147,120,158, 95,199,113,100, 8, 33, 4,245,234,213, 79, 90,180,104, 81, 73,143, 69, 49,214,171, 87, 63,137,231, 57, 71, 74,
- 41, 8,225,126, 22, 69, 33,169, 36,205,215, 93, 16,229,114,197, 24, 0,112,113,113, 77, 58,116,232,144,177,103,207,158, 88,184,
-112,161,124,252,248,241,211,221,220,220, 6,197,198,198,198,190, 46,157,197,241,240,240,192,227,199,143, 49,121,242,228,132,196,
-196,196,117, 9, 9, 9,143,183,110,221, 90,201,211,211,243,147,181,107,215,122, 6, 5, 5,113, 29, 58,116,192,193,131, 7,235,
-150,144,150,210,134,190, 74, 1, 84,105,217,178,101,155,223,127,255, 93,158,149,149,133,200,200, 72,168,213,106, 76,155, 54,205,
-242,243,207, 63,111, 14, 96,183, 57,154, 60, 33, 77,222,239,214,221, 73,175,215,230,232,245,186,236,240,200,155,241,113,113, 15,
- 51,170,122,249, 59,190,215,190,177,221,227,199, 97, 77, 94,103,176,138,107, 42,149,202, 15,155, 52,105, 98,185,109,219, 54, 52,
-104,208, 0,214,214,214, 56,115,230, 12,238,221,187,135,180,180, 52,142, 82, 10, 11, 11, 11,204,155, 55, 15, 30, 30, 30,200,206,
-206, 70, 68, 68, 68, 5,169, 84,106,255,166,116,138,162,216,105,211,166, 77, 78,246,246,246, 48,153, 76,160,148,194,100, 50, 65,
- 20, 69,196,199,199, 35, 39, 39, 7, 26,141, 6, 58,157, 14,231,207,159, 43,209, 44, 23,215,140,141,141, 61,191,118,237,218,243,
-213,171, 87,111, 62,126,252,120,200,100,178, 9, 25, 25, 25, 88,184,112, 33,212,106, 53,102,205,154,229, 92,175, 94, 61, 0, 48,
-154, 76,166,162,178, 68, 41,197,138,226, 38,200,156, 17, 48,238,238,238, 39,147,146,146,131, 90,181,106,133,244,244,116,227,180,
-105,211, 80,175, 94, 61, 84,173, 90, 13,165, 29,207,119, 5,211,100,154, 76,147,105,254, 27, 52,255,145, 6,171,240, 17, 83,164,
-132,247,248,253,247,223, 75,220,240,227,197, 33,144,240, 5,215,191,213,171, 87, 35, 45, 45,173,212,104,147, 32, 8, 95, 57, 57,
- 57,105, 39, 76,152,208,186,106,213,170,198, 47,191,252,242, 86, 68, 68,196,232,226,235, 84,174, 92,121,217,143, 63,254,136,103,
-207,158,165,204,155, 55,239,116, 98, 98,226,164, 50,102,250, 84, 66,200, 74, 0,136,139,139, 75, 61,120,240, 96,131,115,231,206,
-141, 93,178,100,137,243,136, 17, 35,228, 35, 71,142, 28, 2, 96,250,107,182,141, 35,132,108,117,115,115,235,223,180,105, 83,116,
-239,222, 61,181, 73,147, 38,134,235,215,175, 59, 95,189,122,117,234,202,149, 43,197, 65,131, 6,113,205,154, 53, 67,114,114, 50,
-118,237,218, 37, 70, 69, 69,113, 10,133,194,236,103, 6, 18, 66, 90,243, 60,255, 53,199,113,245,124,125,125, 31, 13, 27, 54,236,
-126, 90, 90, 90, 74, 76, 76, 12,242,242,242, 96, 48, 24, 32,145, 72, 32,147,201,202, 48,127, 6,177, 86,171, 85,178, 43,151,246,
- 30,139,139, 9, 73,137, 79,188,159,201,129,114,113,113, 55, 51,125,124, 90,219,161,160, 79, 86,169, 88, 88, 88,120, 38, 39, 39,
- 35, 39, 39, 7, 54, 54, 54, 88,178,100, 9, 28, 29, 29,161,213,106,241,248,241, 99,234,238,238, 78,206,156, 57, 3, 55, 55, 55,
-164,167,167, 67,175,215, 35, 47, 47, 47, 81,175,215,191,113,255,165, 82,233,254, 65,131, 6, 53,119,116,116, 84, 23, 69,176, 68,
- 81,132,183,183, 55, 70,140, 24,129, 29, 59,118, 32, 52, 52, 20,148, 82,163,155,155,123, 18,199, 17, 71, 0,148,227,248,173, 38,
-147, 41,169,132,124,162,238,238,238,179,166, 78,157,234,254,211, 79, 63, 85, 25, 61,122, 52, 4, 65,128, 40,138, 16, 4, 1, 73,
- 73, 73,216,191,127, 63, 46, 93,186,100,120,252,248,241, 14, 43, 43,235, 7, 90,173,246,102,126,126,254,115,115,143,168,187,187,
-187, 82, 20,197,207,170, 85,171,214,177,111,223,190, 70,153, 76, 6,173, 86,139,188,188, 60,220,191,127,223,216,177, 99,199,180,
-174, 93,187,216, 29, 58,116,136, 82,138, 37, 44,122,197, 96, 48, 24,229,227,117, 30,228, 31, 19,193,122,221, 78,109,216,176, 1,
-148, 82,240, 60, 15,142,227, 94, 52, 17,230,196,137,248,120,228, 22,200,120, 17, 71,143, 30, 69,221,186,117,205,250, 65, 81, 20,
-151, 31, 61,122,180,113,211,166, 77, 37,109,219,182,173, 95,169, 82,165,122,145,145,145,183, 1,160, 82,165, 74,245,218,181,107,
- 87,223,209,209, 17,203,150, 45,211,137,162,184,188,156,206,186,248,197,238,154,135,135,199,119,123,246,236,249,105,216,176, 97,
-112,113,113,169, 83,202,182,195,218,183,111, 95,247,219,111,191,197,228,201,147, 13,235,214,173, 51, 13, 31, 62, 92,210,178,101,
- 75,108,222,188,153,123,242,228, 9,214,173, 91, 39,238,217,179, 39,129, 16,194,183,111,223,222,169, 12,133,168,133,147,147,211,
-175, 59,119,238, 20, 3, 2, 2,148, 79,159, 62,173, 49,102,204, 24,167,248,248,248,227, 85,171, 86, 77,205,203,203,131,201,100,
- 66,110,110, 46, 0,232,205,213,229,120,146, 24, 19,243,220, 49,223,144,161,235,208, 50,104, 76,114, 68, 10, 28, 42,119,195,137,
-115,191, 47,141,140, 14, 21, 9, 7,179,154, 26,115,114,114,158,155, 76, 38, 59, 0,142, 39, 79,158,132,131,131, 3,178,179,179,
- 97, 48, 24,160,213,106, 13,182,182,182,138,212,212, 84,228,231,231, 35, 63, 63, 31, 86, 86, 86, 8, 14, 14, 78, 51,153, 76,135,
-223,164, 27, 21, 21,245, 16,192,123,175, 24,105, 5,199,113,167,140, 70, 35,194,194,194,240,232,209,163, 54, 17, 17, 17,249,133,
-199,201, 21, 0, 76, 38, 83,220,235, 52, 99, 98, 98,116, 14, 14, 14,223,126,250,233,167,163,157,156,156,252, 0,192,203,203,203,
-106,204,152, 49, 88,176, 96, 1, 30, 60,120, 48, 85, 42,149, 94,141,141,141,205, 47,107,249,113,114,114,242, 85,169, 84,227, 70,
-141, 26,229,228,235,235,139,252,252, 2, 9, 75, 75, 75,228,229,229,193,202,202, 10,141, 27, 55,126,252,221,119,223, 25, 40,197,
- 80, 74,105, 34,171, 34, 25, 12, 6,227,221,152,172,127, 84, 4,171,208, 88, 16, 66, 8,125,101,135, 11, 46,224, 28,247,146,185,
-226,121, 30, 31, 52,224,145, 93,213, 11, 28, 87,208,148,104, 50,153, 55,136, 44, 57, 57, 57,209,221,221,125,111,112,112,112,207,
- 94,189,122,225,244,233,211, 95, 0,248, 12, 0,120,158,255,162, 87,175, 94, 8, 14, 14,198,163, 71,143,246, 38, 39, 39,191,147,
- 11,151,193, 96,200, 51, 26, 11, 90, 35,149, 74,165,172, 84,195,194,113, 6,153,172, 96,181,167, 79,159,118, 31, 57,114,100,247,
-246,237,219, 15,238,220,185, 51,246,239,223,143, 77,155, 54,205, 6,112,186,105,211,166, 91,202,146, 14,158,231,199,236,216,177,
-195,212,180,105, 83, 75, 74, 41,106,213,170,101, 57,110,220, 56,195,194,133, 11, 61, 7, 13, 26,148, 26, 19, 19,131,172,172, 44,
- 36, 36, 36, 24,162,162,162, 66,205,213, 53, 9,226,233,149, 43,127,116, 27,250, 89, 55,167,223, 15,174,159,187,107,247,221, 58,
-253,122, 39,132,184,186,213,118, 88,190,234,146,210,100, 18,247,153,163,163,211,233,118, 29, 58,116,168,119,165, 74,149, 28,239,
-221,187, 7,157, 78, 7, 81, 20,209,177, 99, 71, 0, 80, 20,173,247,248,241, 99, 93, 94, 94, 94, 82, 72, 72, 72,118,100,100,164,
- 17, 5,157,204,205, 57,129, 94,140, 14, 52, 24, 12,253, 59,117,234, 4, 65, 16,208,161, 67, 7,220,185,115,167, 63,128,117, 69,
-223,155, 91,150, 0, 76, 4, 0, 55, 55, 55, 59,107,107,235,253, 69,209, 49, 39, 39,167, 75,193,193,193, 70,119,119,247,190, 50,
-153,172,177, 86,171,253, 61, 33, 33,225,124,105,154,174,174,174, 65, 85,171, 86,157,178,112,225, 2,226,228,228, 12, 65, 48,194,
-100, 50, 33, 41, 41, 5, 57, 57, 57,240,245,245,133,135,135, 7,230,205,155, 7,142,227, 14, 48,115,197, 96, 48, 24,111, 79, 73,
- 30,228,255, 29,238,213, 29, 44,205, 92, 21,189,151, 73,120,216, 87,176,133,125, 5, 59,216,218,218, 66, 16, 4,152,235, 62, 57,
-142,219,188,109,219, 54,189,181,181, 53,186,118,237,234,227,226,226,210,212,197,197,165,105,215,174, 93,125,172,173,173,177,109,
-219, 54, 61,199,113,155,223,145, 43,230,120,158, 31,208,180,105, 83, 36, 38, 38,226,249,243,231,215,202,178,125,116,116,116,118,
-124,124,252,142,220,220, 92, 72, 36, 18,232,116, 58, 0, 56, 11,160,204,207, 82, 19, 69, 49, 32, 32, 32, 64, 85,212, 87, 45, 60,
- 60, 28,150,150,150,150,209,209,209,142,121,121,121,208,235,245,200,200,200,192,173, 91,183,242, 0,196,153,171,251,224,193,211,
-189, 55,175,223, 12, 62,122,252, 2, 87,165, 74, 29, 7,119, 55,117,150,189,131,187,229,225,163,247, 84, 9,241,169, 97, 15, 30,
-132,154,251, 48,220,229,123,246,236, 73, 13, 14, 14,126,228,238,238, 30,101,109,109, 77, 1, 32, 62, 62,254,165,215,141, 27, 55,
- 20, 71,143, 30,205,139,140,140,220,143,130, 65, 1, 38, 51,242, 97, 38, 33,120, 66, 8,158,240, 60,191,168,110,221,186,253,130,
-130,130, 16, 29, 29,141,160,160, 32,212,170, 85,171,159,189,189,189,115, 25,243,214,153, 16,226,234,235,235,171,209,104, 52, 75,
- 7, 15, 30, 12,147,201,132,182,109,219, 34, 55, 55,119,189,171,171,235, 55,237,219,183,255, 98,205,154, 53,117,156,156,156,190,
- 50, 83,182,111,159, 62,125,136, 90,173,129,209,104,132, 92, 46,135, 70, 99, 1, 79, 79, 79,180,110,221, 26,148, 82,180,110,221,
- 90, 92,187,118,237,126,149, 74,181,133, 85,139, 12, 6,131,241,238, 76,214, 63, 50,130,245,154, 11, 24, 4, 65, 0, 33, 4, 87,
- 51,253,160, 51, 73,144, 25,125, 19,189, 2,228, 47,140, 22,207,243,224,121, 30, 70,163, 17,230, 62,118, 39, 42, 42, 42,195,197,
-197,229,183, 75,151, 46, 13,236,209,163, 7,142, 29, 59, 54, 12, 0,122,244,232,129, 75,151, 46, 33, 44, 44,236,183,248,248,248,
-140, 50, 94,108,237, 1,240,197, 35, 10, 78, 78, 78, 85, 42, 86,172,248,197,208,161, 67, 27,214,174, 93, 27, 91,183,110, 5,128,
-211,102, 71,134, 10,162,114,142, 0,114, 94,217, 55, 25, 0, 75, 81, 20,203, 52,201, 38,199,113, 55, 78,159, 62, 29,208,185,115,
-103,203,200,200, 72,196,197,197, 97,231,206,157, 73,118,118,118, 73,162, 40,194,206,206, 14,246,246,246, 48, 26,141,170,199,143,
- 31, 59, 3, 48,123,174, 45,129,202,127, 62,126,236,218, 79,129,254, 29,185, 42,149, 52,153,128,158,220, 8,142,213, 72,100,146,
-213,101, 40,220, 38, 66, 72,215,139, 23, 47,142,186,114,229,202, 7, 46, 46, 46,100,224,192,129,232,216,177, 35,228,114, 57,180,
- 90, 45,210,211,211,113,232,208, 33, 98, 50,153,130, 0,192,197,197,165, 98,229,202,149, 55, 16, 66, 98,195,195,195, 7,190, 38,
-111, 94,157,162, 99, 88,247,238,221, 31,198,199,199, 27,199,140, 25,131, 69,139, 22,225,147, 79, 62,145,134,132,132,124, 6,224,
-123, 51,243,251, 59, 66,240, 53, 40, 72, 76,116,244,147, 31, 87,173,202,119,113,113,193,201,147, 39,209,184,113, 99,120,123,123,
- 87,185,117,235, 86,149,102,205,154,225,218,181,107, 72, 77, 77,189, 82,154,102,203,150, 45, 37, 60,207,123,186,186,186, 34, 34,
- 34, 2, 74,165, 18,206,206,206,176,177,177,129,131,131, 3, 22, 45, 90,132, 37, 75,150,220,149, 72, 36,235, 98, 99, 99,195, 88,
-117,200, 96, 48, 24,140, 55, 26,172,226,174,241,213, 40,214,145, 35, 71, 64, 41,133, 69, 80, 3, 76,232, 85, 25, 3,190,216,132,
-237, 97,143,161, 80, 40,254, 43, 34,145,224,243,207, 63, 47,211, 15,219,218,218,110,223,190,125,123,143, 38, 77,154,104,218,182,
-109,235, 13, 0, 74,165,210,184,125,251,246, 92, 91, 91,219,237,101, 52, 87,147, 9,193,120, 80,112, 10,185,252,164, 93,133, 10,
-167, 44, 45, 45,253,219,183,111,239,221,161, 67, 7,120,121,121, 97,231,206,157,216,185,115,231,233,248,248,248,203,230,234,122,
-122,122,226,225,195,135, 3, 0,172, 7, 64,241,223, 78,252, 38, 0, 77, 60, 60, 60,148,101, 73,167, 32, 8, 75, 6, 13, 26,244,
-251,228,201,147, 83,124,124,124, 52, 59,118,236, 72, 63,121,242,164,190, 83,167, 78,207,139, 46,228, 90,173, 22, 90,173, 86,238,
-230,230, 86,181, 44, 6,235,193,131, 7, 73, 29,218,183,113, 88,245,211, 37,111,173, 86, 48,236, 59,114,210, 96,212,107,180, 15,
- 31,135, 37,148, 37,141,148, 82,147,187,187,251,112, 81, 20, 29, 76, 38,147,193,193,193, 65,246,235,175,191, 66,169, 84,130,227,
- 56,212,171, 87, 15, 74,165, 82,239,234,234,154, 9, 0,142,142,142,198,197,139, 23, 75, 62,253,244, 83, 89, 89,178,204,217,217,
- 25, 91,182,108, 65,110,110,238,220, 29, 59,118, 76,252,252,243,207,225,227,227,211,210,213,213,117, 81, 92, 92,156,182,148,252,
-182, 45,110,216, 8, 33,213,101, 50,217,195,229,203,151,235, 47, 94,188,184,231,232,209,163, 29, 63,249,228, 19,101,211,166, 77,
-113,249,242,101,252,252,243,207,215,172,173,173,151,149,150,168,115,231,206,137, 46, 46, 46, 47,154,193,117, 58, 29,194,195,195,
-209,184,113, 99,172, 91,183, 14,203,151, 47,223,150,144,144,192,162, 86, 12, 6,131,241, 39, 69,174,254, 73, 81, 44, 73,105, 43,
-236,216,177, 3, 0,240,217,138,199,208,235, 11,250, 49,173, 94,189,250,197,252, 85, 69, 77,137,231,207,159, 7,202, 48,103, 85,
- 72, 72, 72,174,187,187,251,230,145, 35, 71,206,186,113,227,186, 35, 0,220,188,121, 51, 41, 33, 33, 97, 74, 76, 76, 76,110, 25,
-204,149, 13, 33, 24, 47,138,148, 47, 52,105,237,198,140, 25,227,218,164, 73, 19,131, 84, 42, 69, 84, 84, 20,126,248,225, 7, 92,
-186,116,105, 71,124,124,252, 42,106, 70,152, 45, 34, 34,226, 90,116,116,116,195, 17, 35, 70,160,121,243,230, 93,126,254,249,231,
-247,138,239, 91,189,122,245, 54,118,234,212,201, 73,161, 80, 72,244,122,189,240,244,233,211,219,102, 22,162,115,132,144,190,227,
-199,143, 31, 69, 41,173,235,232,232, 24, 21, 24, 24, 24,210,164, 73,147, 84, 43, 43, 43, 72, 36, 18, 36, 37, 37, 33, 47, 47, 15,
-130, 32,216,150, 37, 35, 61, 60, 60,154,142, 26, 53,170,206,240,225,195,145,155,155,139, 77,155, 54, 97,213,170, 85,240,240,240,
-104, 26, 29, 29,125,177, 44, 90,162, 40, 58, 28, 56,112,160, 40, 82,135, 83,167, 78,193,213,213, 21,214,214,214,200,202,202,194,
-192,129, 3,229, 83,167, 78, 5, 0,220,186,117, 75,170, 82,169, 74,219,239, 36, 66,200, 18,142, 35, 99, 0,144,128,128,192,100,
- 43, 43, 43,227,213,171, 87, 67, 99, 99, 99, 15,123,121,121,125, 56,104,208, 32,239,192,192, 64,217,211,167, 79,155, 1, 56, 86,
-214,130,156,150,150,134,243,231,207,159,143,143,143, 95,226,232,232,184,253,187,239,190,251,218,217,217,185,110, 92, 92,220, 85,
- 39, 39,167, 89,193,193,193, 70, 51,242, 71,116,113,113,137, 62,126,252,184, 71,207,158, 61, 33,151,203,145,158,158, 14, 43, 43,
- 43, 44, 94,188,152, 26, 12,134,189,172, 42,100, 48, 24, 12,198, 59, 49, 88,123,246,236, 1,199,113,208, 39,233,241,249,248, 29,
- 80, 43,121,156, 57,115, 6,118,118,118, 47,245,203, 42,106, 50,124,197,252,188,241,105,219,105,105,105, 23,227,226, 98, 29,138,
- 77, 44,233,160, 80, 40, 47,150, 98,168,222,168, 73, 8,129,193, 96,192,209,163, 71,113,225,194, 5,195,179,103,207,206, 17, 66,
- 14,196,197,197,221, 53, 87, 51, 51, 51,115,254,176, 97,195,198,119,236,216,177,225,128, 1, 3,176,124,249,114,217,195,135, 15,
- 65, 41, 69,253,250,245, 81,187,118,109, 55,163,209, 72, 31, 60,120,144,179,127,255,254,163, 58,157,110,139,185,233,164,148,158,
- 4,112,146, 16, 34, 75, 72, 72,168,146,153,153,217, 70, 20, 69,203,164,164, 36, 68, 68, 68, 32, 45, 45, 13, 89, 89, 89, 48,153,
- 76,105,101,217,247,232,232,232,139, 1, 1, 1,224, 56, 14, 90,173, 22, 49, 49, 49, 48,153, 76,136,139,139, 43,243,241,228, 56,
- 46,185, 83,167, 78, 14,249,249,249,166, 62,125,250, 72,146,147,147,225,227,227, 3, 0,200,206,206,198,145, 35, 71, 80,189,122,
-245,162,200, 25,124,125,125, 75,213,164,148, 78, 35,132,172,113,113,113,249,110,206,156, 57, 62, 87,175, 94,133,209,104, 60, 10,
- 0, 70,163,241,232,205,155, 55,189,253,253,253,177,117,235,214,246, 37, 25,172,226,154,148,210,244, 66,195,246, 53, 40,136,111,
-205,154,169, 62, 62, 62, 6,169, 84, 90, 1, 0,146,146,146,146, 0,140, 55,195,156,251,149, 48,103,215,148,221,187,119,127,122,
-229,202,149,102, 95,127,253, 53,105,221,186, 53, 0, 32, 55, 55, 87, 72, 78, 78,206, 45,143,230,219,194, 52,153, 38,211,100,154,
-255, 6,205,127,149,193,202,204,204, 68, 96, 96, 32,140, 70, 35,106,214, 52, 34, 43,203, 19, 70,163,241, 69,231, 95, 81, 20, 97,
- 50,153, 32, 8, 2, 56,142, 51,187, 15, 86, 17, 58,157,206,240,234,228,239, 58,157,206, 80,198,208, 98, 6, 33,228, 7,142, 35,
-227, 65,193,201,229,242,107,171, 86,173,218, 4, 32,150, 82,122,173,180,230,166,146, 72, 72, 72, 72, 1, 48,174, 98,197,138,245,
-207,156, 57, 51,226,131, 15, 62,240,238,218,181, 43,162,162,162, 96, 50,153, 16, 26, 26,106,220,191,127,255,131,140,140,140, 53,
-148,210,135,229, 57,240,148, 82, 3,128, 39,150,150,150, 16, 69,177,121,227,198,141,237, 76, 38, 19, 82, 82, 82,112,229,202,149,
-136,148,148,148, 75,229,136, 96, 97,216,176, 97,200,201,201,193,142, 29, 59,112,236,216,177,114, 69,176, 98, 98, 98,170, 2,128,
-171,171,107,162,149,149,149,100,240,224,193, 48, 26,141,200,203,203, 67, 86, 86, 22, 82, 83, 83,245, 95,125,245,149, 28, 0,228,
-114,185,177, 67,135, 14, 18, 51,247, 57, 46, 40, 40,200, 90,169, 84,226,252,249,243,162, 40,138,167, 10, 77,205,169,139, 23, 47,
-142,168, 91,183, 46,103,111,111, 95,221, 76,173,233,132,144,159,172,172,172, 92,107,250,250, 46,165,148,194,193,193,193,227,109,
- 79,136,196,196,196,100, 0,115,221,220,220,118,127,251,237,183, 67, 26, 54,108, 88,107,250,244,233,160,180, 32, 66,202, 96, 48,
- 24, 12,198,219, 26,172,240,225,195,135, 27,138, 71,134, 94,137,114,252, 33,114, 36,138, 98,108, 25, 77, 70, 18, 33,100,113, 97,
-211, 17,202, 59, 97, 35,165,116, 22, 33,100, 13, 0, 94,151,159,255,206,134,205, 71, 69, 69,221, 34,132, 12,222,188,121,115,219,
-157, 59,119,142,235,221,187,183,106,253,250,245,250,164,164,164, 69, 0,142, 81, 74,197,183,253,141,236,236,236, 39,132,144,248,
-199,143, 31, 55,146,203,229, 42, 65, 16,146,147,147,147, 67, 40,165, 57,101,209,137,142,142,190,232,234,234,138,189,123,247,194,
-206,206, 14,105,105,105,102, 69,176, 74,185, 67,233,190,109,219,182, 61,162, 40, 42, 95,201,251,172,184,184,184,170, 64, 65, 39,
-247, 35, 71,142,108, 32,132,196,154,153,206, 29, 95,126,249,229,192,228,228,228, 93,177,177,177,233,133,134, 46,221,221,221,125,
-201,228,201,147,251,166,164,164,252, 90,134,124, 79, 32,132, 36, 63,127,254, 60, 59, 45, 45,205, 82, 16,132,119,118, 98,196,198,
-198, 62, 3,240,141,155,155, 91,195, 14, 29, 58,244,167,148, 38,179,234,130,193, 96, 48, 24,111,109,176,206,156, 57,211,250,127,
-145,128,194,166,163, 31,139, 12,215, 91,232,164,252, 73,233,163, 0, 78, 16, 66, 78, 47, 91,182,172, 70, 94, 94, 94, 4,165, 52,
-247, 29,255, 70, 54,128,227,111,171, 19, 23, 23,167, 38,132, 76, 6, 48, 9,192, 28, 74,233,236,183, 52, 25, 87, 1,188,113,234,
-132,248,248,248, 40, 0,173,204,213,140,137,137,217,141, 87, 30, 1, 84,184,124, 47,128,189,229, 56,118,130,135,135,199,180, 49,
- 99,198,116, 0,112,224, 93,231,127,108,108,236, 53, 0,215, 88, 85,193, 96, 48, 24,127, 57, 1, 0, 28, 10,223, 23,221,244, 58,
-188,242, 94, 15, 64, 94,108,155,162,207,201, 0,110, 20,211, 40,190,188,180,109, 1, 32, 5,192, 93,148,101, 18,240,191,195, 17,
-163,148, 38,253,221, 31, 53, 66, 41, 21,114,115,115, 31,188,107,115,245, 39,164,115, 54,165, 84,253,182,230,234,255,137,232,232,
-232,224,216,216,216,239, 99, 99, 99,239,177,250,135,193, 96, 48,254,185,230,138, 16,114,144, 16,114,176,208, 16, 57,148,240, 94,
- 94,180, 78,241,207,197,140,153, 67, 9,203,223,184, 45, 33,228,224,196,137, 19, 91, 1, 8, 42, 75,130, 57,150,103, 12, 6,131,
-193, 96, 48,254,230, 56, 16, 66, 14, 82, 74,187, 80, 74,187, 20, 26,160,215, 5, 26,186, 20,255,251, 38, 74,210, 41,250,141,226,
-159,231,205,155, 55, 7,128,170, 44, 9,150, 16, 66,252, 94,147, 64,179, 71, 7,188, 78,227, 77,223,149,166,207, 52,153, 38,211,
-100,154, 76,147,105, 50,205,127,158,230,187,218,254, 93, 80,146, 89, 43, 50,114,197, 63, 79,152, 48, 97, 18,202,208, 60, 88, 36,
-254,167,189, 0,248, 49, 77,166,201, 52,153, 38,211,100,154, 76,147,105,190,229,171,115,129,101,161,157,139,191, 47,105,217,155,
-222,151,182,173, 25,235,154,157,102, 9, 24, 12, 6,131,193, 96, 48,254,222, 36, 23,143, 54, 21, 70,152,132, 9, 19, 38, 76, 42,
- 90, 86, 24,101,202, 7,160, 40, 33, 90, 86,124,187,210, 34,107,102,175,251, 38,152,193, 98,152, 5, 33, 68, 2, 96,148,141,141,
- 77, 47, 27, 27,155,202,105,105,105,225, 89, 89, 89,187, 0, 44,167,148, 26,203,163, 89,171, 42,105, 43,152, 48, 78, 20,193,243,
- 18, 44,122, 24, 70,143,178, 35,205, 96, 48, 24,140, 18,184, 1, 32,160,152,233, 73, 6,112,111,238,220,185,233,115,231,206, 45,
-190,236, 14,128,186,133,235, 37,151, 96,148,244,133,159,245, 37,172,163, 55,103,221, 63,197, 96,249, 86, 36, 67, 32, 98, 50, 8,
- 40, 8,230,132, 68,209,159,203,178,125,109, 31,210, 74,206, 73, 86, 81, 80, 94,103, 20, 38, 18, 1, 37,206,209, 68,121, 52, 85,
- 74,249,185, 4, 68,212,139,166,207,239, 61,161,103,204,190,104, 87, 39,237, 36,148, 91, 47,138, 84, 42,138,116, 43, 7, 28, 81,
-235,113,245, 74, 12,213,149, 55, 87, 43, 86, 36, 54, 68, 68, 71,153, 68,210,192, 96, 50,221,164, 28,142, 68, 69,209,140,191, 83,
-201,235,229, 75,100, 18, 15,213, 66,141,194,216,150,231, 5, 91, 65,228,211,243,116,210, 83,198,104,237,216,157, 33,212,236,201,
- 91, 9, 33, 82, 0,163, 52, 26,205,135,106,181,186, 74, 78, 78,206,115,173, 86,187, 71, 46,151,183, 89,190,124,185,123,227,198,
-141, 45,146,147,147, 9,199,113,142,251,247,239,239,191,114,229,202,182,132,144,206,148, 82, 83, 89,211, 44,152,240,205,163, 67,
-159, 7, 1, 64,149,182,171, 39, 17, 66,142,151,117,110,177, 58,222,164,166, 32, 96, 88,105,235,241, 60,214,220, 13, 45,223,164,
-176, 53, 61,201,106, 2, 84, 5,197, 94,158,195,206,123, 97,108, 78, 44, 6,131,193,248,139, 76,214,171, 92, 55,115,189,255, 57,
-101, 50, 88,132, 98,250,131,103,209, 54, 16, 13,168,229,227, 53, 13, 64,153, 12,150,156,231,127,190,113, 39,222, 9,130, 14,139,
-191,235,179, 73,167, 23, 33,138, 38, 8, 38, 19, 68,209, 4, 81, 16, 32,138, 38, 80,106,192,220,213, 55, 0, 83, 54, 26,212,243,
-249, 25,128,167,185,191, 33, 21,185,245,183, 46, 31,183, 37,166, 76,108,255,101,214,231,209, 9,218,207, 79, 93,143, 75,245,173,
- 76,166, 61,140,196, 22,115, 47,224,149, 42, 17,103, 74,209,181,162,171,195,135,227,135,127,212,176,125,171,166, 92,197, 74, 85,
- 16, 21, 25, 62,228,216,153,139, 98,179,198,142,215,162,226,146,119, 17,130, 3,145,145, 52,225,109, 50,193,193,134,212,177,210,
-168, 86, 75,101,156, 70,202,243,207,146,211,179,230, 39,164, 82,179, 11, 72, 47, 95, 34,179,240,148, 93,109,213,105,144,109,179,
-214,159, 8, 42,181, 69,118,204,243, 96,253,209, 3,139,218,133,201, 30, 93,235,229, 75, 26,154, 99,178, 8, 33, 18, 66,200,193,
-233,211,167, 59, 55,109,218,212, 50, 53, 53, 21, 38,147,201,110,247,238,221,195, 3, 2, 2, 44,220,220,220,228,155, 55,111, 70,
- 78, 78, 14, 4, 65,176,245,242,242,178,237,221,187,183,105,235,214,173,163, 0, 44,126,147,118,229,202, 68,161, 33,176,122,201,
- 96,137,120, 49,129,169,209, 4,181,151, 43, 92,106, 85, 33, 70, 0,144,235,145, 19, 28, 71, 75,157,133, 95, 16, 48,236,246,205,
- 51,159,154, 50,110, 0,130, 1, 20, 70, 64, 52, 0,212, 8, 42, 26, 0,209, 8, 74, 13,104,212,125, 3, 0,140, 42, 79,254, 16,
-130, 54,167, 78,221,112, 78, 76,136,247, 95,178,100,206, 56,223, 42,228, 56,199, 99,251,131, 48, 92,124, 23,147,205, 50, 24,140,
-191,158, 54,109,218,172,207,201,201,153,127,253,250,245,103,239, 74,211,217,217,185, 6,199,113,145,229,121,162, 72,113,234,215,
-175,255, 21,128,143, 11, 63,110,188,117,235,214,210,183, 77, 91,195,134, 13,221, 40,165, 78,133,117,127,226,181,107,215, 98, 89,
- 41,248, 11, 13, 22, 5, 20,160, 34,112,169, 59, 40,129,178,172, 63, 70, 41,148,160, 38, 32,239, 9, 6,244, 8,128,189,173, 29,
- 32,228, 3,162, 30, 16,243, 11, 94, 66, 62, 82,210, 18, 1, 83, 54,144,124, 4, 38, 74, 21,101,222, 43, 99, 38,144,180, 19, 29,
-130,156, 97, 99, 97,129,209,125,124, 43,172,221,251,100,213,186,189,143, 91, 1, 24, 84,218,230,238,238,100,233,132,225,221, 62,
-123,175, 93, 23, 82,217,203, 15,105,201, 49,184,126,227, 74,198,146,181,191, 63,108,215,162, 65,205, 15,123,124,100, 51,108,248,
-184,198,145, 97,247, 27,159, 61,189,111,113, 69, 87,178, 60, 42,142, 78, 44, 87,116,204, 69, 54,236,189,182,109,191, 95,189,118,
-163, 90,101, 81, 1, 89,105, 81, 85, 6,244,235, 81,215,217,142,116, 73, 72, 51, 47,226, 34,245, 80, 45,106,219,101,176, 93,207,
-143, 23, 90, 26, 13, 57,134,184,167, 71, 31,106, 84, 38,174,119,159,209,153, 27,127,158,230, 28,102, 72, 91, 4, 96,164, 25, 82,
-163,166, 79,159,238,236,229,229, 85,113,219,182,109,200,201,201, 1, 0,199,170, 85,171,162,106,213,170,194,185,115,231,224,227,
-227, 3, 75, 75, 75,156, 61,123, 22, 87,175, 94, 69,189,122,245,212, 50,153,236,195, 55, 25,172,154,222,164, 87,247, 86, 13, 86,
-122, 86,114, 83, 23,116,254, 19, 65,169,136,156,156,124,124, 49, 39, 24,233, 89, 58,116,106, 83,191, 90,101, 55,203,167, 28, 68,
- 80, 10, 68,196, 37, 10, 53, 60, 73,159, 71,207,233,225,210, 34, 83,245, 2, 90, 5,221, 9,190,226, 99, 72, 58,136,192, 78,115,
-159,128,226,242,127,221, 17,130,130,207,109,240, 1, 54,148,235, 4, 33,132, 16,223, 42, 16,162,174,204,135,123,253, 33,252,154,
- 13, 71,237, 51, 83, 99,251,237,222,185,186,251,170, 53, 63,253, 90, 94,211,198, 96, 48,254,118,180,183,177,177,105, 25, 24, 24,
-216,254, 93,153, 44,169, 84,170, 18, 4,161,154,171,171,235,211,242,154,172,209,163, 71,127, 73, 8,153, 29, 28, 28, 12, 0,240,
-247,247,159,237,239,239, 95,226, 60,135, 86, 86, 86,185,190,190,190, 51,151, 45, 91,246,227,155, 52,199,143, 31,239, 98, 52, 26,
- 43,223,186,117,171,200,192, 85,174, 95,191,126,229,146,214,213,104, 52, 66,195,134, 13, 35,231,207,159, 31,207,138,200,159, 25,
-193, 2,158, 36, 92,248,170,174, 62, 45, 15, 4,120, 82,186,161,122,121,168,165,206, 40, 44, 92,249,125,247,239, 27,213,181, 70,
- 66, 74, 62,142, 93, 76,132,104, 50, 66, 20, 5, 8, 66, 81, 4, 75, 64,231,166, 14,104,134,207,177,252,215,167, 48,154,196, 5,
-111,210,252, 67, 68, 3,226,199,245, 90,124,180, 69,160, 84,166, 82,144, 44, 79, 55, 27,135,111, 7,214,230, 70,247,241,133, 86,
-103,250,176,102,101,114,238, 97, 4,221,240, 38,205, 90, 85,108, 7,127, 49,100, 8, 17,213,181,112,243,234, 97,140,250,118,114,
-104, 74,106,250,220,200, 24,220, 58,112,234,124,165,138, 78, 21,166, 47,157, 51,185,158, 79,221, 14,232,192,105,113,254,226,133,
-143, 1, 76, 44, 75, 58,157,156,136, 90,204, 71,167,134,129, 13,102,110,218,113, 80,205,229,220, 6,162,182,194,198,166, 49,214,
- 44,159,239,248,126,143, 94,139, 1,188,103,142,166, 70, 97,108,219,172,205,199, 48, 26,114, 12,198,252,236,124,109,122,136, 65,
-200, 75, 50,112, 82, 78, 18, 80,167,102, 82, 98,226,153,118,230,228,145, 70,163,233, 25, 20, 20,100,177,117,235, 86,248,251,251,
-195,198,198, 6,167, 79,159,198,221,187,119,145,154,154,202, 81, 74, 97, 97, 97,129,121,243,230,193,195,195, 3, 89, 89, 89,136,
-140,140,180,149, 74,165,118,111, 74,167, 66, 34, 25,184,112,254,124, 53,199, 1, 16, 77, 0,253,239, 43, 46, 33, 9,185,185, 90,
-216, 88,200,224, 96,167,122,177,220,100,212,243, 13, 58,126, 51, 28,192,225, 55,237,251,221, 80,250,176, 86, 21,114, 25,212,228,
- 67, 5, 45, 64,113,249, 65, 56,125, 97,122,234,120,147,154,254,205, 63, 25,198,243, 88, 83, 90,249, 44, 9,223, 42,232, 24, 80,
-195, 66,163, 50, 62, 68,204,153, 81, 8, 21, 20,212,169,246,167,232,211,239, 75,245,154,159,215,116, 34,132,140,166,197, 30,194,
-249,103, 12, 47,102,154, 76,243,159,160,217,171, 87, 47, 30, 0,118,238,220, 41,252, 29,211, 41,145, 72, 12, 63,253,244,147,227,
-240,225,195,143,153,107,178, 74,189, 30, 21, 60,191,235, 41, 0,179, 77,214,171,154,161,161,161,115,231,206,157,139,223,126,251,
- 13, 0,176,109,219, 54, 84,171, 86,173,196,109,239,222,189,171,153, 52,105,210, 92, 0, 63,190, 73,243,254,253,251, 85,230,204,
-153,131, 95,127, 45,120, 50,217,150, 45, 91, 80,163, 70,141, 18, 53,111,223,190,205, 79,158, 60,185, 10,128,248, 63, 59,143,254,
-177, 6,139, 16, 66, 41,165,164,148,245,159, 59, 91, 74,235,194,104, 4,128,231,101,253,177,144, 80,186,184, 78, 85, 73,187,238,
-237, 71, 55,173, 86, 25,152,187,122,117,116, 70,150,174, 21,207, 65, 4, 0, 65, 4,103,105, 33, 61,179,120, 92, 35,143,244, 44,
- 61, 14,156,139,189, 24,242,156,150, 41, 20,122,239, 41, 61, 13,192,229,197, 5,214,147, 84, 29, 52,237,252,166,237,115, 90,250,
-141,233, 87, 11,123,207, 70,140, 68, 41,225, 12, 11,181,140, 39, 9,187,144, 46,220, 69,195,134, 93,113,253,122,184,247,157,171,
-123,127,217,177, 99,179, 48,168,207,135,124, 53,255,158,200, 75,125,132,200, 43,115,144, 29,121, 18, 86,106,137,212,220,244, 57,
-216,144, 58, 42,149,234,203,138,206,149,186,140,159, 56, 94,210,165, 75,111, 37,151,123, 31, 52,126, 39, 68, 67, 14,196,220,104,
-216, 89, 4,130, 16, 56,153,125,151, 36,231,109, 44, 44,108, 12,177, 15,182, 61, 50,228, 60, 55, 64,155, 32,208,188, 56, 66,228,
- 82,234,238,232, 12,158, 51, 89,155,163,163, 82,169,170, 36, 37, 37, 33, 59, 59, 27,214,214,214, 88,178,100, 9, 28, 29, 29,161,
-213,106,241,248,241, 99,234,238,238, 78,206,156, 57, 3, 55, 55, 55,164,167,167, 67,175,215, 35, 47, 47, 47, 81,175,215,191,177,
-210,208, 25, 76,171,191, 30,247,117,179, 74,238, 78,124, 81, 4, 75, 20, 69,212,173,229,137,214,205, 27,225,196,131, 27,216,123,
-247, 25, 68, 42,162,232,251,136,152,148, 92,131, 40,108, 49,187,242, 20, 77,128,160, 45,209,128,149, 39,202, 84,187, 54, 81, 11,
- 57,152,208,208,215,114,208,196, 1, 21, 45, 44, 20, 28,116, 74, 1, 58,189, 17,217,143, 86,161,130, 71, 29,168,149, 74, 82,191,
-190, 86, 2,192,200,170, 18, 6,227,143, 52,104,208, 32, 64,173, 86,127, 5,160, 69,126,126,190,165, 40,138,104,214,172, 89, 54,
-199,113,231,242,242,242,150,222,188,121,179,188,125,101,138,174, 85,244, 93,166,183, 82,165, 74, 40,171,201, 42,141,184,184, 56,
-173,171,171,107,153, 76, 86,113,146,147,147,121, 31, 31, 31,104,181, 90,136,162,136,220,220, 92,236,221,187, 23, 89, 89, 89, 16,
- 69, 17, 42,149, 10, 75, 79,230, 35,247,193, 86,108, 93,187, 16,201,201,201,188, 25,154,164, 70,141, 26,208,233,116, 48,153, 76,
-200,207,207,199,241,227,199,145,159,159, 15,163,209, 8,169, 84,138, 57,251, 50,144,127,127, 43, 54,252,252, 3,146,147,147,201,
-159, 93, 86,204,244, 32,255,127, 6,171,104,199,254, 23, 59, 72, 33, 76, 95,181,229,228,153,217, 95,189,135, 79, 63,172,231,177,
-104,227,229, 86, 15,158,211,109, 0, 80,211,147,244, 27,216,185,170,135,141,133, 28,223,173,189, 5, 16, 58,253,109,127,239,238,
-115,250,172,118, 53,242,237,238, 51, 81,199,166,126, 86, 7, 94,110,150,222,222,222, 68, 30, 26, 74,245,165,165,116,196,148, 21,
- 48, 25,151, 26,199, 13,255, 64,218,176,213, 32,212, 13, 58,202,167,133, 31,197,205,221,159, 98,195,158, 43,121, 82, 9,148, 3,
-155, 75,205,158, 13,223,222,154,212,111,212,168,241,177, 53,107,215, 41,157, 92,189, 9, 49, 38, 3, 89,231, 96, 74, 56,142,124,
-109, 10,244,218,108, 24, 68, 75,100, 70,157,134, 66, 78,205, 62,177,141,122, 49, 53, 35, 37, 76,197,139, 25,164, 70, 77,187,166,
- 72, 63, 13,216,246, 66,196,237, 75, 55,194,147,226, 44, 5, 81,146,102,142, 78, 78, 78,206,115,163,209, 88, 1,128,195,169, 83,
-167,224,224,224,128,236,236,108, 24, 12, 6,104,181, 90,163,173,173,173, 60, 53, 53, 21,249,249,249,200,207,207,135,149,149, 21,
-110,222,188,153, 99, 50,153,222,248, 12,193, 71,207,233, 97,127, 87,226,116, 90, 14,139,162,101, 60,143, 10, 38,131,254, 70,235,
- 38,181, 17,124,231, 49,118, 30,188, 22, 32, 8, 72, 45,250, 62,151, 34, 43, 34,130,230,155, 95,176, 76,160,194,127,199, 49, 20,
-117,126, 47, 79,231,118, 95, 79,210, 64,161,144, 46,154, 55,169,115,141, 22,190,130,130,232,226, 65, 0,168,149, 18,228,235, 5,
- 88,187,120,131,234,179,169, 86,167,203,188,127, 31, 38, 48, 24,140, 63, 68,171,146,146,146,150,219,218,218,126, 56,112,224, 64,
- 85,139, 22, 45, 56,142,227,176,100,201, 18, 36, 36, 36, 88,181,111,223,190,203,230,205,155, 91, 55,111,222,124,151,163,163,227,
- 40,115,162, 90,197,174, 89, 82, 0, 69, 38,130,134,133,133,153, 58,116,232,128,176,176, 48,174,208,120,137, 0, 12,229,237, 31,
-249,119, 52, 89,241,241,241, 72, 78, 78, 70,187,174, 93,177,116,222, 60, 52,111,222, 28,109,219,182, 5, 0,156, 60,121, 18, 13,
- 45,174,193,174, 75,115, 60,124,104,126, 85, 23, 29, 29,141,212,212, 84,116,234,214, 13, 63,175, 90,133,250,245,235,163,122,245,
-234, 0,128, 51,103,206,160,181,243, 51, 88, 84,109,141, 71,143, 30,253,233,229,229,127,233, 65,254,146, 8,214,255,138,123,207,
-232,117, 95, 79,114,100, 96,231,154, 29,123,183,247,198,150,253,183,167,251,250,146,223, 11, 12,136, 98,250,160, 46, 85, 17, 18,
-150,142, 83,215,226,142,132, 60,167,215,223,197,111,154, 76,240,112,172, 96, 1, 16, 41,114,243,141, 38, 43, 43,152,125,226,221,
-139, 72,169,250,209,232,159,134,124,245,209,149, 73,163,251,249, 97,235,142,219, 88,252,219,163,111, 12, 6,108,250,176,153, 93,
- 20, 96,126, 95, 52, 75,181,234,243, 53,107,215, 41,157, 43,200, 8, 34,151, 66,208,198, 64,208,165,194,144,159,129,172,204, 12,
-196,196,167, 32, 61, 79,130,200, 68,162,141, 77,208,111, 53, 87, 55, 51, 79,178,255,192,239, 11, 6,245,252,112, 96,133,167,215,
-215, 94,221,119, 90,235,208,167,221,145, 92,185,166,146,205,185,235, 39,109, 51,181,146, 95,204,209,209,233,116,187,142, 28, 57,
-210,187, 82,165, 74, 14,247,238,221,131, 78,167,131, 40,138,232,216,177, 35, 80,236, 1,152,143, 30, 61,210,105,181,218,164, 7,
- 15, 30,228, 68, 69, 69,229, 1, 88, 94,154,118, 97,135,245, 23,149, 74,205, 42,164,151,175,143, 11, 32,104, 81,179,170, 51,140,
- 2, 90, 61, 12,167, 43,202,239,220,141, 5, 17, 44,130,160, 90, 85,200,114, 16, 4,221, 60,189,196,167, 65,235, 49, 40, 75, 4,
-203,215,155,188,231,231,227,186,102,201,156,137,182,118, 14, 30, 60, 4, 45,136, 41,139,138,105, 87, 33,201,125, 10, 43,247,206,
- 16,172,131,176,230,199, 69,185,130, 64,119, 22,111, 30,100, 48, 24, 47, 12,197, 20, 31, 31,159,158, 43, 86,172, 80,223,185,115,
- 7,185,185,185,184,118,237, 26, 22, 44, 88,128, 15, 63,252, 16,238,238,238,220,222,189,123, 53, 35, 71,142,236,249,228,201,147,
-100, 0,223,149,114, 1,182,175, 80,161,130, 77, 74, 74, 74, 28, 0, 89,161,201, 34, 17, 17, 17, 56,115,230, 12, 87,183,110, 93,
-154,148,148,100, 26, 61,122,180, 77, 78, 78, 78,157,101,203,150, 93, 4,144,248, 79,137,100,237,218,181, 11,183,111,223,198,244,
-186,117, 49,198,197, 5, 21, 42, 84,192,185,115,231, 64, 41,133, 70,163, 65, 90, 90, 26,126,253,245, 87,180,108,217,210,236,244,
-236,223,191, 31, 55,110,220,192,204,122,245, 48, 82,169,132,181,181, 53,206,156, 41, 24,176,175, 80, 40, 16, 19, 19,131,211,167,
- 79,163,121,243,230,172, 64,151, 19,179,163, 47, 45, 9,145, 16, 2, 39,163, 81, 11,131,137,130, 16,184,248,250, 18, 89,185, 92,
- 29,135, 25,203,182, 94,166, 42,169, 9,131,223,175,230, 10, 45,134, 64,139, 33,159,118,243,113, 85, 43, 36, 88,182, 35,132, 74,
- 56,204,120, 23, 59, 88,187, 10,169,102,103,169,152,214,181,101,117, 68, 36,230, 35, 60, 54,231, 88,112,176,249,243, 54, 61,127,
-142,244,152, 56, 44,205,209,155,192,243, 18,100,106, 41, 98, 98,240, 75, 82, 18,242,203,154, 22, 94, 66,222,115,114,245, 38, 52,
-113, 47,242, 51, 30, 35, 55, 35, 6,169,169, 49,200,206, 76, 69,110, 94, 54,178,179,243, 16, 31, 27,135,163, 87,226,210, 77, 58,
-225,162,185,186,191, 29,207,155,116,235,214,197,199,215,175, 30,215, 88, 57,212,177,245,173,172, 16, 53,150,174,150,231,174,133,
- 88,199, 37,233, 30,253,118, 52,207,220, 99,185,124,215,174, 93,233,183,110,221,122,228,238,238, 30,101,109,109, 77, 9, 33,136,
-143,143,127,233,117,243,230, 77,197,209,163, 71,243,162,162,162,246, 1,232, 82,214, 41, 26,234,120,147,154,173, 27, 87,251,190,
- 83, 75, 63, 64,208,162, 75,203,154,104, 30, 80,229,251, 58,222,164,102,185,253, 21, 45,104, 34,188,188,173,181,207,229,173, 77,
- 63,189,180,169,161,143, 62,118, 75,153,117,136,136,145, 99,122, 87,182,178, 83,233, 57, 34,228,128, 72,173, 1,181, 55,225,220,
-251, 17,105,253, 77, 36, 42,175,146,208,179, 95,159,228,159,183, 28, 92,109, 47, 98, 41,171, 66, 24,140, 18, 46, 44, 28,247,105,
-255,254,253,213, 42,149, 10, 74,165, 18,155, 55,111,198,231,159,127, 14,133,162, 96,204,146, 90,173,134, 74,165, 66,255,254,253,
-213,132,144,193,102, 72,166,101,101,101, 89,244,232,209,195, 3,128, 26,128, 70,175,215, 91,164,164,164, 88,113, 28,103, 93,171,
- 86, 45,199,233,211,167,251,228,228,228,212, 57,112,224, 64, 18,128,148,242,164, 59, 51, 51, 19, 97, 97, 97, 56,124,248, 48,134,
- 13, 27,150,107, 50,153,228, 22, 22, 22,227,223, 50, 58, 35,117,114,114, 82,187,186,186, 86,160,148, 86,167,148,114,148,210,138,
-229,209, 18, 4, 1, 13, 26, 52,192,201,243, 55,176,102,231, 37, 44,250,113, 19,162,162,162, 80,163, 70, 13,136, 98,249, 7, 52,
- 7, 4, 4,224,244,233, 11,216,186,239, 58, 22, 44, 89,141,152,152,152,215,246,201, 98,148, 49,130, 85, 90,104,206,183, 10,169,
-237,228,167, 88, 55,249,125,175, 26,146, 90, 51, 64, 36, 42,236,222,112,160,241,196,185, 63,221,170,227, 78, 62,189, 27, 67,203,
-212,142,126, 55,148, 62,172,229, 73,118, 94,191, 31,243,209, 71,237, 60,177,229,112,232, 4, 0,248,168,157, 39,174,135, 36,227,
-218,253,164,157, 15,158,151,111,206,162, 34,106,120, 18,111,142, 98, 80,245, 42, 14, 67,150, 78,237,170,113,170,160,194,247,171,
- 79, 67, 4,182,154, 95,152, 1, 0,238, 0, 50,255, 27,167, 32, 69,209, 28, 27, 65, 68,153, 66,153, 28,161,199, 19, 34,239,244,
-174,192,217,145,156,172, 20, 36,196, 69, 35, 59, 43, 7, 54, 86, 82, 88,171,121,184,186, 56, 66,109,237, 14, 81,146,108,243,248,
-121, 78, 32, 0,179, 39,222,204, 50,202,190,184,116,233,196,197, 38,117,135,234,106, 86,145,154, 36, 82, 94,121, 35, 36, 66,145,
-173,149,141, 52, 87,131, 82,106, 34,132,116,185,112,225,194,168,203,151, 47,247,112,113,113, 33, 3, 7, 14, 68,135, 14, 29,160,
- 80, 40,160,213,106,145,158,158,142, 67,135, 14, 17,147,201, 20, 4, 0, 46, 46, 46, 21, 43, 87,174,188,129, 16, 18, 27, 30, 30,
- 62,208,156,223,145,203,229,139,166,141,234, 36, 53, 25,114,240,221,242, 67,152, 54,162, 45,166,143,104, 41,237, 50, 44,118, 17,
-128,246,229,202,112,209, 4, 81,208, 33,104,192,249,130, 81,132, 4, 65, 55,142,205,242, 1,110,155, 45,225,239, 79,164,188,132,
- 84,175,233,150, 47, 21, 98,119,128, 40,221, 40, 95,161, 5, 96,225, 67,168,133, 31, 86, 46,155,150,187,110,221,186,147,148,195,
-156,255,176,119,222,225, 81, 84,109, 27,191,207,204,108, 79, 15,233,133, 64, 40,161, 24, 8,217, 20,170, 4,233, 72, 17, 4, 21,
- 17, 21,164,169, 32, 69, 5,108, 8, 40, 96,161, 88, 0, 65, 80, 81,138,244, 46, 16,164,183,144, 2, 4, 66, 2, 4, 72,239, 61,
-217,100,235,204,249,254, 72, 54, 95,192,148, 77,192, 87, 95,222,249, 93,215, 94,187,179, 59,123,207,153,153, 51,115,238,121, 78,
-139, 75,162,241,226,237, 67, 68,164,118, 52, 26,205,212, 69,139, 22,109,106,221,186,181,210,223,223, 31,107,214,172,193,144, 33,
- 67,170,205, 85,167, 78,157,144,154,154,138,133, 11, 23,106,203,203,203,167, 89,112,111, 18, 8, 33, 55, 79,158, 60,217,126,232,
-208,161,238, 79, 63,253, 52,233,208,161,131, 68, 46,151, 11, 58,157,206, 42, 51, 51, 83, 30, 31, 31,143,168,168,168,187, 90,173,
- 54,150, 82,202, 55, 37,221, 11, 23, 46,212, 56, 57, 57, 89,205,156, 57, 19, 95,126,249,101,250,153, 51,103, 2, 31,245, 88,184,
-187,187,183,100, 24, 70, 72, 79, 79,191,239,233,233,233,158,150,150,214,164,198,225,230, 96,249,181,107,215,112,246,142, 0,153,
-149, 3,146,226, 75,112,124,255, 62,140,155, 60, 5, 38, 83,211, 91, 43, 92,185,114, 5, 91,142,197,195,173,101,123,104,227,175,
- 96,215,174, 93,152, 54,109,218, 35,105, 54,114,223,200, 19,219, 6,203,188,131, 15,255,216,186, 53,145,201,116,248, 96, 96, 55,
-207, 89,163,251,182,102, 77,229,153, 16, 4, 1, 44, 0, 39, 27, 6, 63,173, 95,215,114,199,158, 63, 78,118,106,206,174,129, 94,
- 88, 24,155, 77,203, 45,118,245, 28, 62,251,118,235,141, 81, 91,150, 60,195, 77, 27,211,222, 1, 0,164, 18, 6,223,110,189, 97,
- 34, 28, 62,107,100,148,170, 39, 39, 97,182, 24, 41, 85, 82,158,166,120,184,217, 89, 61,215,175,179,231,136,254,129, 8,236,224,
- 5,222,164,195,130,213,135,177,251,232,205,213,241,247,235,239,246,255,128, 73,107,105,143, 72,143,236,119, 25, 14,159,145, 26,
-246,202,213, 21, 82, 41,135,153,109,189, 21, 50, 52,162, 9, 78,105,121,197,218,249,115,103,246,251,240,237,225,142,134, 82, 21,
-185,157, 84, 8,240, 90, 88, 41,173, 97,237,214, 11,246,182,109,160, 45,201,132,148,139, 86,185, 58,165,141,105,140,193,218,115,
-184,244,206,219,227,219,177,159,126, 23,233,164, 47, 7, 53, 25,162,153,114, 45,161,187,194, 75, 18, 27,153,209,141, 94, 94, 94,
- 83, 4, 65,112, 54,153, 76, 6,103,103,103,233,246,237,219,161, 80, 40,192, 48, 12, 2, 2, 2,160, 80, 40,244, 30, 30, 30,197,
- 0,224,226,226, 98, 92,177, 98, 5, 55,113,226, 68,139,162,153, 29,125,137,247,200, 1, 79,245,104,102,203, 98,211,158, 11,216,
-119,252,230,190,150,158, 86, 35, 38,140,120, 10, 97, 33,158, 61, 58,250, 18,239,184,123, 52,181,241, 87,168, 17, 53,123, 17,118,
-110, 77, 58, 4, 15,248,168,214,222,131,117,209, 50, 6,194,173, 86, 20,132,176,160, 32,128, 54, 29,166,180,205, 96,125,167,211,
- 61,123, 63,171,248,113,253,134,165,113, 73,141,235,116, 33, 34,242,191,200,213,171, 87,255, 8, 9, 9,153, 55,126,252,248,101,
-227,199,143,151,189,246,218,107,236,165, 75,151, 32, 8, 2,130,130,130,176, 97,195, 6,211,182,109,219,140, 58,157,110,238,213,
-171, 87,255,176,240,222,164, 35,132, 92, 61,116,232,144,227,205,155, 55, 29, 37, 18,137,147, 32, 8,246,229,229,229,121,122,189,
- 62,191,176,176, 48, 7, 64, 97, 83,171,237,181, 90,173,226,230,205,155, 17, 6,131,193, 99,230,204,153,237,250,245,235,231,167,
- 86,171, 67,162,163,163,155,220, 84,133, 97, 24,169, 32, 8, 21,148, 82,165,121, 51,206,206,206, 86,185,185,185,154,166,232,177,
- 44,139,194,194, 66,148,166, 39,162, 60, 47, 15,237,216,114,116,113,116,134,141,141, 13,140,198,166,247,181, 41, 43, 43,131,220,
-148,134,251,145,247,145,151,151,132, 54, 45,187,192,202,202, 10, 58,157,238, 63,150,103,158, 52,115,245,128,193,250, 75, 65,216,
-156, 76,114,144,226,203,215,198,248, 74,125, 91,120, 66,159, 27,133, 43,137, 26,124,180, 49, 36,158,149,218,232,222,126,181,127,
-151, 62,253,156,209, 59, 44,152,180,240,249,232,173,101,203,214, 78,233,232, 77, 62,136, 75,165,171, 45,217,240,245,219,244,126,
-135,150,228,151,147, 81,153,111,120, 57, 85,128,130,226,100, 84, 38,174,221, 41,252,229,230,125,122,191, 81,153, 78,202,252, 26,
- 19, 29,235, 8, 83, 5,178,238,236,247,115,115,245, 1, 4, 3,140,250, 10, 92,136,185,129, 13,219,207,152,162,175,167,190,127,
- 51,137, 90, 84,216,222, 73, 41, 58,158,152, 86,220,111,209,212, 16, 12,238,209,252,181,165, 27,163, 95,170,238,172, 66, 41, 6,
- 5,217,223, 28,215,199, 70,165,228,244, 48, 65,134,232,219,197,225,150,232,102,230,209, 24,119, 39, 50,234,218,181,171,175,123,
-186,217,245, 27, 28,172,116,114,182,133,212,198,169, 5,100, 86,142, 16, 76,101, 40, 47,184, 5,202,107, 65, 32,248, 54,230, 24,
-120,123,123,247,156, 57,115,166, 98,202,148, 41, 40, 43, 43,195,166, 77,155,176,102,205, 26,120,123,123,247, 76, 77, 77, 61,215,
- 24, 45, 65, 16,156, 15, 28, 56, 0, 84,182,117,192,159,127,254, 9, 15, 15, 15,216,217,217,161,180,180, 20,227,199,143,151,125,
-252,241,199, 0,128,152,152, 24,137, 82,169,108,196, 69,132, 49,131,122,248, 18,240, 21,216,121,228, 70, 62, 20,120,125,119,120,
- 66,143, 9,195,124,155, 13,238,234, 78, 14,157,190, 63, 6,192,215,141,191, 56,121, 64,168,120, 32, 74,138, 70,246, 30,220, 65,
- 41,223,209,151,220,221, 22,158,107, 53,122, 72,160, 82, 42, 97, 8,213,166, 65, 32, 82,178,106,205, 79,101, 86, 28,126,130,136,
-136,136, 69, 92,190,124,121, 99,215,174, 93, 47,254,252,243,207,115, 24,134,233,161,211,233,156, 1, 8,199,142, 29,203,226,121,
-254,108, 69, 69,197,183, 81, 81, 81,183, 27, 89, 8, 83, 0,249, 85,175,219,143, 51,189, 28,199,253, 94, 82, 82,178,152,231,249,
-209, 71,143, 30, 93, 62,114,228, 72,236,223,191,127, 2,106, 31, 41,220,210,123,105, 73,102,102,230,125, 47, 47, 47, 39, 31, 31,
- 31, 39,141, 70,147, 45,151,203,221, 0, 36, 54, 69, 79, 46,151,227,236,217,179, 24,220,179, 23,174, 30, 79, 70,123, 87,111,244,
- 25,247, 42,246,158, 60, 9,150,101,155,186,223, 56,123,246, 44, 70, 13,233,131,221,187,119,163,101,160, 63,222,126,251,109, 28,
- 59,118, 12, 28, 39,206,166,247,183, 24, 44, 34,224,227,240,223,151, 72, 33, 24,177,115,203,151, 56, 30, 89,174,143, 79,195,167,
-237,210,177,122, 39, 74,133,236,252, 93,111,132,158,190,251,249,132,215,134,170,158,233,221, 31,207, 60,221,135,123, 42,160,247,
- 60,212, 24,127,131, 16,226, 95,223, 88, 25, 84,192,178, 31,119,197, 79,220,118,248, 22,129,169, 20, 47, 13, 15,166, 84,192,178,
-122, 35, 95,117,105,154, 42,128,226, 8, 28, 12,143,128,155,107, 58,110,223, 75,193,222, 35,209,169,197,165,229,191, 17,130,205,
- 55,147,234,142,138, 60,172,153, 95,170,127,107,208,244,131,223,191,208,191, 85,255, 89, 99, 59, 99,223,138,103,101,247, 50,138,
-193,243, 38,244,239, 76, 65,218,203, 84, 2,120, 92, 72,228,232,143, 7,211,247,150,233,249, 89,150,166, 51, 51,143, 70, 3,136,
-246,117, 32,182, 55,238, 96,240,200, 94, 46,159,119, 13,228, 93,202,178,163,145,153,114, 7, 69, 21, 10,164,229, 19,128,226,174,
-197,251, 14, 32, 53, 53,245, 92,112,112, 48, 0,160,162,162, 2,105,105,105, 48,153, 76,200,200,200, 56,215,216,227,201, 48, 76,
-238,144, 33, 67,156,117, 58,157,105,236,216,177, 92, 94, 94, 30,252,252,252, 42,163,112,165,165,248,227,143, 63,170,123,155,220,
-184,113, 3, 29, 59,118,180, 56,157,206,246,202,113, 65, 29, 29,113,227, 86, 10,146, 51, 74,182,198,221,163,134,142,190,100,235,
-181,132,236, 25,221,187,184,192,209, 86, 54,174, 54,131, 85,151,102,231,214,164, 3, 8,186, 67, 48, 86,246, 34, 36,232,222,185,
- 53,233, 96, 73,207,193,218, 52, 57, 14, 19,150,255,158, 52,119,199,233,220,161,239,191,209,203,166, 71,183,193, 50, 8, 70, 90,
- 86,174, 51,222,184, 71, 75,155,162,249,168,136,154,162,230,127,171,230,165, 75,151, 18, 0,188,241,223,176,239, 39, 78,156,152,
- 9, 0,106,181,122,219,238,221,187,151,108,218,180, 73,102,109,109, 29,252, 40,154, 25, 25, 25,183,170,214,203,245,240,240,232,
-144,159,159,127,221,203,203, 75,214, 24, 77,137, 68,146,219,185,115,103,231,231,158,123, 14, 38,147, 9,119,238,220, 65,114,114,
- 50,134, 77,120, 29, 14, 14, 14,136,136,139,195,157, 59,119,240,201, 39,159, 64,167,211,225,254,253,251,185, 13,105, 74,165, 82,
-131,191,191,191,116,248,240,225, 48,153, 76, 72, 76, 76, 68,106,106, 42,166, 79,159, 14, 59, 59, 59, 36, 36, 36, 32, 49, 49, 17,
- 31,127,252, 49,116, 58, 29,146,147,147, 13,255,137,115,244, 63, 99,176, 40, 1, 15,193,136,226,200, 5,248,225, 32, 12, 70, 30,
-129, 55,210,104, 82,141, 85,126,236,226, 77, 14, 95,187, 30, 31, 23, 29,241,140, 12, 37,177,160, 64,163,234,189,227,147,105, 86,
-112,123,174, 12,166, 82, 27,228,254,129,123, 25,165,154,248, 38, 76, 59,195, 27,132,241, 93, 66,186,110, 21, 64,165, 2, 79,119,
-152,128, 19, 28,197,189, 27,247, 17,215,148,112,113, 90, 26,205, 0,240, 92, 11, 47,242,244,129,179, 73,203, 38, 14,107,239, 63,
-109,244, 83, 40,215,148, 66, 66,181,184,158, 37,195,247,251,179, 35,243, 75,245,239,165,166,210,232,166, 28,248,123,133,180, 4,
-192,182,246, 45, 56, 90, 90,113,227,195, 81,125,124, 90, 18, 56, 33, 59,183, 24,187, 78,102, 94,202, 40,168,191, 87, 77, 29, 17,
- 44, 76,157, 58, 21,165,165,165,216,182,109, 27,142, 30, 61,218,164, 8, 86, 90, 90, 90, 27, 0,240,240,240,200,182,177,177,225,
- 94,127,253,117,243, 80, 13, 40, 41, 41, 65,126,126,190,126,230,204,153, 50, 0,144,201,100,198, 65,131, 6, 89,252,152,211,198,
-199,206,147,131, 14,123,255,188, 5,112,248,189, 42, 23,254,190,239, 84,242,140,206,109, 29,209,166,185,109, 43,181, 7, 81, 90,
- 50, 77, 14, 80, 57, 85, 78,228,145,133,126,218,219, 31,131, 82, 35,206,174,113,240,235, 53,173,112, 10,154, 56,194,250,181,219,
- 52, 3,192,140,142, 45,201,198,119, 62, 63, 50, 47,200, 63,174,251,187, 83, 71,216, 80, 34, 78,140, 46, 34,242,191, 64,116,116,
-116, 73, 64, 64,192,235,207, 60,243,204,172,178,178,178, 21,143, 67,147, 82,106,114,115,115,203,116,115,115,243, 51, 24, 12,141,
-154,203,212, 96, 48, 76,255,254,251,239,191, 51, 26,141,206,230,239,116, 58, 29,182,108,217, 2,131,193, 0,169, 84, 10,149, 74,
-133,196,196, 68,176, 44,155,107, 50,153, 26,108,119, 43, 8,194,221,213,171, 87,183, 50, 24, 12,213, 77, 59, 76, 38, 19, 54,111,
-222, 12,157, 78, 7,185, 92, 14,107,107,107,220,185,115, 7, 82,169,212, 32, 8,194, 93, 49,103, 52,193,212,215,229, 63, 58, 54,
- 39,147, 64,241, 1, 40, 8, 24,124, 94,215,196,206,213,235, 1,120,120, 2,104, 75, 28,110, 39, 63,210, 71,198,178,155, 0, 64,
- 43,240, 19,111, 36,208,240,127,211,147, 13, 33,132,248,120, 97,140,187,147,213,183,239,142, 11,176,250,242,183,171,154,204, 2,
-205,196,148, 20,122,232,113,165,179,185, 43,105,233,233,128,121,114, 25,236, 77, 38,196, 37,229, 98,115,106, 14,189,215, 88, 77,
- 15, 15,143,114, 31, 31, 31, 56, 58, 58,162,160,160, 0,201,201,201,200,200,200, 80, 53, 53,157,158,158,158, 93, 9, 33,123, 4,
- 65, 80, 60, 28,225, 50,155, 48,119,119,247,230, 50,153,236,129, 70,238,245,105, 62,213,154, 44,241,111,237, 48,245,198,221,226,
-205,215,239,240,213, 38,168, 99, 75,178, 40,176,131,211,155,177,119, 10,126,188,118,155,159,223,152, 8,214,195,147, 61, 91, 58,
-246,149, 69,249,211,151, 60, 35, 80,188, 3,130,204, 27,247,232, 84, 49,146, 33,106,138,154,162,166,168, 41, 70,176, 44,117,214,
-127,219, 11,128,255,147,162, 9,128,107,209, 2,109, 1,200,254,229,233,252, 16, 64, 57,128, 15,255,173,233, 12, 12,132,228,127,
- 57, 47,137,154,162,166,168, 41,106,138,154, 79,254, 75,172,246,104, 68,136, 23,143,185, 81,229,223,148,206,207, 1,124,254,239,
- 14,193, 83,113,106, 25, 17, 17, 17, 17,145, 39, 26, 70, 60, 4, 34, 34, 34, 34, 34, 34, 34, 34,143, 23, 2,192,191,182, 31, 26,
- 83,183, 74, 8,241,111,236,134, 27,210, 23, 53, 69, 77, 81, 83,212, 20, 53, 69, 77, 81,243,201,211,108, 72,251, 73,105,219, 69,
-254,206,169,212,196, 6,128,162,166,168, 41,106,138,154,162,166,168, 41,106,254, 47, 34, 86, 17,138,136,136,136,136,136,136,136,
-136, 6, 75, 68, 68, 68, 68, 68, 68, 68, 68, 52, 88, 34, 34, 34, 34, 34, 34, 34, 34,162,193, 18, 17, 17, 17, 17, 17, 17, 17, 17,
- 17, 13,150,136,136,136,136,136,136,136,200,191,134,191,181, 23,161,136,136,136,136,136,136,136,200,255, 34, 12, 0, 16, 66,104,
-213,171,183,120, 72, 68, 68, 68, 68, 68, 68, 68,254, 83, 60,169, 30,164,122,170, 28, 74, 41, 33,132, 80, 84, 14, 62, 42, 34, 34,
- 34, 34, 34, 34, 34,242, 31,225, 73,244, 32, 76, 77, 7, 9, 32, 76, 60,205, 34, 34, 34, 34, 34, 34, 34,255, 73,158, 68, 15,242,
- 64, 4, 75, 60,197, 34, 34, 34, 34, 34, 34, 34,255,105,158, 68, 15, 34,246, 34, 20, 17, 17, 17, 17, 17, 17, 17,121,204,136,189,
- 8, 69, 68, 68, 68, 68, 68, 68, 68, 30, 51, 98, 4, 75, 68, 68, 68, 68, 68, 68, 68,228,191,201, 96, 17, 66,252, 69, 77, 81, 83,
-212, 20, 53, 69, 77, 81, 83,212, 20, 53, 69,131, 37, 34, 34, 34, 34, 34, 34, 34, 34, 34, 26, 44, 17, 17, 17, 17, 17, 17, 17, 17,
-209, 96,137,136,136,136,136,136,136,136,136, 6, 75, 68, 68, 68, 68, 68, 68, 68, 68, 68, 52, 88, 34, 34, 34, 34, 34, 34, 34, 34,
-255, 16, 4, 64,173, 61, 1, 40,165,215, 45, 22,105, 66,111,130,134,244, 69, 77, 81, 83,212, 20, 53, 69, 77, 81, 83,212,124,242,
- 52, 27,210,110,140,255,248, 87, 27,172,191,115,160, 81, 66,136,255,227, 62, 80,162,166,168, 41,106,138,154,162,166,168, 41,106,
- 62,121,154, 79, 26, 98, 21,161,136,136,136,136,136,136,136,200, 99,134,251,167, 54, 76, 8, 97,106, 24, 60, 1, 0,165,143, 24,
- 78,251, 59, 52,255,173, 16,128,233,176,112, 33, 39,207,204,108,212, 57,212,185,187,155,110, 46, 88, 96,162,149,199, 71, 68,228,
-191,142, 59,197,103,171, 63,183,181,127,154, 84, 94, 14, 0, 0,122,187,232, 76,157,215,123, 27,187, 94,226,193, 19, 17,169,131,
-168,168,168,114, 31, 31, 31,116,234,212,233,118, 86, 86,214, 90, 74,233,143,226, 81,249, 23, 25,172, 14,174,202, 16, 31, 47,167,
- 65,135,163, 82, 62,173,111, 61,181, 90, 45, 25, 58,116,232,143, 0, 70,215,252,126,216,176, 97, 15,172, 39,145, 72,242, 11, 11,
- 11,125, 79,157, 58,101,106,104,219,106,181, 90, 50,116,216,176,191,106, 14, 31,254, 23,205, 20, 71,199, 86, 49,235,214,153,106,
-124, 73, 8, 64, 40, 64, 1,192,207,207,239, 28,195, 48,158,132,144,186,140, 92,245,103,134,169,244,115,130, 32,164,199,197,197,
-245,108, 40,157, 30, 30, 30,253, 0,204,177,224,112, 46,207,200,200, 56, 94,223, 10,182,225,225,137,148, 82,123,150,101, 45, 58,
- 63, 60,207, 67,122,227, 70, 17, 22, 44,104, 33,102,125,145,255,118,218,218, 63,205, 12, 27, 54,236, 25, 0,213,249,249,189, 87,
-151,255,101, 61,150,101,117,123,247,238,221, 76, 41, 21, 31, 42, 68, 68,234, 32, 60, 60, 28,147, 39, 79, 70,108,108,108,219,195,
-135, 15,175,242,240,240,152,146,153,153, 57,136, 82,154, 39, 30,157,127,216, 96,249,121,216,180,117,105,214,108,215,210,207, 22,
- 1,192,167,245, 25, 33,119,119,247, 31,189,189,189, 7,173, 88,177, 2, 7, 15, 30, 68,203,150, 45, 33,149, 74,193,178, 44, 88,
-150, 5,195, 48, 96, 89, 22, 51,103,206,180,175, 74,163,169, 33,115,229,238,238,254,163,151,183,247,160,229,203,151,227,240,225,
-195,240,241,241,169, 85,115,214,172, 89,246, 0, 36, 0,248,106, 1,169,212,252, 20, 76,171, 76,147,103, 76, 76,140,179, 66,161,
-168,124, 44,166, 20,130, 32, 60,240,162,148, 86,191,120,158, 71,175, 94, 22, 63, 29,207,137,143,143,239,169,209,104, 30,208, 48,
-111,195,252,185, 74,175, 94,131,165,215,235,155, 69, 93, 62, 7, 98,184, 7,240, 5,160,140, 35, 32,243, 5, 24,121,173,235, 23,
- 20, 20, 96,224,192,129,205,196,108, 47,242, 36,152,171,161, 67,135,246,109,211,166,141,199,146, 37, 75,144,152,152, 8, 63, 63,
- 63,240, 60, 15, 65, 16, 30,120, 31, 63,126,188,108,244,232,209, 68, 60,106, 34, 34, 15,210,124,228,143,171, 40,111,156, 84,185,
-100, 15, 96, 61, 74, 75, 75,241,198, 27,111, 96,223,190,125,237,186,118,237,186, 24,192, 84,241, 72,253,131, 6,171,173,151,210,
- 67, 37,179, 58,176,238,135,239,137,177, 52,203,190,174,245, 8, 33,204,144, 33, 67,214,122,121,121,245, 95,177, 98,133,149, 84,
- 42, 69,194,196,137, 40,210,106,161,255,242, 75,216, 59, 57,193,111,202, 20, 52, 51,153, 96,186,122,213,162,109,215,212, 92,190,
-124,185,149, 84, 42, 69, 90, 90, 26,244,122, 61, 92, 92, 92,160, 84, 42, 33,147,201,170, 95, 22,106, 66,161, 80, 32, 60, 60, 28,
- 28,199, 85,191, 88,150,173,117,217,213,213,181, 49,135,107,121,187,118,237, 58,221,185,115,199,166,160,160, 0, 93,187,118, 45,
- 37,132,196,154,127,164,148,118,138,141,141,181,177, 84,140, 24,238, 65,147,242, 3,132,194, 93,128,253, 40,240,182, 47, 66, 11,
-223, 90, 11, 26, 65, 16, 31,224, 69,158, 8,115, 69,134, 12, 25,210,167,117,235,214,238, 75,150, 44,145, 72, 36, 18, 92,185,114,
- 5, 57, 57, 57,104,214,172, 25,148, 74, 37, 36, 18, 9, 88,150,133, 68, 34, 17, 15,152,136, 72, 29, 80,222, 56, 41, 32,168,123,
-245,242,166,240,111,161,179, 11, 68,250,167,159, 98,213,170, 85,104,219,182,109,144,120,148,254, 65,131, 21,208,194,222, 78, 70,
-165, 7, 54,174, 89, 33,131,161,204, 62, 33,242, 60,158, 26, 60,197,108, 22,174,215, 48, 45, 4, 0, 35,145, 72, 94,248,234,171,
-175, 24,169, 84, 10, 0, 8,226,121,120, 24, 12, 40,238,216, 17, 74,123,123, 52, 55, 24, 0,131, 1,186,170,223,255,146, 33, 44,
-208,100, 89, 22, 82,169, 20, 28,199, 65, 34,145, 64, 42,149,214,111,176, 52,154, 90,123, 66,152, 77, 84,120,120, 56,140, 70, 35,
- 70,143, 30, 93,171,217,106, 40,157, 53,201,200,200, 56,238,225,225, 17, 43, 8, 66, 79, 65, 16, 64, 8,137,205,200,200, 24,104,
-254,221,195,195,163, 95,231,206,157,231, 0, 88,110,145, 38, 95, 0,161, 96, 43,108,186,229,161,228,162, 19,136, 85, 63,240,240,
-193,133,107,201, 56, 29,157,140,220,130, 18,248,251, 58,225,133,129,254,181, 26,172,191,163, 23,136,168, 41,106,254,205,154, 68,
- 42,149,182, 88,178,100, 9, 49, 27, 40,115,132,218,108,172,204,159,205, 85,248,226,241, 20, 53, 69,205, 90, 46, 36, 86,242,227,
-213,168, 11,147, 0,160,228,230,110,188, 51,182, 59, 74, 75,239, 96,234,212,143,145,158,158,142,219,183,111, 95,249, 79,166,243,
-137, 53, 88,132, 16, 74, 41,109, 84, 24,221,203,139, 40,108, 76,170, 93,171, 87, 45,181,181,177, 81, 57, 69, 29,219,139,228,228,
-172,122,255, 35, 8, 2,253,227,143, 63,112,107,210, 36,116, 49,153, 80,248,213, 87, 32, 30, 30,120,106,196, 8, 72, 13, 6,148,
- 92,190, 12,169,181, 53,100,214,214,168,171, 13, 84, 93,154,105, 25, 25,224, 56, 14,214,214,214,176,178,178,130, 92, 46,175, 54,
- 86, 82,169, 20, 82,169,212, 98, 77, 74, 41, 56,142,195,245,235,215,145,156,156, 12,123,123,123,156, 63,127, 30,253,250,245,123,
-192, 92,177, 44, 11, 66,136,197,186, 53,245,121,158,175,213,128,161,129,170,193, 7,207, 96, 51,192,241, 21,148, 94,242, 0, 28,
-198,193, 72,237, 33, 80, 1, 81, 9,217,248, 97,225, 43, 0,128,192,145, 11, 49,186,127, 71, 49,130, 37,242,196,192,243, 60,110,
-221,186,133,155, 55,111,130,101, 89,216,218,218,194,202,202, 10, 18,137,164,250,197, 48,140, 24,193, 18, 17,169,135,148, 61,147,
-102, 18, 66,150, 53,111,222,252,232,218, 37, 75, 90,247,235,215, 15, 0,112,252,248,113,252,252,242,203,248, 20, 24,251, 45, 33,
- 89, 51, 40,253,228,239, 78, 75, 83, 60,200,127,133,193, 50,239, 88, 99,118,144, 16, 66, 90,187,218,254,182,240,195,183, 90,248,
-248,182,114,141, 56,180, 29,247,238,165, 35, 59,187,176, 46, 67, 65, 9, 33, 2, 0,218,162, 69, 11, 20,106,181,240,208,235,193,
-122,120,192,186, 89, 51,112, 85,145, 43,137,149, 21,164,214,214,144,214, 17,193,170, 79, 83,171,215, 67, 38,147,193,218,218, 26,
-214,214,214,144,203,229,144,214, 48, 87,150,104,214, 48,109,224, 56, 14,215,174, 93, 67,207,158, 61,225,237,237,141,223,127,255,
- 29, 3, 7, 14,252, 75, 20,171,177,230,170, 54,131, 85,163,241,123,131,141,219, 31, 64,214, 26, 38,155, 23,192,168,250,194, 64,
-109,161,163,238,149, 85,130, 38, 1, 95,239,190,135, 91, 41,121,224,121,161,186,154, 80, 68,228, 9,128, 18, 66,104,251,246,237,
- 73,126,126, 62, 36, 18, 73,181,185,106,215,174, 29,210,211,211,171,205,149, 57,162, 37, 34, 34, 82, 59, 44,203, 46,222,187,119,
-111,107,133, 66,129,207, 63,255, 28, 54, 54, 54,184,180,120, 49,126,146, 74,161, 4,176,214, 96,152, 3,224,111, 53, 88, 77,241,
- 32,255, 85, 17,172,198,226,233,233,185,180,107,207,174, 61,125, 59, 4,203, 35,142,236,198,157,219,201,200,203, 43, 6,165,168,
-168,239,198, 8, 0, 18,137, 4,229,139, 22,161,176, 83, 39,248, 63,255, 60, 56,131, 1, 37,151, 46, 65,106,109, 13, 85, 96, 32,
-136, 94, 15, 73,118,182,197, 55, 91,179,166,179,179, 51,164, 82, 41,228,114, 57, 20, 10, 69,101, 4,171,134,185,106,172,193, 42,
- 41, 41,193,253,251,247, 49,121,242,100,168, 84, 42, 16, 66,144,147,147,131,230,205,155,131,101, 89,164,167,167,227,196,137, 19,
-104,217,178, 37,100, 50, 89,163, 50, 69,141,198,237,157, 60, 60, 60,142, 82, 74, 59,197,196,196,216,168,213,106, 52, 42,130, 69,
-164,208,193, 7, 60,188, 32,208,255, 55, 82,198, 26,102,138, 82,177, 13,150,200,147,195,237,162, 51,244,253,215, 86, 0, 0,156,
-157,157,171,141, 84,171, 86,173, 30,136, 92,137,230, 74, 68,164, 97,218,182,109,219,197,211,211, 19, 51,103,206,132,118,235, 86,
-148, 1, 24, 10, 96,175,193, 0, 0,176, 6,230,139, 71,233, 63,104,176,188,189,189,167, 6, 4, 4,188,254,227, 47,155,173,150,
-125,252, 94,105,113,220,117, 70,167,213, 91,105,141, 70,253,189,140,130,181,245, 69,156,134, 15, 31, 14,150,101, 97,237,224, 0,
-165,157, 29,164,230,200,149, 74, 5,169,181, 53,136, 94, 15,170,215, 67,106, 97,104,191,166,166, 66,161,128, 76, 38,171,213, 88,
- 53,214, 96, 21, 21, 21, 97,251,246,237, 8, 9, 9,129, 74,165, 2,203,178,232,220,185, 51,226,226,226,224,235,235, 11, 0,216,
-187,119, 47, 70,141, 26,133, 59,119,238,160, 67,135, 14, 86,141, 53, 88, 60,207, 35, 60, 60,220,134, 82,218,147, 82,138,220,220,
-220, 38,157, 68,158,231, 81, 80, 80,128,125,251,246, 33, 59, 59, 27,206,206,206, 40, 41,181,131,185, 87,186, 32,252,127, 47, 72,
- 17,145, 39, 5, 65, 16,160, 84, 42, 17, 29, 29,141, 23, 95,124, 17, 0, 96, 52, 26,225,228,228, 4, 95, 95, 95, 12, 26, 52, 8,
- 3, 7, 14, 20, 15,148,136, 72,125, 15, 44,183,111, 71, 37, 39, 39,251,125,252,241,199,248,217,211, 19, 54, 54, 54,152,189, 96,
- 65,132,201,100,122, 70, 60, 58,143,193, 96, 53, 38, 52,231,237,237, 61,220,205,205,109,241,230,205,155,149, 25, 25, 25,240,108,
-235,111,115,112,231, 14,157,139,181,180, 34,189,176,104,242,181,180,210,189, 13,105, 48, 12,131,118,179,102,161,165,193,128,252,
- 11, 23, 32,179,182,134,117,112, 48,136, 94, 15, 89, 82, 18,164,214,214, 96,149,202, 70,237, 8,195, 48,149, 85,130,102, 51, 85,
-163,106,208,108,182,106,107,240, 90, 27, 6,131,193,174, 95,191,126,232,219,183, 47,158,127,254,249,234,170,192, 46, 93,186, 96,
-219,182,109, 24, 57,114, 36,174, 94,189, 10, 15, 15, 15,180,107,215, 14,237,218,181,195,201,147, 39, 27,149, 94,243,176, 12, 3,
- 6, 12, 40, 37,132,196, 82, 74, 59, 69, 70, 70,218, 52,229, 36, 10,130,128,125,251,246,225,165,151, 94, 66,219,182,109,113,233,
-210, 37,204,253,248,115,216,185,248,192,196, 56, 3,160, 98, 21,161,200, 19, 7,207,243,117, 54,100, 55,223, 19, 68, 68, 68, 26,
-188,142, 62, 30, 49, 98,132,250,243,207, 63,111, 55,123,246,108, 0,128,135,135, 71,168,135,135, 71,244,127,106, 28,172, 39,177,
-122,176,218, 96, 89,178,131,189,123,247, 94,205,243,252, 48,149, 74,101,255,198, 27,111, 24,242,242,242,176,103,207, 30,252,244,
-211, 79,229, 26, 35,115,165,184,128,127, 35, 49,189, 52,221, 82, 51,164, 48,153, 0,131, 1,210,170, 54, 87,208,233, 64, 13, 6,
- 72,172,173,193,169, 84,141,222, 17,134, 97,106,141, 88,201,101, 50, 72,170,198,195,178, 20,153, 76, 86,124,238,220, 57,231,180,
-180,180, 7, 26,180,183,108,217, 18, 0,112,249,242,101, 92,186,116, 9, 47,189,244, 18, 56,142,131, 84, 42,197,181,107,215,202,
- 26,107,138,120,158,175,238, 69,232,225,225,209, 47, 36, 36,164,214,222,131,150,104,165,165,165,161,109,219,182,208,233,116,176,
-177,177, 65, 94,230,125,220,189,125, 7, 37, 21,113,104,238,172, 66, 78, 78, 14,228,114,185,120, 55, 17,121,162, 96, 89, 22, 79,
- 63,253, 52,242,242,242,224,228,228, 4,185, 92,142,226,226,226, 7,140,215,198,141, 27,197, 3, 37, 34, 82, 11,205, 71,254,184,
-202,107,216,234, 73, 0, 48,231,155, 63,241,225,226,149, 24,247,252, 64,188,254,250,235,255,241,113,176,158,248, 54, 88,117,237,
- 88, 88, 88,216, 56, 71, 71,199, 49, 19, 38, 76, 80, 94,190,124, 25,159,125,246, 25, 23, 30, 30,110,136,140,140, 52, 9,130, 48,
- 63, 45, 45,195,226, 59, 24, 33, 4, 12,195,160,236,208, 33,148,186,185,193, 54, 40, 8,196, 96,168,140, 92,217,216, 64,227,233,
- 9,232,116,176, 43, 46, 70, 99, 53,205, 67, 50,212, 28,150, 65, 82, 53, 92, 67, 83,110,220,181,141,123, 53,117,234, 84,252,248,
-227,143,232,214,173, 27,218,180,105, 3,142,227,192, 48, 76,147,122, 17,214,172,178,107,116,239,193,135,158,228,189,189,189, 17,
- 29, 29, 13,123,123,123,252,244,211, 79,112,113,118,198,212, 17,126,208,235,245, 48, 26,141,208,104, 52,224,121, 30, 79,232,204,
- 65, 34,255,131, 8,130,240, 64,155,171,188,188, 60,120,121,121,213, 27,213, 18, 17, 17,169, 81, 14,213, 28, 7, 43,168, 59,206,
-239,254, 10,219,110, 53, 71,250,226,197,255,200, 56, 88, 79, 90, 4,171,193,187, 80,143, 30, 61,172, 11, 11, 11,191,126,245,213,
- 87,149, 26,141, 6,121,121,121,200,203,203, 67, 68, 68,196, 9,189, 94, 31,156,150,150,182,177, 30,227,227, 95,151,121,113,116,
-113,129,204,198, 6,164, 70,239, 65,137, 74, 85, 25,201,210,235,129, 58,140, 64,125,154, 53,205,149,185,138,208, 34,115,101,101,
-245,128, 38,195, 48,213,195, 52, 60,220, 99,208,219,219, 27, 75,150, 44,193,136, 17, 35, 30, 24,166,193,210,116,122,120,120,244,
-163,148,118, 50, 23, 16, 85,141,220,251, 89,104, 36,253,235, 50, 88,131, 7, 15,198,193,131, 7,241,238,187,239, 34, 41, 41, 9,
- 35, 71,142, 4, 33, 4,118,118,118,112,115,115,131,131,131, 3, 20, 10,197, 95,210, 90,151,230,163, 32,106,138,154,255, 41,205,
-154, 13,218,173,173,173, 81, 94, 94,222,160,185, 18,143,167,168, 41,106, 86,125, 95, 57, 14, 22,174, 70, 93,192,233, 95,102,227,
-173,161, 45, 49,178,197, 29,124,252,113,195,227, 96,253, 29,233,124,210,104,208,125,148,148,148,124,210,174, 93, 59,233,205,155,
- 55,145,152,152,136, 91,183,110,129,231,249,187,105,105,105,207, 55,217,213, 49, 12,236,236,236, 32,147,201,192,165,167, 87,182,
-145,178,182, 6,128,202,200, 21,165, 32,141,172,206, 98, 24, 6, 28,199,253,255,152, 87, 85, 55,221,166,194,243,124,245, 8,237,
-230,113,174,204, 47,134, 97,170, 95, 77, 24,162, 97, 78, 68, 68,132, 77,114,114, 50, 40,165,216,179,103,143,205,168, 81,163,230,
- 52, 53,122,149,147,147, 3,131,193, 0,137, 68,130,193,131, 7,163,123,247,238, 40, 43, 43,171,142, 86, 17, 66,192,113,156,216,
-139, 80,228,137,195,220, 6,171,230,168,237, 98,228, 74, 68,196,114, 82,246, 76,154, 9, 96, 38, 33,100,204,130, 5, 11,126,126,
-243,205, 55, 33, 8, 2, 78,158, 60,137, 53,243,230,225, 83,158, 31,251, 45, 33,229, 51, 40,157, 41, 30,173,199,104,176,186,118,
-237,234, 83, 90, 90,250,163,201,100,234,204,243,188,236,244,233,211,208,106,181,136,139,139,171, 16, 4, 97, 79,147, 55,200,113,
- 89, 51,102,204,240,178,100, 93,169, 84, 90,132, 6,230, 33,172,169, 73, 45, 48, 59, 82,169,180, 72,231,238, 94,175,166, 32, 8,
-233, 53,231, 22, 52,155,168, 90,162, 63, 53,111,246,233, 22, 30,130,229, 93,187,118,253,203,119, 77, 57,150, 50,153, 44,109,232,
-208,161,110,141,249,143, 84, 42,205, 18,179,189,200,127, 59, 82,169,180, 98,252,248,241, 22,245,220,101, 89, 86,191,115,231, 78,
-177,110, 92, 68,164, 14, 20, 82,233,216,183,222,122, 11,191,253,246, 27,246,172, 90,133,129,105,105,216, 38,149, 66, 41,149, 98,
-173,193, 48, 9,128,104,176, 30,167,193, 42, 46, 46,254,180,160,160, 32,164,164,164,196,116,247,238,221, 10, 66, 8,207, 48, 76,
-133, 32, 8, 75,121,158,223,208,212, 13,238,218,181,203,239,113,239,132, 89,147, 88, 80,229,105, 9,113,113,113, 61,255,174, 3,
-254, 40,109,173, 30,230,226,133, 11,237,197, 44, 44,242,191, 70, 27,187, 94,216,177,163,215, 86,241, 72,136,136, 60, 30,174,196,
-198,246, 3,128,193,131, 7,163, 98,206, 28, 0,192,166,170,113,176,108,128, 31,255, 37,201, 12, 6,224, 92,245, 57, 15, 64, 2,
- 0, 53, 0, 37, 0, 29,128, 50, 0, 78, 53,214,207,175,250,205,252,251, 25, 0,198,255,100,130,235, 52, 36, 9, 9, 9,175,229,
-230,230,218,232,245,122, 7,158,231,157, 76, 38,147,171,193, 96,104,105, 50,153,126,164, 98, 75,233,127, 28, 10, 8,143,242, 18,
-143,160,136,136,136,136, 8, 0,248,249,249,169,156,156,156, 84,126,126,126,170,143, 40,125,224,245, 47,170, 30,116, 38,132, 28,
- 36,132, 28,156, 63,127,126, 31, 0,221,231,207,159, 31, 82,181, 28, 4,192,201,252, 59, 33,228, 32,128,102, 15,253, 30,240,159,
- 78,240,147,214, 96,129, 54,233,101, 48,152, 63,139,136,136,136,136,136,136,252, 91, 11,121, 74,135, 46, 91,182,108, 9, 0,118,
-217,178,101, 75,106, 44,131, 82, 58,180,230,251, 67,191, 59,255,167,211, 74, 0,248,215,177, 19, 22,207,148,221,148,222, 4, 13,
-233,139,154,162,166,168, 41,106,138,154,162,166,168,249,228,105, 54,164, 93,199,255,159, 37,132, 28,164,148, 14,173,249, 94,211,
-120, 85,105, 30,172,249,249,161,223, 15,253,167,221,224,223,246, 2,224, 47,106,138,154,162,166,168, 41,106,138,154,162,166,168,
-249,136,175,103, 43, 45, 75,221,239,117,125,174,241,221,127, 50,189,245, 12,211,176,115, 39,155,234,167,180,145, 91,241, 82, 0,
-208,105, 88,131,247,173,138, 82,140, 30, 45,206,183, 34, 34, 34, 34, 34, 34, 34,242, 31,135, 16,114,112,222,188,121, 31,252, 55,
-164,149,171,203, 92,229,170,101,205, 20,198,162, 54, 38, 19,218, 1,128, 66,134,132, 92,181,205, 29,231,157, 59,243, 31,183,201,
- 26, 62,124,184,181, 76, 38,147,236,216,177,163,240,223,120,144, 58,181, 38,158,188, 17,195,192, 98, 16, 0,128,199, 17, 86,130,
- 3,177,137, 52,189,145, 25,195,165, 42,106,152,243, 56,214,123,220,255, 21,121, 50,240,240,240, 80, 2, 24,202,113,220, 56, 7,
- 7,135,160,252,252,252,207,211,210,210,190,107,226,205,140, 3, 48,195,222,222,126,140,189,189,125,139,130,130,130,251, 37, 37,
- 37,187, 0,124, 75, 41, 53,254,147,251, 73, 8, 97,252,253,253, 21, 60,207, 19,185, 92, 46, 72,165, 82, 42,147,201, 30,110, 75,
-105, 58,117,234,148,233, 73, 61,215, 97, 97, 97,114, 0, 56,117,234,148,238,191,172,144,100, 90,182,108,105,125,255,254,253, 50,
-106,158,149, 94,164, 65,186,119,239,126, 75,175,215,215, 59,204,145, 84, 42,205,151,201,100,190, 79, 96,190,207, 51, 87,253, 1,
-200, 1,192, 86, 45,235,171,222,179,107,124,151, 93,199,239,255,188,193, 74,245, 83,218, 40,140, 69,109,114,178,226, 70,231,100,
- 92,121, 30, 0, 92, 60,186,236,114,113,235,184, 51,213,207,222,208,181,227, 24,107, 86, 73, 86,113,140,164,179, 86,167,107, 38,
-145, 72,242,245, 38,211, 53,206, 72,102,102,196,237, 72,109,108, 34, 40,165,219, 9, 33,238,195,134, 13, 59, 42, 8,194,166, 67,
-135, 14, 37, 52,233,162, 13, 11,227, 92, 11,155,141,101, 36,220, 16,128,250, 83, 10, 80,194, 93,135,193,112, 36,219, 49,111, 51,
-109, 68,134, 83,171,137, 82, 91,130,126, 16, 48,172,109, 75,215,208,153, 83,158,111, 22,210,125,160, 82, 83,110,196,153, 19, 7,
-131, 55,108, 57,240,214, 83,190,228, 50, 79,112, 64,105,135,240,232,104, 90,209,192, 13,101, 17, 33,152, 85,245,121, 37,165,244,
-147, 71, 89,207,130,255,126, 79, 41,157,255,152,111,138, 79, 57, 56, 56,124, 47,151,203,173, 88,150,189,147,150,150,246, 53,165,
- 52,166,177, 58,222,222,222, 29, 77, 38,211, 8,137, 68,162, 54, 26,141,209, 28,199,237, 75, 77, 77,141,123,132,116,177, 29, 58,
-180,126,133, 37,164, 7, 0,123, 0, 69, 60,165,231,111,222, 76,252,141, 82,218,164,135,129,176,176, 48,174, 66,163, 25,203,177,
-236, 96, 74,169, 63, 40, 37, 32,228,186,201,100, 58,162,178,177,217,108,233,205,171, 91,183,110,183, 76, 38, 83,163,198, 42, 99,
- 89, 54,215,203,203,203,111,199,142, 29,141, 78,187,151,151,215, 40, 79, 79,207,181, 93,187,118, 85,117,233,210, 5, 82,169, 20,
- 95,126,249,229, 12, 0,223, 89, 98,164,172,172,172, 70,171, 84,170,150,101,101,101,247, 42, 42, 42,246,202,100,178,103,190,253,
-246, 91,207,110,221,186,217,228,230,230, 18,134, 97, 92, 14, 28, 56,240,242,119,223,125,215,143, 16,242, 44,165,244,145,110,226,
- 30, 30, 30,239, 2, 48, 79,199, 17,149,145,145,241,181, 37,255,235,216,177,163,116,232,208,161,191, 18, 66,158, 37,132,212, 89,
- 64, 51, 12, 83, 22, 22, 22,214,188,190,243,213,178,171,195, 57,142,229, 60,235,250,221,196,155,210,239, 95, 42,124,228,161, 91,
-250,245,235,183,133, 82, 58,194,100, 50,129,101,217,211, 39, 78,156, 24, 98,249,253, 72,221, 12,192,108, 0,140, 76, 38, 91,113,
-225,194,133, 92,181, 90,125, 72, 42,149,134, 85,253,126, 42, 58, 58,250,217,135,206, 41,121,148, 30,223, 97, 97, 97, 31, 9,130,
- 48, 69, 38,147,165, 22, 22, 22, 78,140,142,142,190,245,168,199, 64,173, 86, 75,178,179,179,103,116,238,220,121, 90,112,112,176,
- 91, 92, 92, 92,182,167,167,231, 26, 87, 87,215,111,163,163,163, 27, 52,236, 93,186,116,113,103, 24,230, 21, 0, 99,171, 10,208,
-157,132,144,205,209,209,209,247,254, 23, 12,150,201,100,114,187, 56,111, 30, 32,151,131,239,221, 27, 2, 33, 32,159,125, 6, 33,
- 59, 27,134, 47,190,128, 9,192,208,161, 67,237,171,202,246, 39,205, 96, 93,254,111, 75,112,173, 6, 75,110,197, 75, 77, 38,180,
-203,201,184,242,124,232,160,111,109, 1, 32,226,200,140,231, 29,221, 59,198,201,173,248, 59, 50,107,233,214, 81,195,250,117, 30,
- 61,180, 55,241,114,119, 65, 90,102,142,203,198,109, 71,251, 31, 60,114,114, 43,128, 30, 22, 70,173, 94, 54, 26,141, 62, 12,195,
-108, 99, 24,198,125,213,170, 85,173, 18, 19, 19, 39,110,219,182,109,248,176, 97,195,206, 11,130,240,243,161, 67,135, 46, 90,186,
- 35,110, 93, 70,180,119,131,219,150, 17, 35,135, 52,127,182,191,179,204,199,205, 25,130, 32, 71,194, 61,163,119,248,217,152,254,
-135,255, 56, 54,211,213,127,196, 43,217,215,247,221,104, 72,171,125, 43,242,162, 74, 46,157, 61,239,205,103,221, 6, 15, 26,106,
-227,232, 21,200,129, 84, 78, 22, 45,179, 5, 70,190, 50,199,106,196,203,239, 88,221,187,113,206,243,208,225, 3,253, 55,239, 61,
-149,217,190, 21, 89, 17,127,151,254, 94, 87, 84,137, 16,204, 18, 4,202, 84,222,244,201,156,254,253,251, 15, 80, 40, 20, 15,220,
- 80,180, 90,173,132, 16,116, 20, 4, 90, 85, 56,144, 89,132,144,213,150, 68,163,204,219,208,235,117,140, 68, 34, 3,203, 50, 51,
- 2, 2, 2,186,228,230,230,158, 2,176, 33, 35, 35, 35,255, 81, 50,138, 74,165,154, 48, 98,196,136, 37,155, 54,109,178, 86, 42,
-149,200,200,200,240,123,241,197, 23, 59, 19, 66,158,163,148, 54,120,227,245,240,240, 8, 0,240,156,147,147,211,168,137, 19, 39,
-250,244,237,219, 23, 45, 90,180, 64, 70, 70, 70,191,147, 39, 79,206, 15, 12, 12, 76,201,206,206,222, 5, 96,111, 70, 70,198,213,
-198,152, 43,255,142,109,151, 79,158, 50,181,253,200,145, 35,221,229, 10, 37,151,150,150,148,187,254,135, 53,118, 44, 97, 58, 19,
- 66,230, 52,214,100,133,134,134,182, 39,130,176,117,218,132, 9, 45,130,186,119,231, 92,221,221,161, 45, 46, 70, 98, 66,130,119,
-228,229,203,253,246, 29, 63, 62, 75,173, 86,143,139,142,142,110, 48, 47, 25, 12, 6,175,179,159,127, 14,214,201, 9,212,104,132,
-182, 77,155,234,250,121,249,197,139,128,209, 88,249,125,159, 62,160,148,130,231,121,140, 26, 53,202, 37, 47, 47, 79, 2,160, 81,
-233,246,246,246,118,111,211,166,205,134,249,243,231, 75,117, 58, 29,174, 92,185,130, 11, 23, 46, 8,185,185,185,203, 27, 50, 87,
-132,144, 3, 11, 22, 44,240,232,217,179,167, 77,126,126, 62, 76, 38, 83,179,189,123,247, 78, 86,171,213, 54,158,158,158,178, 95,
-127,253,213, 60, 67,128, 67,171, 86,173, 28,198,142, 29,171,255,245,215, 95,103, 0, 88,241, 72, 55, 32,142, 11,190,117,235,214,
- 16, 0,104,213,170,149, 69,255,233,216,177,163,212,215,215,119,147,175,175,111,159,101,203,150,145,196,196, 68,182, 67,135, 14,
- 16, 4, 1, 38,147, 9, 60,207,131,231, 43, 15,221,184,113,227,172, 27, 42,108, 56,150,243, 60,183,251,134,179, 74,165,170,254,
-175,121, 50,118,141, 70,131, 65,175,118,125, 44, 55, 91,158,231, 7,109,216,176, 1, 28,199, 97,220,184,113,189,213,106,181, 50,
- 58, 58,186,194,194,191, 79,123,227,141, 55,222,177,182,182,198,170, 85,171,158,233,216,177, 99,152, 92, 46, 15,251,243,207, 63,
- 1, 0,189,122,245, 10, 11, 9, 9,113, 52,153, 76,195, 8, 33, 35,109,109,109,123, 6, 6, 6,158, 11, 8, 8,120,229,234,213,
-171,197,141, 77,107, 80, 80,208, 40,127,127,255,233, 95,125,245,149,213,141, 27, 55, 28, 22, 45, 90,180, 21, 64,151, 71,217,255,
-142, 29, 59, 74, 53, 26,205,150, 79, 63,253,116,176,121,170, 49, 65, 16, 92,207,156, 57,179,232,221,119,223,237,170, 86,171, 95,
-170,203,100, 5, 7, 7,119,166,148,126,220,170, 85,171,126,175,190,250, 42,219,163, 71, 15,148,149,149,225,216,177, 99,239,239,
-222,189,251,253,192,192,192, 75,148,210, 69, 87,174, 92, 57,251,184, 10, 71,181, 90,157, 0,192,219, 28,119,136,142,142,110,247,
-175,136,254,217,217,161,116,240, 96, 24,238,220, 1,100, 50, 72, 87,172, 0, 12, 6, 24, 22, 44, 0,100, 50, 49,204,247,111, 55,
- 88, 13, 81, 94, 94, 30, 48,127,198,120, 48, 76,229, 72,230,109,124,155, 99,233, 7,147,201,190,131, 71, 45, 30,103,162,160,160,
-224,227,177, 99,199,186,239,219,183,239, 13,134, 97, 20, 57, 57, 57,164,188,188, 92, 57,107,214, 44,175,210,210,210,145,123,247,
-238,125,122,248,240,225,177,148,210, 47, 15, 28, 56, 16, 85,159,150,115,192,243,173, 93,156, 92,142,125,189,120,178,131,191,111,
- 43,232,141, 70,164,229,164,131, 66, 14, 55, 23,107,140,123, 46, 64,218, 35, 72,210,122,249,247,127, 30,117,235, 60,172,127,214,
-181, 3, 55,235,141, 32, 80,188, 23,113, 57,174, 45, 99,202, 39, 68, 98, 91,199,147, 49,135,214,157,194,184,105,190,254,246, 67,
- 6, 12,178, 29,245,218,172,247, 0,252, 94,223,117, 81,163, 64,195, 59,239,188, 83, 61, 21,143,153,236,236,108,156, 56,241,103,
-173,255,177,244,218,171,185,240,217,103,159,217, 21, 20, 20, 60,187,113,227,198,126,238,238,238, 11, 51, 51, 51, 27,125,243, 33,
-132, 40, 1, 12,122,230,153,103, 22,239,222,189,219,218, 60,122,189,171,171, 43, 86,172, 88,225,253,226,139, 47,126, 1, 96,120,
- 3,230,234,231,241,227,199,143,233,223,191, 63,252,252,252,144,159,159,143, 75,151, 46,233,215,172, 89,115,191,111,223,190, 45,
-199,140, 25, 35,123,231,157,119,154, 39, 37, 37,205,217,187,119,239, 28, 7, 7,135,159, 10, 11, 11,167, 91,146,190, 14, 29, 90,
-191, 50,113,210,164,246, 83,167,189,173, 54, 24,116,229,215,162, 79,159,224,164, 12,251,246,244, 73,118, 5,133,185, 78,148, 10,
-175, 0,248,165, 17,230,170,181,167,171,107,248,178, 47,190,176,119,116,118, 70, 86, 86, 22, 82,211,210,144,121,253, 58, 8,128,
-254,253,251,203, 2, 58,119,110,181,114,221,186, 35,193,193,193, 3, 34, 35, 35,111, 54, 24,145,114,114, 66,122, 96, 96,229, 93,
-250,228, 73,115,100, 5,158,195,134, 85,175, 83, 24, 25, 9,150,101,225,229,229,213,148,233,151,204,145,224,208,158, 61,123, 74,
- 1,224,221,119,223, 45,213,104, 52, 95, 17, 66,182,167,167,167,103, 52,240,215, 25, 31,125,244,145,123,171, 86,173,154,111,217,
-178, 5,101,101,101, 0,224,236,235,235,139, 54,109,218,240,167, 79,159,134,159,159, 31,108,108,108,112,250,244,105, 92,186,116,
- 9,129,129,129,214, 82,169,244,249,198, 24,172,186,162, 85, 60,207,163,216,194,201,221, 9, 33,204,179,207, 62,187,161, 69,139,
- 22, 97,203,150, 45, 83, 73,165, 82,196,198,198, 34, 43, 43, 11,206,206,206, 80, 40, 20,144, 72, 36,224, 56,174, 81, 83,101,169,
- 84, 42,100,100,100,192, 80, 53,184, 34,207,243, 40, 45, 45,133,155, 91,101,240,113,225, 66,194, 44, 88, 96,121, 85, 86,191,126,
-253,188, 41,165,205, 31, 50, 88,140,217, 92,235,245,122, 40, 20,138, 94,125,251,246, 45,175, 50,154,133, 71,143, 30,173, 47, 47,
-217,185,187,187, 99,216,176, 97,208,235,245,237,215,174, 93,251, 11,165, 20,229,229,229,213, 43,184,184,184, 36,245,234,213,139,
-237,217,179, 39, 90,181,106,133,117,235,214,245,217,185,115,231,211, 0,246, 55, 54, 47,217,217,217,189, 48,122,244,104, 43,107,
-107,107,132,134,134, 66,175,215,123,132,133,133,201,155, 82, 21, 73, 8,225, 60, 60, 60, 92, 57,142,251,102,198,140, 25, 3,123,
-247,238,141,248,248,120, 28, 57,114, 4,195,135, 15, 71, 88, 88, 24, 62,252,240,195, 65,159,124,242,201, 12,212, 49,171,133, 32,
- 8,155,119,237,218,213,194,203,203, 11, 44, 91,249,176,107,107,107,139,137, 19, 39, 98,252,248,241, 56,124,248,112,215, 37, 75,
-150,108, 13, 11, 11,243,121,140, 85, 99,222,209,209,209,102,179,229,253,111, 41,180,141,221,186,193,144,146, 2,169,143, 79,165,
-177, 74, 74,170, 52, 90, 85,203, 18,181, 90,116, 54,255,102,131,165,211,176, 6,133, 12, 9, 46, 30, 93,118, 69, 28,153, 81, 93,
- 69,200, 81, 36,104, 53,172, 1, 0,120, 74, 81, 82,102,130, 82,206, 32, 41,179, 20,215,239,230,214,118,195,127,160,171,101,255,
-254,253, 15,148,150,150,250, 57, 58, 58,174, 48,153, 76,108,159, 62,125,216,174, 93,187, 58, 39, 39, 39,227,212,169, 83,144, 72,
- 36,208,235,245,196,193,193, 65, 62,113,226, 68,143,138,138,138,102, 31,124,240,129, 19,128,222,117,105,146, 49, 99, 88,119, 9,
-187,243,171,197, 99, 29, 8,123, 11,183, 82,138,208,218, 43, 20,205,236,188,145,158, 91,134,232,184,195,184,149,120, 8,173,189,
-154, 99,242,184, 54,118, 43,127,200,219, 69,212, 83,252,105,244, 58, 99, 93,154, 0, 88, 86,213,154,232, 79,142, 18, 88,167,222,
-132,117, 31, 74,136,194,227,129, 21, 52,249, 73, 72,184,184,137, 38,197,238,167,205, 3, 94, 33, 0,216,186,246,157, 82,154,195,
-178,236, 6,134, 33,147, 8, 33,232,210, 37, 48,103,249,242,229,181, 61,169, 25,187,116, 9,204, 97, 89,198,165,114, 30, 65,230,
- 71, 65,224,115,234, 73,103,205,237,229, 16, 66, 86,202,100,242, 89, 0,224,238,238,145,115,232,208, 33,227,232,209,163,241,245,
-215, 95,203,230,206,157,187,192,211,211,243,213,244,244,244,244,250,206, 81,141,155,162,191,173,173,237,148,182,109,219, 14, 95,
-188,120,177,108,208,160, 65, 74, 74, 41, 74, 75, 75, 81, 90, 90,138,242,242,114, 88, 89, 89,129,227, 56,183,134,206,123,139, 22,
- 45, 70, 77,156, 56, 17,206,206,206,136,136,136,192,220,185,115,147,115,115,115, 63,203,204,204,140,222,186,117,107,187, 86,173,
- 90,125,184,110,221,186,246, 61,123,246,100,134, 13, 27,134, 3, 7, 14,244,104, 72,179,250, 68, 17,210,227,185,231, 70, 58,235,
-245, 21, 26,157,174,162,248,126,114, 84,102, 90,218,141, 34,191, 54,193, 46, 3, 6,118,115, 76, 72,184,219,163, 46,131,245,176,
-230,152, 49, 99, 88,134,231,127,255,226,171,175,236, 25,142,131,209,104,132,143,143, 15, 98, 99, 99, 81, 82, 88,136,138,178, 50,
-220,139,139,131, 71,203,150,152, 49,110,156,253,103,107,214,108, 81,171,213, 65, 53,159,186,107, 75, 39, 53, 26, 31,202, 92,236,
- 95,230,204, 99, 89,182,186,224,176,116,223,107, 41,132,146, 50, 50, 50,160, 82,169,208,190,125,123,171,168,168,168, 11,105,105,
-105, 25, 13,105, 42, 20,138,231,123,244,232, 97,179,117,235, 86,168,213,106,216,219,219,227,196,137, 19,136,141,141,133,193, 96,
- 96, 74, 75, 75, 97,109,109,141,101,203,150,161,121,243,230, 40, 41, 41, 65, 82, 82, 82, 51,137, 68,226,212,200,116, 6,197,197,
-197, 61, 91, 21,205, 48, 27, 46,117,219,182,109,129,202, 54, 21, 81,245,165,147, 84, 58, 79,134,227,184,231,150, 44, 89,194, 72,
-165,210,106,179,106,158,147,208,108,172,204,147,180,215,102, 86,107, 75,167,201,100,130,193, 96,128,193, 96,128, 32, 8,200,205,
-205, 69, 73, 73, 9, 28, 28, 28, 42, 87, 88, 0, 16, 16, 66,235,152,133,190,166,230,128, 1, 3,222,115,113,113,249,216,197,197,
-229,129, 19,170,211,233, 48,111,222, 60,148,149,149,193,211,211, 19,158,158,158,187,205, 19,203,231,231,231,163,127,255,254,203,
-194,195,195, 23,215,166,201,113,220,151, 95,127,253,245,240,118,237,218,185, 77,152, 48, 1, 28,199, 13,202,207,207,199,166, 77,
-155,160, 82,169,176,113,227, 70,180,104,209,130,229,121, 30, 21, 21, 21,102, 35,172,145,201,100, 73, 77,201, 75,133,133,133,191,
- 29, 60,120,176,123,183,110,221,236, 0, 96,196,136, 17,204,190,125,251, 82,250,244,233,147, 90, 90, 90,250, 74,205,234,194,186,
- 52,213,106,181, 36, 43, 43,107,246,184,113,227,222,233,215,175,159,109,126,126, 62,228,114, 57,182,111,223,142, 13, 27, 54, 28,
- 51, 26,141, 11,119,237,218,245,233,250,245,235,251,143, 24, 49, 2,235,215,175,127,179,170, 89,132, 80,139,166,187,183,183, 55,
-174, 93,187, 6, 7, 7, 7, 56, 57, 57,161,184,184, 24,151, 46, 93,194,229,203,151,209,190,125,123, 16, 66,234,173, 26,171, 39,
-157, 77,142, 84, 53,102, 56,163,199,165,217,148, 90,223,134, 52, 67, 66, 66, 90,240, 60,255, 50,128, 49, 85, 95,237, 96, 89,118,
-203,229,203,151,147,254,147,251,254, 68, 26, 44, 66,136,249,140,133, 81, 74, 79,123,223,170, 40,205, 85,219,220,113,113,235,184,
-211,209,189, 99, 28, 0,112, 20, 9, 84, 98,115,199, 59,182,162,180,178,234,131,226, 66, 66, 33,174,222,206, 70,236,237, 44, 88,
- 43, 26,126,234,214,233,116,207, 28, 57,114, 4, 59,119,238, 92,254,221,119,223,209,148,148, 20, 36, 39, 39,195,193,193, 1,189,
-123,247, 70,110,110, 46, 34, 35, 35,209,186,117,107, 80, 74,225,237,237, 45, 3, 96, 87,159,166,235,109, 97,220,171,147,187,180,
-116,178, 35, 56,112,225, 40,186,182, 31, 9,149,156, 67,110, 97, 57, 24, 66,144,120,255, 56,120,222, 10, 87,227, 83,208,221,223,
- 10, 61, 67,109, 61, 53,127, 22, 78, 0,176,174,225, 18,203, 8, 62,231, 56,229,115,254,164,140, 67, 16, 97,221, 71,144,194, 98,
- 45,226, 47,254, 68, 51, 19, 78, 86,223,107, 13,250, 82, 75,170, 7,102,186,186,186, 86,204,155, 55,239,153, 54,109,218, 24,223,
-122,235,173,152,164,164,164,119, 30, 50, 34,223,172, 94,189, 26,119,238,220,201, 91,182,108,217,137,236,236,236, 15, 26,121, 17,
-125, 76, 8,249, 30, 0, 50, 50, 50,242, 15, 30, 60, 24,116,250,244,233, 57, 43, 87,174,116,123,251,237,183,101,211,167, 79,159,
- 84, 89, 84, 52,248,196, 25, 16, 22, 22,118,228,183,223,126,179,114,115,115, 35,132, 16, 24, 12, 6,228,230,230, 34, 55, 55, 23,
-197,197,197,208,104, 52, 40, 43, 43, 3,195, 48, 13,182,151, 83,169, 84,108, 73, 73, 9,138,138,138, 16, 18, 18,130,203,151, 47,
-251,156, 63,127,126,195, 15, 63,252, 32,140, 31, 63,158,132,133,133,145,188,188, 60,236,222,189, 91,200,202,202, 98, 20, 10, 69,
-153,197, 79,199, 12,236, 85, 42,165,244,226,249,189, 71, 50,210,226,242, 50,179,175, 23, 51,160, 76, 70, 70, 84,177,111,155, 62,
-205, 80,217, 38,203, 34,238,221,187,247,210,172,169, 83,125,237, 28, 28, 96, 50,153,224,228,228,132,180,180, 52,148,151,151,163,
-188,164, 4, 21,101,101,208,150,148, 32,254,207, 63,209,109,200, 16, 12,232,210,197,251, 80, 76,204,235, 0,214,215,167,171,247,
-243, 67,234,201,147, 96, 24, 6,222,189,171,159, 21,144, 31, 17, 81,109,182,108,251,247, 7, 81,169, 32,249,160,233,157, 99, 50,
- 50, 50,174,250,248,248, 28, 29, 52,104,208,192,201,147, 39, 51, 89, 89, 89,251,220,220,220,158,201,202,202,138,175,239,127,214,
-214,214,190,121,121,121, 40, 45, 45,133,189,189, 61, 86,174, 92, 9, 23, 23, 23, 84, 84, 84, 32, 50, 50,146,122,121,121,145,147,
- 39, 79,194,211,211, 19, 5, 5, 5,208,235,245, 40, 47, 47,207,214,235,245, 21,141,137, 88,153, 35, 67,102,143,207,113, 92,112,
-108,108,172, 75,101, 36,178,131,197,237,175, 4, 65,160,119,238,220, 65, 92, 92, 92,229,177,179,181,133,149,149, 85,229, 36,239,
- 82,105,181,185,226, 56,203, 3,244,230,201,209,205,230, 42, 55, 55, 23,137,201,183,176,251,228,175, 48,240,198,102, 63,135,218,
-222,111, 37,145, 92,119, 46, 35, 11,114,175,209,171, 13, 92,135,227,191,252,242, 75,214,221,221,253, 47,191,165,165,165,161,184,
-184, 24, 54, 54, 54,176,183,183,175,174,210,204,203,203,195,204,153, 51,199, 3, 88, 92,155,102, 68, 68, 68, 78,104,104,232, 11,
-179,103,207, 62,254,235,175,191,202,198,141, 27, 87, 93,157,201,243, 60,202,202,202,240,231,159,127,226,236,217,179,136,138,138,
- 42, 52, 24, 12,251, 89,150, 93, 19, 17, 17, 17,223,216,124,212,173, 91, 55, 7,107,107,235,207,223,124,243, 77, 27, 0,208,106,
-181, 24, 55,110,156,242,133, 23, 94, 64,116,116,116,251,239,190,251,110, 19,128,144,134,170, 3, 25,134,217,113,242,228,201,126,
- 85, 6, 26, 70,163, 17,231,207,159,199,228,201,147, 11, 84, 42,213,248,184,184, 56,141,167,167,231,167, 7, 15, 30,236, 31, 16,
- 16,128, 78,157, 58,185,230,229,229, 89, 3, 40,169,227,188,131,231,249,234,243,179,113,227,198,234,223,180, 90,109,229,181,166,
-215,147,144,144,144, 22,245, 25,131, 70, 68,170, 82,107, 44,167,254,147, 5,117,199,142, 29,173,100, 50,217, 8,142,227, 88,110,
-231, 78, 72, 39, 77,130, 33, 49,241,129,200,149, 57,146,101, 28, 49, 2,146, 70,104, 18, 66,198, 57, 57, 57,245,232,222,189, 59,
-145, 72, 36, 24, 49, 98, 4, 14, 31, 62, 60,255,200,145, 35,243,212,106,245, 5, 65, 16, 54, 27, 12,134,189,113,113,113,154,191,
-173,218,243, 33, 15,242,196, 69,176, 40,165,164,106, 39, 9, 70,143,230,157,119,238,204, 79,245,179, 55,200,173,248, 59, 0,160,
-213,176, 6,239,216,170, 97, 26, 22,111, 5, 5, 5,207, 83, 80, 65,128, 64, 41,120, 11,130,231,205,108,141, 96,174, 59, 96,108,
-215, 17, 24, 63, 62,138,252,249,231,159, 56,117,234, 20, 2, 2, 2, 96, 52, 26, 97,107,107,139, 49, 99,198, 96,239,222,189, 80,
-169, 84,208,104, 26, 62,159,214,142,166,145,161,157,218,176,183, 82, 98, 17,212,246,121,180,112,239,137,196,244, 98, 20,150,234,
-144, 95, 92, 1, 63,191,247,144, 93, 80,129, 18, 77, 5,174, 37,108,129,151,187, 47,195, 72,238,246,183,200, 96,253,255, 45, 19,
- 66, 97, 36, 21, 10, 35,233,159, 71,255,218,220,200,164,179,172,122, 67, 16,132,111,143, 28, 57,210,173,103,207,158, 92,191,126,
-253, 2,125,124,124,186, 36, 39, 39, 95, 1, 0, 31, 31,159, 46,253,251,247, 15,116,113,113,193, 55,223,124,163, 21, 4,225,219,
- 38, 62,253,212,108,175, 21,225,237,237,189,112,207,158, 61, 63, 76,153, 50, 5,238,238,238,157, 45,209,176,183,183,159,180,105,
-211, 38, 43,119,119,119, 98, 50,153,160,213,106,145,149,149,133,162,162, 34, 20, 22, 22, 34, 37, 37, 5, 5, 5, 5,200,204,204,
-212, 36, 37, 37,237,178, 52,109, 31,125,244, 17, 76, 38,147,113,242,228,201,146, 62,125,250,224,215, 95,127,101,238,221,187,135,
-245,235,215,243, 59,118,236, 72,102, 24,134,123,254,249,231,155, 55,110,135, 73, 94, 90,218, 61,103,157,161, 80, 59, 40,172,251,
-172,220,164, 60, 56,183, 24,129,227,103,118,125,147,146,148, 72, 9, 3,139,219,158,201, 37,146, 1,234,174, 93, 37, 89, 89, 89,
-104,221,186, 53,210,211,211,113,251,246,109,232,245,122,104,138,139, 97, 44, 41, 1, 95, 88, 8, 90, 82,130,164, 51,103,208,161,
-117,107,217,145,152,152,254, 13, 25, 44, 65, 16,192, 48,204, 95,162, 41,230,168, 21,195, 48, 32, 86, 86,128,149, 21, 40,211,184,
-201, 21, 60, 60, 60,134,218,218,218,206, 46, 41, 41, 57,154,145,145,241,133,193, 96,152,189,116,233, 82,245,162, 69,139,154,205,
-157, 59,215,102,238,220,185,155, 91,180,104,209, 45, 41, 41,169,206,170,157,178,178,178,123, 70,163,209, 17,128,203,241,227,199,
-225,236,236,140,210,210, 82, 24, 12, 6, 84, 84, 84, 24, 28, 28, 28,228,249,249,249,208,233,116,208,233,116,176,181,181, 69,116,
-116,116,129,201,100, 58,220, 80,196,234,254,253,251,207, 86, 61, 60,180, 34,132,216,119,234,212,169,250, 55,115,228, 40, 43, 43,
-203,210,188, 77, 9, 33, 2, 33,132,250,249,249,161,168,168, 8, 44,203,194,202,202, 10,214,214,214,104,223,190, 61, 82, 83, 83,
-155,108,176,106,154,171, 63, 47, 30, 68,110, 89, 38,126,252,106, 43, 60,221,188, 25, 0, 78,233, 89,169,207, 76,152, 51, 38,184,
-101, 79,199,175,238,159, 43, 88, 94, 79, 97,241,235,220,185,115, 63,117,118,126,112,224,104,111,111,111, 76,153, 50, 5, 7, 15,
- 30,196,157, 59,119, 30, 24, 47,167,160,160, 64, 0,240,107,125,105,140,136,136,136, 81,171,213, 19,198,140, 25,179,162, 69,139,
- 22, 46,148, 82, 4, 4, 4, 96,236,216,177,248,234,171,175,112,230,204,153,157,130, 32,252,108,107,107,123, 33, 55, 55,151, 77,
- 76, 76,212, 55,246,254, 17, 18, 18,226, 40,151,203, 79,175, 94,189,218,167, 85,171, 86, 76, 70, 70, 6, 46, 94,188,136,110,221,
-186,129, 16,130, 54,109,218,192,104, 52,122, 54,100,174, 40,165,219,247,236,217,211,175, 85,171, 86,136,143,143,199,217,179,103,
-225,236,236, 12,165, 82,137, 97,195,134, 57,110,223,190,125, 74,199,142, 29,191,227, 56,238,147, 33, 67,134,128,231,121, 68, 69,
- 69,101,221,191,127,191,172,190,115, 84,207,195, 59, 40,165, 48, 26,141, 95, 50, 12,243,124,112,112,240,176,200,200,200,168, 71,
- 41, 28,255, 45,109,174,158,122,234,169, 25, 42,149,234,163,238,221,187,171, 46, 94,188, 8, 90,101, 38,235,129, 45, 43, 43,123,
- 19,245, 84,223, 15, 28, 56,112,166,141,141,205, 7, 93,187,118, 85,121,120,120, 64,163,209,160,160,160, 0,121,121,121,152, 59,
-119, 46,218,182,109,139, 25, 51,102,144, 11, 23, 46,244, 56,112,224, 64,143,139, 23, 47, 46, 87,171,213,159, 68, 71, 71,255,240,
-119,237,231, 3, 30,228, 73, 51, 88, 85, 59, 22, 86,253,203,232,209,188, 55, 80, 84,117, 19,111,102,111,111,191,130,231,249,222,
-248,228, 19,216,112,118, 72, 74,188,141,210, 66, 1, 70,189, 14,130, 64, 65,133,134,143,137, 82,198,195,246,105,138,146, 51, 4,
- 18, 66, 48,100,200, 16, 12, 28, 56, 16, 49, 49, 49,248,245,215, 95,209,179,103, 79, 20, 23, 23,163,164,164, 4,101,101,101,230,
-182, 32,245, 34, 85,104,159,242,113,109,139,210,138, 16,168,100, 50, 20,148,232, 80, 88,170, 67, 94,145, 22,187,247,141,133, 78,
- 91, 14,147, 78, 15,222, 96,130,181,235, 72,180,113,236, 3,208, 59, 29, 31,231, 65, 52,234, 74, 45,138,217,230,230,230,102,123,
-121,121,237,141,142,142, 30, 61,102,204, 24,156, 56,113,226, 77, 0,111, 84, 21,182,111,142, 25, 51, 6,209,209,209,136,143,143,
-223,155,155,155,251, 88,186,148, 26, 12,134,114, 99, 85, 21,149, 66,161,144, 90,242, 31,134, 97,250, 59, 59, 59, 19,131,193,128,
-252,252,124,228,229,229, 33, 63, 63, 31, 21, 21, 21, 40, 43, 43,131,201,100,130,209,104, 68, 68, 68, 68, 54,207,243, 17,141, 73,
-207,205,155, 55,219,204,154, 53,235,141,126,253,250,125, 56,116,232, 80, 28, 56,112, 0,191,253,246,219, 20, 0,187,122,244,232,
- 17,221,216,253,227,121,254,228,234,213,107, 92, 39, 77, 28,238,186,243,224,198,165,187,118, 95,235,252,242,139, 89,113, 30,158,
-157,156, 55,175, 57, 47, 51,153,232, 65,139,197, 4,161, 83, 51, 87, 87, 36, 37, 37, 33, 50, 50, 18, 90,173,182,218, 84, 24, 10,
- 11, 97, 44, 40, 0,209,104, 32, 55,153,160, 77, 73, 65,171, 78,157, 64,128, 14, 22,220, 56,192, 48, 76,157,213,130, 12,195, 0,
- 86, 86,149, 38,171,142,106,173, 58,204, 85,151, 46, 93,186,252,186,126,253,122,233,236,217,179,131,125,125,125,127,200,204,204,
- 76,241,246,246, 30,242,245,215, 95,159, 89,188,120,177,124,220,184,113,109,215,175, 95,255, 50,128,141,117,233,104,181,218, 93,
-135, 14, 29,122,209,199,199,199, 37, 54, 54, 22, 90,173, 22,130, 32, 96,240,224,193, 0, 32, 55,175,151,144,144,160, 45, 47, 47,
-207,137,139,139, 43, 77, 78, 78, 54, 2,104,240, 33,128, 16,130,220,220, 92, 16, 66,236, 99, 98, 98, 92,164, 82, 41,170, 34,162,
- 46, 93,186,116,201,233,212,169,211,161, 42,179, 21,228,225,225,177, 29, 13,247, 36,164,102, 93, 39, 39,167,234, 42, 65,115,117,
-161,171,171, 43,138,139,139,155,100,176, 74, 74, 74, 80, 92, 92,140,219,247,227,145, 83,154,137,240,109, 23,193,243, 60,116,186,
- 74,111,234,225,234,133,227,219, 46, 91,135,141, 14,122,223,169, 11, 57,147,119,133,214,154, 95,143, 29, 59,246,213,128, 1, 3,
- 14,102,101,101, 57,213,184,166,186, 25,141,198, 79, 76, 38, 19,146,146,146,112,243,230,205, 47, 41,165, 39,107,228,133,244,240,
-240,240, 6,163, 46,209,209,209,251, 58,118,236,248, 71,105,105,169, 15,207,243, 47, 58, 58, 58,206, 53,153, 76,230,232,219, 65,
-134, 97,174,105, 52,154, 3,173, 91,183,238, 30, 20, 20,180, 59, 42, 42,106, 66, 3,231,135, 4, 7, 7, 63,175, 82,169, 94,211,
-104, 52,219, 20, 10,197,220,213,171, 87,251,248,250,250, 50,201,201,201, 48,153, 76, 72, 73, 73, 17, 34, 35, 35,203,131,130,130,
-172,195,195,195,203, 24,134,169,211, 8,170,213,106,137,209,104,252,125,255,254,253,253, 91,181,106,133, 51,103,206, 96,217,178,
-101,104,221,186, 53,126,254,249,103,116,239,222, 29, 45, 91,182,132,131,131,195, 91, 37, 37, 37,161, 95,124,241,197,192,192,192,
- 64,236,217,179, 7,185,185,185,107,235, 27,178,193,100,170,187,105, 85,121,121, 57, 40,165,120,230,153,103, 38,204,158, 61, 27,
-195,134, 13, 59, 16, 26, 26,218, 43, 34, 34, 34,209,130,211,255,175,137, 84,213,177,223, 31, 59, 57, 57, 41,239,222,189, 11, 74,
- 41, 12, 47,191, 12,195,136, 17,127,137, 92,113, 62, 62, 56,219,172, 25,220,131,130,144,155,151,247,105,199,142, 29,191,143,139,
-139, 51,212, 90,110, 74,165, 11,103,207,158,205, 37, 39, 39, 35, 62, 62, 30, 5, 5, 5,127, 49,176, 28,199,161, 87,175, 94,104,
-222,188, 57,250,244,233,163,250,244,211, 79,151, 1,248,219, 12,214, 95, 60,200, 19, 27,193,122,240, 38,222,204,206,206, 46,106,
-245,234,213,142, 33, 33, 33,172,201,100,194,159, 39, 78,224,221,233, 19, 48,104,232, 91,208,234,100, 48,105, 9,120,169,117,131,
- 27,171,208,179, 40, 57, 67, 32, 88, 15,129, 94,175,199,228,173, 82,216,147,124,172,122, 45, 4,223,125,247, 93,101, 85, 76,121,
- 57, 74, 75, 75, 81, 86, 86,134,210,210,134,171,222,202,138,172, 13, 6,163,128,244,156,100,164,101, 94,135,157,117,115, 80,198,
- 27,217, 5,229, 32,112,129,177, 34, 1, 66,213,133,169,171, 72,131, 70,103,161, 57,110, 68,239,115,131,190,196,226,117, 25,134,
-249,117,203,150, 45,195, 86,172, 88, 33, 27, 54,108,152,159,187,187,123, 79, 0,120,225,133, 23,252,236,236,236,176,101,203, 22,
-125,125, 55,176, 70,102, 88,198,221,221,253,149,158, 61,123, 34, 59, 59, 27,247,238,221,139,176, 48,141,199,174, 94,189,250,170,
-183,183, 55, 73, 73, 73, 65, 90, 90, 26, 10, 10, 10, 96,103,103, 7, 71, 71, 71,184,185,185, 65, 16, 4, 84, 84, 84,184,222,184,
-113,163, 11,128, 99,150,166, 41, 39, 39,167, 16,192, 55,229,229,229, 31,114, 28,103, 14,237,239, 67, 19, 39,160,190,113, 51,113,
-135,191,127,155,142, 94, 94, 14,109,213,254,254,206, 94,158,137, 37, 78,206, 94, 54,135,143,196, 42,115,178, 11, 19,110,220,184,
-179,167, 49,135,172,162,160, 0, 25,215,174, 85,182,185, 42, 45,133,182,172, 12,166,162, 34,184,183,109, 11,104, 52, 96,180, 90,
-112, 90, 45, 36,130, 0,165, 74, 5, 75,158,182,228, 23, 47,194,125,104,229,240, 45, 5,151, 47, 87,155, 42,155,129, 3, 1,149,
- 10, 68,165,130,113,247,110,176, 44, 11,234,224, 0,108,220,104,137,185,106,230,230,230,182,227,187,239,190,147,230,229,229, 33,
- 46, 46, 46,246,222,189,123, 37, 78, 78, 78,214, 28,199, 9, 9, 9, 9, 39, 19, 18, 18, 6,183,108,217, 18, 60,207, 55,212, 61,
-239,219, 61,123,246,244,237,209,163,135,169,101,203,150,170,220,220, 92,239,194,194, 66,146,153,153,249,192, 74,145,145,145,242,
-212,212,212,114,158,231,247,163,114, 28,172, 6, 47, 18, 74,233, 3, 13,199, 99, 99, 99,107, 53,155,215,174, 93,115, 1,240,108,
-231,206,157, 27,140, 98,141, 24, 49, 2,148, 82, 68, 70, 70,226,236,217,179, 56,123,246, 44,146,146,254,223,155,216,217,217, 33,
- 60, 60, 28,125,250,244,177,248,196,151,151,151,195,213,213, 21,118,118,118,216,115,234, 87,108,248,122,107,117, 67,247, 26, 15,
- 72, 80,169, 84,248,252,221,149, 86, 19,222,127,254, 19, 0,195,234,210, 59,118,236,216, 45, 0,183,204, 38,166,111,223,190, 75,
-250,245,235, 7,131,193,128, 94,189,122, 33, 54, 54,118,176,189,189,253,103, 77, 25,138, 35, 46, 46,206, 16, 24, 24,232,226,234,
-234, 58,235,213, 87, 95,133,201,100,194,192,129, 3,113,235,214,173,159,114,115,115,211, 39, 78,156,232,211,187,119,111,124,242,
-201, 39, 47,132,132,132, 44,174,175,186,172,103,207,158,239,141, 30, 61,250,253,231,158,123, 78,113,246,236,217,144,138,138, 10,
-214,203,203,139, 73, 76, 76, 4,207,243, 56,127,254,188,233,216,177, 99,233, 6,131, 97,249,245,235,215,187,150,149,149,237,191,
-114,229, 74,157,145,203,236,236,236, 25,123,246,236, 25,224,231,231,135, 35, 71,142, 96,218,180,105, 71,172,173,173, 59, 60,251,
-236,179,222, 86, 86, 86,184,122,245, 42, 12, 6, 3,220,221,221, 93,230,205,155, 55,120,224,192,129, 56,126,252, 56, 22, 45, 90,
-244,135,171,171,235,183, 13,153, 96,174,170,109,228,195, 15, 42, 87,174, 92,193, 51,207, 60,131,185,115,231, 2, 0,254,252,243,
- 79,155, 1, 3, 6, 68,134,133,133,185, 53,212, 48,191,174, 72,213,191,165, 23,161, 74,165, 98,247,239,223,143,237,219,183,227,
-151, 95,126,193,186,117,235, 48,114,228, 72,152,159,150,245,122, 61, 14, 28, 56,128,120,181, 26,114,127,127, 4,123,123,227,240,
-225,195,172,147,147, 83,157,225,240,204,204, 76,110,212,168, 81,184,120,241, 34, 60, 61, 61,113,251,246,109,196,198,198, 86,155,
- 88, 65, 16,144,144,144,128, 59,119,238,224,206,157, 59, 16, 4, 1,148, 82,201,223,185,159, 79,116, 4,171, 46,236,236,236,190,
- 90,187,118,173, 99,247,238,221, 89,141, 70, 3, 65, 16,208,173,107, 87,188,250,218,171, 56,186,103, 39,220,125,251,128,213, 42,
- 97,178, 81, 53,108,176,140,182, 64,231, 98,104, 74, 75,161,168,106, 76,122, 45, 77, 91,125, 19,214,104, 52,213,109,123,204,141,
-169, 27,140, 30, 25,228, 87,110,222,229,189, 74,202,174, 32, 34,250, 55, 24,245,122,180,244,155, 15,157,209, 9, 86, 46, 19, 81,
- 97, 56, 0, 67, 81,229,131,162,204, 54, 12,217,217,121, 0, 97, 26, 28,115,137,154, 44,110, 6, 4,163,214,114,131,149,146,146,
- 82,228,238,238,190,253,252,249,243,227, 71,142, 28,137,163, 71,143, 78, 1,128,145, 35, 71,226,252,249,243,184,123,247,238,246,
-204,204,204,162, 70, 26, 41, 39, 84,142, 9, 83, 29,245,114,117,117,109,217,188,121,243, 55, 39, 79,158, 28,218,169, 83, 39,108,
-222,188, 25, 0, 78, 88,162,151,151,151,247,227,156, 57,115,250,207,154, 53,203,141, 97, 24,114,235,214, 45, 16, 66,224,226,226,
- 2,111,111,111, 56, 58, 58,162,168,168, 8,129,129,129, 86,222,222,222,195, 44, 53, 88, 85, 79, 72, 94, 0,138,205, 13, 53,171,
-222,165, 0,236, 40,165, 77,234,213, 42, 8,210, 53,199,142, 68,172, 9, 14, 28,196,180,244,177, 42, 6,244,228,114,100,186,149,
-145,151,172,111,164, 35,141,189,123,251,118, 75, 42, 8, 40, 43, 44,132,161,180, 20,198,194, 66,152, 10, 10, 64,220,221,193,105,
-181, 96,117, 58,176,122, 45, 20, 10, 21,138,115,114, 64, 24, 11,242, 82,141, 2,161,182,168, 21,177,178,250,255,170, 66, 66, 44,
-106,196, 42,151,203,127, 94,183,110,157,155,187,187, 59, 86,174, 92, 9, 55, 55, 55,191,190,125,251,230,245,234,213, 75,233,228,
-228, 4, 63, 63, 63, 4, 5, 5,225,228,201,147, 96, 89,246,110, 3, 55, 54, 19, 33,100,216,185,115,231,102, 92,188,120,113,148,
-187,187, 59, 25, 63,126, 60, 6, 13, 26, 4,185, 92,142,138,138, 10, 20, 22, 22,226,208,161, 67,196,100, 50,117, 7, 0,119,119,
-247,230, 45, 90,180,248,153, 16,146,126,255,254,253,241, 22, 24, 44, 85,112,112,112,205,234,107, 85,116,116,180, 11,165,244,217,
-160,160, 32,240, 60,255,128, 73,178, 36, 47,113, 28, 87,107,213,171,249, 56, 51, 22, 86,183,154,120, 83,250,224,215,186,253,255,
- 3, 19,111,104,230,233,230,205,152, 35, 87, 0, 80, 82, 82,130,148,148, 20, 24,141, 70, 52,107,214, 12, 70,163,209,226,249,217,
-250,246,237,251, 74,155, 54,109,186,132,134,134, 34, 41, 41, 9, 1, 1, 1,104,211,166, 77,199,219,183,111, 79, 68, 3,213,203,
-117, 84,227,181,177,183,183,223,245,217,103,159, 73,109,109,109,113,229,202, 21,116,232,208, 1, 95,127,253, 53,119,235,214, 45,
-159,118,237,218, 33, 62, 62, 30,233,233,233,247, 26,106,139, 36,147,201,166,188,245,214, 91,138,212,212, 84, 60,255,252,243,138,
-123,247,238,225,198,141, 27,160,148, 34, 38, 38,198,180,103,207,158,244,138,138,138,167,163,163,163,243, 1,252,212,208, 3, 93,
-175, 94,189,222,106,211,166, 13,254,252,243, 79,188,249,230,155,199,172,172,172,198, 22, 21, 21, 77,212,235,245, 95, 15, 29, 58,
- 20,221,187,119, 71, 66, 66, 2,134, 13, 27,134,224,224, 96,156, 56,113, 2,115,231,206, 61, 98,101,101,245,114, 3,227, 96, 37,
-158, 58,117,170, 99, 80, 80, 80,117,237,134, 68, 34,129,189,189, 61,110,222,188,137,182,109,219, 98,238,220,185, 88,177, 98, 5,
-102,207,158, 45, 12, 24, 48,192,164,215,235,165,230,200,102, 19,249,215,244, 34, 36,132,160, 93,187,118, 88,186,116, 41,178,179,
-178,176,122,206, 28, 88,191,247, 30, 12, 60,143,212,113,227,160,244,247,135, 77,104, 40,100, 50,153,197,249,158, 16, 2,185, 92,
-142,214,173, 91,163, 69,139, 22,120,234,169,167, 16, 27, 27,139,247,223,127, 31, 45, 91,182, 68, 82, 82, 18, 76, 38, 19,100, 50,
- 25,108,109,109, 33,210, 68,131, 69, 41, 37, 53,223, 31, 44,188,132,222, 65, 65, 65,108, 89, 89, 25,180, 90, 45,178,179,179,113,
-255,254,125, 40,149, 74,164,231,164, 32,164,117, 25,178,136, 30,113, 49,183,121,112,220,181,134,110,138,122,189, 30, 17, 17, 17,
-136,136,136,128,224,183, 12,130, 32,152,171, 41,170,163, 87, 89, 89, 89,130,183,183, 55, 74, 74, 74,152,134, 11, 47,221,177, 19,
-231,175, 14, 28, 63,242, 25, 89,248,169, 13, 48,234, 76, 40,211,218, 67,163,213,163,180, 66, 2,189,124, 0, 8, 57, 3,134,149,
-163,123,151,214, 56,121,238,182, 86, 48, 26,194,235, 47,112, 32, 8,134,124,202,120,141, 35, 66,230,110, 10,190,142, 58,111,150,
- 5, 39,179, 70, 69,121,169, 64,169,229, 17, 24, 7, 7,135,173, 91,183,110, 29,217,163, 71, 15,171,126,253,250,181,174,170,190,
- 51,110,221,186, 85,227,224,224,176,181,145, 23,222,135,132, 96, 46, 40, 24,185, 76,118,220,177, 89,179, 63,109,108,108,212, 3,
- 7, 14,108, 61,104,208, 32,180,106,213, 10, 59,118,236,192,142, 29, 59, 78,100,102,102, 94,176,240, 73,226, 26, 33,100,204,253,
-251,247, 95,118,119,119, 31,208,185,115,103, 55, 95, 95, 95,133,157,157, 29, 88,150,133, 70,163, 65, 94, 94,158,185,199,149,175,
-165,105,109,209,162, 5,220,221,221,223,149, 72, 36,159, 61,244,164, 98, 2, 48,196,221,221,221,170, 41,153, 56, 46, 46, 46,123,
-208,192,190, 46,107,126, 56,223,166,162,130, 55,236,251,227,184,193,168,183,170,184,153,112,183, 81,163,217, 27, 4,225, 88,116,
- 84,212,160,158,221,187,203,147,162,163, 97, 44, 42, 2, 95, 88, 8,206, 96, 0,167,209,128,213,233, 64, 42, 42,208,188,139, 10,
- 16, 92,113,249, 94,186,201,192,243,199, 45, 53, 88,148, 97,170, 11,126,150,101, 65,172,173, 43, 13,150, 74,245,128,193,106,168,
-138,208,213,213, 85, 53,120,240,224,176,192,192, 64, 80, 74,241,213, 87, 95,193, 96, 48,200, 12, 6, 3,140, 70, 35, 12, 6, 3,
- 74, 75, 75,177,107,215, 46,252,250,235,175, 23,109,109,109,127,179,224,156,155,188,188,188,166, 10,130,224,108, 50,153, 12,206,
-206,206,210,237,219,183, 67,161, 80,128, 97, 24,116,233,210, 5, 10,133, 66,239,225,225, 81, 12, 0, 46, 46, 46,198, 21, 43, 86,
-112, 19, 39, 78,148,214,111,126, 5, 24, 12, 6, 36, 36, 36, 88, 73,165, 82, 43,115, 85, 79,219,182,109,115, 76, 38,147,213,237,
-219,183, 1, 32, 39, 48, 48,208,220, 94, 38,202,194, 60,138,190,125,251, 98,192,128, 1,213,213,129, 46, 46, 46,208,235,245, 48,
-153, 76, 22, 23, 50, 0, 96, 30, 68,116,225, 66,194, 96, 1,240,115,168,205,125, 0,213,213,123,197,197,197, 72, 77, 77, 69,114,
-114,114,229, 3,149,209, 8,129, 90,246,148,189,112,225, 66,134, 16,242,209, 43,175,188,130,172,172, 44, 44, 90,180, 8, 31,124,
-240, 1, 70,143, 30,141,207, 63,255,252, 3,181, 90,253,179, 37, 3,108, 62, 84,101, 52,126,250,244,233, 86, 46, 46, 46,216,184,
-113, 35,246,239,223,159,211,185,115,103,151, 9, 19, 38,192,207,207, 15,113,113,113,248,230,155,111,242, 5, 65,120,209, 2,173,
-123,151, 47, 95,118, 53, 24, 12, 72, 79, 79,175,142, 92,164,167,167, 11,167, 79,159, 78,215,106,181,102,115,213, 32, 45, 91,182,
-180, 86,171,213, 46,183,110,221,194,182,109,219, 96, 52, 26, 23,198,197,197, 25,236,237,237,183,173, 94,189,250, 3, 95, 95, 95,
-135,167,159,126, 26,221,187,119, 7,165, 20, 7, 14, 28,192,167,159,126,122, 68,169, 84,142,173,171, 42,171, 70, 84,253,165,197,
-139, 23,127,220,172, 89,179,231,199,141, 27,199,168,213,106, 68, 69, 69,129,231,121,244,237,219,183,218, 92, 29, 61,122,116,251,
-145, 35, 71,158, 3, 32,181,182,182,118,180,100, 88, 9, 66,200, 16, 0,230, 8, 65, 57,165,244,240,191,185,208,118,117,115,195,
-203, 31,127,140,210,210, 82,108,218,180, 9, 86, 85, 3, 10,215, 52, 78,141, 54, 2, 28,135,230,205,155,195,203,203, 11, 63,254,
-248, 35,174, 94,189, 90,221,105,164,169,154,141,141, 94,213,229, 65,158,232, 8,150,217, 24, 9,130,128,140,140, 12, 68, 70, 70,
-226,222,189,123,176,182,182, 70,133, 73, 16,190,187,116, 85, 96,136, 36,195, 68,113,145,240,146, 15,235, 45,192, 12, 6,240, 60,
-143,139, 23, 47,226,206,157, 59,176,107, 75,205, 13, 19,161,213,106,161,209,104,204,145,171,138,155, 55,111,102, 21, 23, 23, 59,
- 54,148,182,236,182,204,230,240,240,227, 51,131,186,116,108,211,175,247,167, 56,120,240, 19, 20,149,148, 64,163,227, 80, 86, 97,
-128, 70, 75,225, 97,211, 10,161,157, 3,145,155,175,199,173, 27,209,233,185, 82,135,122,159,196, 40,193,247, 99, 70,246,157,245,
-241,123,147, 93, 59,248,205, 83,208,156,195,160,197, 49, 20,230,241, 42, 9, 3,153,181, 19,192,201,105,212,205,188,178,147,177,
- 21,121,148,224,251, 70, 24, 2,141,151,151,215,175,211,167, 79,255, 44, 50,242,178, 11, 0, 68, 69, 69,229,100,101,101,125,148,
-150,150,102,113, 79, 13, 66,136, 61, 33,152, 43, 8,148,173, 50,105,253,103,205,154,229,209,163, 71, 15,131, 68, 34, 65, 74, 74,
- 10,190,252,242, 75,156, 63,127,126, 91,102,102,230,154,198,140,234, 76, 41,189, 10,224, 42, 33,100, 81,108,108,108,191,190,125,
-251,126,222,182,109, 91, 47,147,201,132,226,226, 98, 20, 22, 22,226,246,237,219, 40, 47, 47,191, 99, 65,212,238,120,106,106,106,
-191,169, 83,167,162, 71,143, 30,175,253,242,203, 47, 47,213, 12, 3,119,234,212,233,210,240,225,195,189,236,236,236,164, 21, 21,
- 21,198,132,132,132, 51,141,122,204,244,246,238, 57,115,230,204,206, 83,166, 76, 65, 89, 89, 25, 54,109,218,132, 53,107,214,192,
-219,219,187,103,106,106,234,185, 70, 24,192,173,251,195,195,103,117,110,215,174,173, 79,203,150,184,117,236, 24,164, 6, 3, 36,
- 38, 19,216,242,114, 72,140, 58,180, 8,178,130, 84,225,132,204,164, 10,108,187,113, 35,153, 82,250, 83,131,213, 79, 79, 63,141,
-226,232,104,176, 44, 11,155, 33, 67, 64, 84, 42, 80,149, 10,198,237,219,171,163, 48,220,226,197,149,102,235,153,103, 26, 76,103,
-118,118,118,121,155, 54,109, 98,226,227,227,213,237,218,181,195,194,133, 11,145,154,154, 10, 74, 41,114,114,114,180, 57, 57, 57,
- 25, 5, 5, 5, 41, 12,195,236, 79, 79, 79,255,217,210,169, 72, 4, 65,112, 62,112,224,128, 57,162,136, 63,255,252, 19, 30, 30,
- 30,176,179,179, 67, 73, 73, 9,198,143, 31, 47,251,248,227,143, 1, 0, 49, 49, 49, 18,165, 82,105,145, 17, 50, 24, 12,184,123,
-247,110,181,137,172, 50, 63,170,208,208,208,156,170,117,138, 8, 33, 22,247, 34, 52, 27, 55,150,101,255,210,160,189,177,230,170,
- 38, 11, 22, 80,129,128, 16, 95,142,189,150,158,149,218,207,195,213, 11,217,217,217, 72, 73, 73, 65, 74, 74, 10, 82, 83, 83,209,
-166, 77, 27,220, 79,190, 11,153, 84,114,205, 18,205,243,231,207,247,106,217,178,165,135,151,151, 23,214,175, 95,143,138,138,138,
-187,123,247,238,109, 53,126,252,120,248,248,248, 56,241, 60,223, 23,192,145,198,164,147, 97, 24, 47,149, 74,133,138,138, 10, 28,
- 56,112,160,192,218,218,186,253,149, 43, 87, 70,223,190,125,251, 75,111,111,111,155,228,228,228,108,131,193, 48, 56, 42, 42,234,
-118, 67, 90,101,101,101,111,188,255,254,251, 91, 4, 65,240,125,234,169,167,216,225,195,135, 91,121,122,122, 34, 50, 50,178, 92,
-167,211,125, 97,169,185, 2,128,251,247,239,151,157, 61,123, 54,167, 99,199,142, 46,238,238,238,144, 72, 36,139, 61, 60, 60,190,
-176,178,178, 90, 50,116,232, 80,135, 29, 59,118, 96,231,206,157,176,178,178,194,253,251,247, 51, 19, 18, 18,190,119,113,113, 89,
- 99,137,193,140,140,140,188, 15,224,245,208,208,208, 37,171, 86,173,154, 75, 8,121,233,216,177, 99,213, 6, 96,249,242,229, 56,
-122,244,232,246, 22, 45, 90, 76,218,177, 99,199,132,198,214,194, 81, 74,111, 84,221, 83,159,170,241,253,191,165,109,150,209,100,
- 50,201, 60, 61, 61,145,149,149, 85, 93, 69,106, 99, 99,243,128,241,225, 56, 14, 54, 54, 54,230, 30,177,124, 94, 94, 94,125,215,
-189,201,104, 52,114, 94, 94,149,121,220,172,201, 48, 12, 12, 6, 3,100, 85, 3,150, 74, 36, 18,216,218,218,154,183,243,196, 78,
- 57,245,143, 25,172,170, 41, 29, 70,118,238,220,153,187,125,251, 54,170,158, 56, 81, 94, 94,110,226, 88,236,201,190,182,247,245,
-122, 12,128,255, 67,227, 65, 93, 92,176, 96, 65,183,215, 94,123, 13,158,158,158, 88,119,217,128,228, 20, 30, 6,131, 1,153,153,
-153,184,112,225, 2,223,171, 87, 47,214,100, 50,149,241, 60, 63, 44, 53, 53,117, 44, 33, 36,171, 94,205, 29, 59,120,231,128,231,
-199,172, 94,251,227,201,215, 94,123,205, 97,248,136, 53,136,137,187,142, 66,141, 11, 0,192,195,201, 10,161,237,222, 71, 78,190,
- 14, 71,255, 56, 88, 68,133,242,151,233,149,109,198,250, 52,111,222,163, 63,249, 55, 39,167, 95,153,252,209, 59, 93,252, 91, 14,
-120,119,234,115,205,218,122,141,144,163, 40,130,202,109, 75, 33,179,114, 70,252,189,188,138,195, 23, 51,242,243,138, 77,127, 18,
- 30,223,220, 76,161,247,235,211,124,152,130,130,130,115, 25, 25,233,206, 53, 70,109,119,150,203, 21,231, 26, 48, 84,245,106,154,
-135, 83, 56,114,228, 8,206,158, 61,107,184,115,231,206,105, 66,200,129,140,140,140,107, 77,213,164,148,150, 2,216,109, 99, 99,
- 35,104,181,218, 79, 6, 15, 30,220,134, 16,130,196,196, 68,156, 56,113,226, 84, 94, 94,222, 23, 13,105,150,151,151,191,245,206,
- 59,239,124,223,175, 95,191,254, 85, 61,158,100,183,110,221, 2,165, 20,193,193,193,232,222,189,187,175, 94,175, 23, 46, 93,186,
- 84,112,232,208,161,109, 90,173,118, 69, 99,210,153,154,154,122, 46, 56, 56, 24, 0, 80, 81, 81,129,180,180, 52,152, 76, 38,100,
-100,100, 52,234,120,238,216,177,131, 15, 13, 13,125, 97,213, 79, 63,157,156,241,252,243, 14, 93,135, 15, 71,250,197,139,208,103,
-100, 64,198,243,144, 73, 21, 48,106, 92, 80,144,174,197,134, 27, 55, 74,244, 60, 63,246,225,194,161,182,116,154,205, 0,203,178,
-128, 74, 5, 88, 91,131,169, 28, 67,236,129,104, 22,107, 99, 3, 72, 36,127,121, 90,172, 77,179,162,162,226,229,201,147, 39, 71,
- 28, 62,124,216,126,236,216,177, 24, 62,124,248,213,146,146,146, 65,121,121,121, 22,213,109,215,166,201, 48, 76,238,144, 33, 67,
-156,117, 58,157,233,165,151, 94,226,242,242,242,224,231,231, 7, 0, 40, 45, 45,197, 31,127,252,129,118,237, 42,155,161,220,184,
-113, 3, 29, 59,118,108, 80,211,108,176,204,198,202,108,178,226,227,227,173,164, 82,169, 21, 33, 4, 38,147,201,165,109,219,182,
- 65,141,201,159,148,210, 7,204, 21,199,113, 40, 47, 47,183,200, 92,213,151,151, 40, 40,117,214,144,133,175,207, 30, 19,122,124,
- 91,132,181,149,149, 85,117,225,211,186,117,107,112, 18, 14, 27,247,126,167, 41, 46,205, 95,100, 97, 58, 95, 10, 9, 9, 65, 69,
- 69, 5, 98, 98, 98,120,137, 68,242, 82,108,108,236, 69,141, 70, 35,233,220,185, 51,146,147,147, 95,168,203, 96,213,163,121, 47,
- 45, 45, 13, 45, 91,182,132,189,189,189,173,209,104, 52, 93,185,114,229,183, 78,157, 58,237,185,125,251,118, 75,185, 92,158, 28,
- 21, 21, 85,102,137,102,116,116,116, 42,128,158, 97, 97, 97,220,245,235,215,147,123,245,234, 5,153, 76,134, 54,109,218, 88, 39,
- 38, 38,142, 69, 3, 61, 27,107,106, 82, 74, 5, 79, 79,207,213,151, 47, 95, 94,212,165, 75, 23,188,244,210, 75,207, 68, 69, 69,
- 61, 19, 16, 16,128, 86,173, 90,225,252,249,243, 56,117,234,212, 54, 65, 16,102,100,102,102,106,235,123,224,171,107,223,171, 26,
-173,191,161, 86,171, 71, 85, 25, 10, 54, 61, 61,157, 61,118,236, 24, 40,165,111,215,215,166,173,161,123,221,195, 88,210,230,170,
-177,154, 77,185, 54, 9, 33,203,198,142, 29,187,112,222,188,121,108,167, 78,157, 80, 80, 80,128,156,156, 28,152, 59, 55,200,100,
- 50,248,248,248, 64,169, 84, 34, 41, 41, 9,209,209,209,188, 78,167, 91, 86, 51, 42, 88, 75, 58, 23,190,252,242,203,159,190,255,
-254,251,127,209, 4, 0,185, 92, 14, 31, 31, 31, 40, 20, 10,220,191,127, 31,209,209,209, 60,128,133,127,247,190,255,207, 25,172,
-162,162,162,247,230,207,159,223,123,226,196,137,142, 21, 21, 21,172,147,147, 19, 50, 50, 50, 76,199,142, 29, 43, 44, 43, 43,123,
-175, 49, 27, 99, 89,118, 80, 70, 70,198,184,153, 51,103, 46,106,211,166,141,227,235,175,191,142,183,222,106, 7,189, 94, 15,185,
- 92, 14,169, 84,250,195,193,131, 7, 71,219,219,219,167, 31, 56,112, 32, 21,192, 50, 75,116,115,175,238, 74,116,235, 50, 98,192,
-183,223,174,217, 18, 24, 28,234,221,162,101, 75,121, 79,111, 59, 24,140, 60,178,115,242,113,250,194, 77,221,173,184, 43,105, 48,
-105, 95,201,190,126,224,166, 37,154,215, 43, 13,211, 59,157, 91,147,128,151,222, 92, 62,179, 87, 72,171,174,111,191, 20,236, 80,
- 34, 20,211, 61,251,239, 20,220, 75, 45,187,204,177, 88,117,227, 62,189,218,148, 3,175,213,106, 13, 15, 71, 93,181, 90,173,161,
-145, 97,213, 34, 66,200,151, 12, 67,230,130,130,145,201,100, 17,107,214,172,217, 4, 32,157, 82, 26,145,145,145, 81,241,184, 50,
- 74,105,105,233, 94, 66, 72, 76, 98, 98,226, 44,134, 97,236,121,158,191,153,157,157,189,157, 82,218,208, 40,225,168, 26,236,242,
- 57, 47, 47,175,167,207,157, 59,183,108,232,208,161,254,207, 62,251, 44,178,178,178,192,113, 28,174, 94,189,170, 63,116,232, 80,
- 68, 81, 81,209,167,148,210,200,198,166,173, 42,130,133,169, 83,167,162,180,180, 20,219,182,109,195,209,163, 71, 27, 29,193, 50,
-223,192, 67, 67, 67, 7,124,246,243,207, 91,135,180,107,215,188, 93,171, 86, 82,159,142, 29,161, 84,169, 80,156,159,143,171, 73,
-153,252,111, 9, 9,247, 43, 76,166, 87,162,163,163, 45,202, 75, 6,131, 1, 78, 78, 78,160,148, 66, 57,127, 62, 40, 33, 16, 40,
- 69, 25, 33,213, 99,251,200, 67, 66, 96,226, 56, 20, 86, 13,143,208, 80, 15,184,244,244,244,116,111,111,239,177,111,191,253,246,
-225, 77,155, 54, 49, 97, 97, 97,157,247,239,223, 79, 31,229, 28,167,165,165,181, 1, 0, 15, 15,143,108, 91, 91, 91,238,245,215,
- 95,135,209,104, 68,121,121, 57, 74, 74, 74,144,159,159,175,159, 57,115,166, 12, 0,100, 50,153,113,208,160, 65, 13,222, 63, 42,
- 42, 42, 96, 52, 26, 65, 8,121,192, 96,221,185,115,231,225,136, 86,163, 48, 71,213,171, 26,223, 86, 79,147,243, 56,200,189, 70,
-175,182,236,110,255, 85,159, 49,193,239,127, 54,103,165,149,147,179, 19, 76, 38, 19,238,165,220,197, 79,123,190,215,148,232,138,
-190,204,187,222,240, 28,156, 97, 97, 97,114,137, 68, 50,188, 75,151, 46,136,138,138,130, 94,175, 63,115,252,248,241,248,190,125,
-251, 30,191,122,245,234, 96, 63, 63, 63, 48, 12, 51, 36, 44, 44,204,234,212,169, 83,141, 25, 99,232,110, 70, 70, 6,140, 70, 35,
-156,157,157,185, 91,183,110, 53, 7,112, 47, 54, 54,182, 28,192,141,166,236,243,169, 83,167, 76, 61,123,246,188,115,253,250,245,
-224, 22, 45, 90,144,136,136, 8,141, 86,171,221,218, 88, 29, 87, 87,215,111, 15, 30, 60,216,131, 82,218, 63, 48, 48, 16, 62, 62,
- 62,230,168, 61,206,156, 57,179, 35, 61, 61,125,242, 99,154,220,153, 18, 66, 80, 90, 90,202, 86, 21,246, 6,107,107,235,166,234,
-150,215,136, 92,149,255,219, 10,233,168,168,168,149,106,181,250,192,212,169, 83,231,250,248,248,188,248,238,187,239,178,237,218,
-181, 67, 73, 73, 9, 66, 67, 67,225,226,226,130,248,248,120, 28, 59,118,140, 47, 44, 44,220,197,178,236,210,152,152,152,196, 6,
-204,227, 10,181, 90,189,127,234,212,169,115, 91,182,108,249,226,236,217,179,217,246,237,219,163,184,184,184, 90, 51, 46, 46, 14,
-135, 15, 31,230,139,139,139,127, 7,240,197,255,202,124,143,143,213, 44, 91, 82,107, 84, 53, 76,195, 87, 60,207,247, 54, 71,181,
-138,138,138,222,107,104,126,187,186, 28,110, 88, 88, 24,167, 84, 42,199,229,229,229, 45,242,242,242,114,124,253,245,215,241,225,
-135, 31, 34, 54, 54, 86, 53,114,228, 72, 71,142,227, 76, 59,118,236, 40,105,236, 19,131,121,178,103,112,210,193,160,130, 63, 0,
- 2,134,109,112,178,103, 75,156,120,167, 86,164, 15, 79, 49,169,242, 15, 88, 31,119,151,158,122,212, 39,155,154,147, 51, 83,138,
- 6, 39,118,174, 75,179,182, 70,238, 77,125, 90,250, 59,158,192, 30,250,141,184,187,187,143,145,201,100,223,142, 25, 51,198,234,
-151, 95,126,209,230,228,228,204, 4,176,173,190, 57, 3, 27, 74,167,135,135, 71,185,143,143, 15, 28, 29, 29, 81, 80, 80,128,228,
-228,100,100,100,100,168,154,154,206,154,147, 61,163,106,178,103,106,193,100,207, 15,107,118,237,218, 53,201,104, 52, 58, 55,230,
-248, 73, 36,146,124,185, 92,238,107,222, 70,125,233,244,244,244, 28,227,229,229,181, 56, 61, 61,125, 95, 90, 90,218,220,199,113,
-142, 60, 61, 61,187, 18, 66,246, 8,130,160,120, 56,194,101, 54, 97,238,238,238,205,101, 50,217, 3,141,220, 31,214,124,104,160,
-209, 6,203,145,218,170, 8,107, 75,231,152, 49, 99, 98, 13, 6,131,143,133,199, 50,151, 16,242,192,196,217,150,230,121,167, 46,
- 68,109,167,108,246,137,222, 96,236,196, 16, 80,137, 68, 18, 91, 92,154,191,168, 54,115, 85,155,230,192,129, 3, 29, 28, 29, 29,
-211, 62,249,228, 19,172, 93,187, 22, 55,111,222,156,116,252,248,241,173,253,250,245, 27,213,162, 69,139, 95,199,141, 27,135,181,
-107,215, 34, 55, 55,183,231,137, 19, 39,174, 88,122,142, 66, 67, 67,219,251,250,250, 70,206,159, 63,159, 44, 94,188, 24,169,169,
-169,234, 75,151, 46, 37, 60,234,121,239,218,181,171, 15,203,178, 63,243, 60,239, 75, 8,249,229,210,165, 75,159, 90, 98,134, 30,
-214,236,216,177,163,180,184,184,248, 77, 47, 47,175, 25,174,174,174, 46,217,217,217, 41,169,169,169, 95,103,102,102,254, 98,169,
-185,178,228, 28,169,213,234, 66, 0, 50, 0,176,164,189,213,127,250, 94,247,119,104,170,213,106, 95, 0,115,189,189,189, 95,156,
- 58,117, 42,123,251,246,109, 28, 57,114,132,207,203,203,219,197,178,236,210,186,134,165,176, 68,211,199,199,231,197, 41, 83,166,
-176, 85,211, 24,241,249,249,249,245, 26, 43, 49,130,245,152, 12,214,223,149,249,204, 70,171,176,176,240, 67,107,107,235, 59,225,
-225,225, 67,254,109, 25,250,239,214, 36,132,184, 84, 69,163,114,254,151,246,157, 16,194, 41, 20,138, 32,173, 86, 27, 79, 41, 45,
-121, 76,154, 31, 2,248, 0,192, 18, 74,233,231,255,107,121, 73,212,252,119,105, 86, 13,207,176,215,193,193,161, 95, 97, 97,225,
-117,147,201, 20,118,234,212, 41,157, 90,173,150,216,219,219,111,177,181,181, 29, 82, 82, 82,114,174, 71,143, 30,131, 23, 44, 88,
- 32, 52, 38,157, 65, 65, 65,159,178, 44, 59,198,100, 50,109,139,142,142, 94,252,111, 60,158,132, 16,226,227,227, 35,171,111,144,
- 91, 49, 47, 53,217, 92,250, 2,120,147, 16,194, 84,141,216,159,248,184, 52,171, 22,215, 52, 20,177, 18, 13, 86,195,112,255,228,
-198,171,158,208,127, 65, 35, 38,227,125,210,176,196, 88, 61,161,251,109, 2,112,233, 49,107,126, 14,224,115,241,178, 22,249,151,
-228,113, 10, 96, 68,191,126,253,188,143, 31, 63, 94,221, 72, 58, 58, 58,218, 24, 22, 22, 54,182,162,162,194,222,100, 50, 21,213,
-102,174, 26, 34, 42, 42,234, 83, 0,159,254, 23,236,191, 78,204, 9,143,159, 42,243, 51,231,223,174, 41, 26, 44, 17, 17, 17, 17,
-145,191,141,154,230,234,161,135,203, 60,241,232,136,136, 60,185, 16, 0,254,117, 60,125, 88, 28,250, 35,132,248, 55,118,195, 22,
- 84,247,136,154,162,166,168, 41,106,138,154,162,166,168,249,132,105, 54,164,253,164, 84, 61,254,163,109,176, 68, 77, 81, 83,212,
- 20, 53, 69, 77, 81, 83,212, 20, 53,159, 68, 24,241, 16,136,136,136,136,136,136,136,136, 60, 94, 44,110,131,213,169, 53,241,228,
-141, 24, 6, 22,131, 0, 0, 60,142,176, 18, 28,136, 77,164,233, 77,221,184,155,155, 91,123, 66,200, 43, 12,195,140, 6, 32, 8,
-130,176,131, 16,242, 91, 70, 70,198,237,166,106,134,134,134,182, 55,153, 76, 47, 18, 66,158, 3, 0, 74,233, 94,142,227,126,143,
-136,136,136,183,228,255, 74,165, 50, 73,171,213, 58, 3,128, 66,161,200,213,106,181, 45, 81, 53,234,248,232,209,163, 73, 94, 94,
- 30, 1,128,211,167, 79, 83, 0,180,114, 19,245,135, 1,229,114,121,146, 94,175,255, 75, 87,125,137, 68, 98,176,183,183, 47,106,
-214,172, 89,145,179,179,115,161, 84, 42,189,145,151,151,119,250,234,213,171, 81,148,210,172,198,236,119,239,222,189, 63,150,203,
-229,211,245,122,253,186, 83,167, 78,125,252,119,103, 28, 66, 72,176,183,135,219, 58,163,209, 32,100,229, 22,124, 74, 41, 61,216,
-152,255,183,110,221, 90,230,233,233, 73, 30,238, 90,189,106, 10,113,163, 12,152, 89,107, 27, 30, 95,171,129,244, 5, 74, 36,146,
-169,174,174,174, 3,210,210,210, 98, 0,124, 72, 41,141, 23, 47,121, 17, 17, 17, 17,145,127,220, 96,169,213, 68,169, 45, 65, 63,
- 8, 24,214,182,165,107,232,172,169,163,155, 5,117, 27,168, 42, 47, 55,208, 51, 39, 14, 6,111,216,114,224,173,167,124,201,101,
-158,224,128,210, 14,225,209,209,180,206,129, 45,191,121,151, 75,226,121,222, 25, 0, 4,112,154,149, 59,156, 19,131,131,131, 3,
-230,204,153,131,208,208, 80, 8,130,128,211,167, 79,207, 90,185,114,229, 44,119,119,247, 40,150,101, 55, 75,165,210,157,247,238,
-221,107,176, 11,127,112,112,176,151, 32, 8,163, 1,188,208,181,107,215,142,211,166, 77, 67,155, 54,109,160,211,233, 16, 17, 17,
- 49,103,243,230,205,115,212,106,117, 28,128,237, 12,195,236,140,140,140, 76,171, 75, 75,171,213, 58,155,253, 18, 33,196,121,242,
-228,201, 26,163,209, 8,189, 94, 15,163,209, 8,107,107,235, 56,173, 86,123,173,103,207,158, 81, 54, 54, 54, 23, 14, 29, 58,116,
- 7, 0,223,193, 85, 25,226,227,229, 52,232,112, 84,202,167, 15,107,234,245,122,103,109, 68, 4,192,243, 48, 37, 39, 67,219,175,
- 31,170,230,141,147,178,131, 7,187,152, 24,198,133,148,149,221,213,254,246,219,218,118,237,218, 85,119,183,173, 79,243, 33, 51,
- 65,166, 78,157, 58,103,222,188,121,146,151, 95,126,249,245,176,176,176,133,117,141,211,100,169,102, 3,219,147,119, 13,234,252,
-199,129, 93,219, 20, 32, 4, 35, 71,142,254,153, 16, 50,137, 82,186,247,225,117,187,116,233,210, 87, 42,149,126,106, 50,153, 98,
- 56,142,251, 56, 34, 34,162, 52, 40, 40,104,151,147,147,211, 32,189, 94,143,192,192,192,139, 49, 49, 49,253, 0, 96,237, 27,100,
-161, 12,152, 5, 30,100,221, 27,100,245,148, 13,116, 94, 19,211, 55,249,181,215, 94,251,250,243,207, 63,103,221,221,221,145,158,
-158,222,191, 67,135, 14,109, 8, 33, 65,148,210, 10,241,178, 23, 17, 17, 17, 17,249,199, 12, 86,251, 86,228, 69,149, 92, 58,123,
-222,155,207,186, 13, 30, 52,212,198,209, 43,144, 3, 97, 43, 35, 50,182, 32, 35, 95,153, 99, 53,226,229,119,172,238,199,157,247,
- 60,116,248, 96,255,223,246,156,200,108,223,138,172,136,191, 75,127,175, 77,143,231,121,231,217, 19,167, 1, 0, 86,108, 92,107,
-149,144,144, 16, 96,109,109,253,192,180, 32, 3, 7, 14, 68,255,254,253,145,146,146, 18,180,107,215,174,160,159,127,254,249, 75,
- 47, 47,175, 5,105,105,105,223,213,109, 2,213,139, 61, 61, 61,103,205,153, 51,135, 4, 5, 5, 65, 46,151, 87,255,102,101,101,
-133,190,125,251,162,111,223,190,200,202,202,234,120,234,212,169,142, 91,182,108, 89,164, 86,171, 87, 70, 71, 71, 91, 20,229, 25,
- 59,118, 44,242,243,243,145,159,159,143,146,146,146, 76,141, 70,147,171,213,106, 51, 21, 10,197,237, 62,125,250, 36, 2,224,253,
- 60,108,218, 58, 59, 53,219,181,244,179, 69, 64, 61, 93,167, 51,186,119, 7, 0, 84, 92,255,255,106,107, 21,165, 20, 82,233, 45,
- 46, 51,115, 95, 77,115,101,169,102,149,193,116,184,119,239,158, 32,149, 74,209,174, 93, 59,201,173, 91,183,146,194,194,194, 54,
-156, 58,117,234,129,169, 13, 26,163,217, 0, 65,159,190,247,150, 52,239,238, 21,196, 95, 56,134, 17,106, 47, 69,204,141, 91, 11,
- 0,252,197, 96,177, 44, 59,239,240,225,195, 1,151, 47, 95, 14, 88,176, 96, 65,107,181, 90, 61, 28, 64,159, 35, 71,142, 64, 34,
-145,160,111,223,190,221,194,194,194,154, 73, 77,185,195,134,183, 33,115,222,156, 53,149, 0,192,250,239,215,191,189,230, 45,178,
-250,205,213, 52,173, 17,198, 74,202,178,236,202, 77,155, 54,189, 54,126,252,120, 36, 39, 39,227,220,185,115,176,182,182,198,226,
-197,139,125,230,204,153,179, 16,192,123,226,101, 47, 34, 34, 34, 34,242,143, 25, 44,150,226,189,136,203,113,109, 25, 83, 62, 33,
- 18,219, 90,215, 97, 24, 14,173,252,123,115, 83, 91, 62,101, 63,184,255, 0,219, 81,175,205,122, 15,192,239,150,108,216,198,198,
-166, 14, 77, 6, 45, 90,180,192,187,239,190,139,128,128, 0,217,171,175,190,250, 17,128,239,234,145,154,181, 99,199, 14, 82, 61,
-215, 91, 29,184,185,185,161,127,255,254,112,115,115, 35,239,189,247,222, 44, 0,181, 26, 44,133, 66,145, 75, 8,113, 6, 0, 71,
- 71, 71,172, 93,187, 22, 70,163, 81, 40, 47, 47,191, 94, 94, 94,126,213, 96, 48, 68,202,229,242, 75,103,206,156, 73, 4,128,182,
- 94, 74, 15,149, 76,117, 96,253,218,239, 96, 44,205,118,168,107,251,124,218, 95,125, 2,165,180,152, 81, 42,147, 37,247,239,239,
-146, 22, 23, 71,155,191,183, 84, 19, 0,122,246,236,105,111,101,101,117,122,205,154, 53, 18,169, 84,138, 73,147, 38, 89,101,100,
-100,224,171,175,190,122, 19, 53,230,142,106,140,102, 61, 6,166, 91,207, 80,245,254,111,151,125,162, 12, 12,237,137, 75, 59,215,
-160,168, 72,131,178,210,114,240, 2,149,215,246, 31, 74,105, 65, 98, 98, 34, 6, 15, 30,140,204,204,204,167,215,173, 91,183, 78,
- 16, 4,162,209,104,170, 39,106,181,182,182,190,211,187,123,152,140,185,187,168,201, 25,153, 16,226,108,107,107,187,253,232,209,
-163,193,193,193,193,184,116,233, 18,238,222,189,139,183,222,122, 75,255,214, 91,111, 73, 95,125,245, 85, 50,123,246,236,105,132,
-144,189,148,210,139,226,165, 47, 34, 34, 34, 34,242,143, 24, 44, 0, 44,171,106, 77,244, 39, 71, 9,172, 83,111,194,186, 15, 37,
- 68,225,241,192, 10,154,252, 36, 36, 92,220, 68,147, 98,247,211,230, 1,175, 16, 0,236, 67,133,107,117,168,134, 97,217,188, 21,
- 27,215, 58, 1,128, 76,217, 12, 59,118,236, 64,191,126,253,176,235,219,142, 40, 43,206,172, 44,104,237,220,241,252,140, 56, 36,
- 36, 36,224,252,249,243,230,137,102, 37,117,105,154,203, 86, 68, 69, 33,183, 71, 15,200, 10, 10,160, 82,169,170,103, 2, 55,115,
-235,214, 45,156, 57,115, 6,201,201,201,104,213,170, 85,229,127,234,208,172,168,168,104, 49,126,252,248,188, 87, 94,121, 69,249,
-203, 47,191,224,222,189,123,110, 17, 17, 17,165,181, 29,160,128, 22,246,118, 82, 65,122, 96,227,218,149, 18, 24, 52, 14, 9,145,
-231,241,212,224, 41,181,166, 83,219,187,119,117,228, 74, 25, 26, 10,166,101, 75, 3,145, 74,111, 23,172, 95, 63, 32, 48, 48,208,
-216, 88,205, 94,189,122,125,192,243,252,219,130, 32,200, 55,110,220, 40,113,114,114, 98, 86,172, 88, 97, 60,118,236, 24, 79, 41,
-101,164, 82,233,154,166,164,179, 62,228, 50,201,186,181, 95,126,164, 36,134,114,196, 28,254, 13,105,201, 41,184,118, 39,221,248,
-251,185,155,188,222,104,154, 90,219,241,228, 56,110,198,252,249,243,187,108,220,184,209,253,141, 55,222,128, 84, 42,125, 33, 63,
- 63, 31,219,182,109,131, 74,165,194,218,181,107,209,162, 69, 11, 25,207,243,184,114, 48, 31,107,191, 89, 13, 80, 10,173, 81,186,
-117,246, 38, 83, 90, 61,231,189,166,185,234,232,227,227,115,224,228,201,147, 46,158,158,158, 56,117,234, 20,178,178,178,224,238,
-238,142,183,222,122, 75,182,108,217,178, 45, 37, 37, 37, 35, 63,255,252,115, 69,108,108,236, 47,132,144,182,180,146,199,222, 3,
- 70,212, 20, 53, 69, 77, 81, 83,212,252, 91, 8, 6,224, 12, 32, 23, 64,228, 67,203,168,250,140, 90,150,243,170,202,252,102, 53,
-180,242, 80,217,134,218, 25, 0, 15,224, 50,128,194,191,197, 96, 17, 66,122, 3, 56, 5, 96, 33,165,244,211, 7,214, 16,140,224,
-115,142, 83, 62,231, 79,202, 56, 4, 17,214,125, 4, 41, 44,214, 34,254,226, 79, 52, 51,225, 36, 69, 85,123, 37,131,190,180,222,
- 13,125,179,219,203, 79, 38,147, 21,196,199,199,227,207, 63,255, 4, 0,236,222,189, 27,101,197,153,168, 81,117,136,175,191,254,
- 26, 38,147, 9, 12,195,192, 96,176,108,238, 99,170,171,108, 39,173,215,235,161,215,235, 65, 66, 66, 32,121,250,105, 36,190,245,
- 22,142, 31, 63,142,220,220, 92, 72,165, 82, 72,165, 82,139, 38,132, 53,153, 76, 36, 39, 39, 7, 90,173, 86, 48,213,241, 7, 47,
- 47,162,176, 49,169,118,125,183,242,115, 27, 27,107,149, 75,212,177,189, 72, 78,174,187, 93,186,209,104,252,255, 40, 93,171, 86,
- 21,224,184, 24,201,149, 43,191,215, 52, 87,141,209,228,121,254,157,173, 91,183, 90, 21, 22, 22, 66, 42,149,226,139, 47,190, 48,
-158, 61,123, 54,195,100, 50, 61, 29, 29, 29,157,223,212,116,214, 7,203, 73,127, 30, 50,102,226,226, 69,175,245, 69, 69,185, 22,
-123,206,198,225,207,216,251, 99, 0, 92,164,148,214, 58, 89,109, 68, 68, 68, 78,104,104,232,168,153, 51,103,158,248,249,231,159,
-149,227,198,141, 3,207,243,213,175,242,242,114,156, 60,121, 18,103,207,158, 69,116,244,181, 52, 41,109,247,167,155,170,116,251,
-111, 71, 45,155,164,153, 16,226,222,178,101,203, 67, 17, 17, 17, 78, 42,149, 10,225,225,225, 40, 42, 42,194,155,111,190, 89, 29,
-185, 42, 42, 42, 26,189,118,237,218,151,147,146,146,150,156, 63,127,190,160,234, 65,192, 4, 17, 17, 17, 17,145,127,156,122, 61,
-200,255,227, 76, 8, 57, 72, 41, 29, 10,160, 31, 0, 89,141,101, 16, 66, 14, 86, 25,191, 7,150,231,205,155,247,193,210,165, 75,
-111,152,151,205,235,204,159, 63,255,169,101,203,150, 45,233,214,173,219,182, 11, 23, 46,220,251,219, 12, 22,128, 83,148, 82,210,
-128,141,129, 80, 24, 73,133,194, 72,250,231,209, 91,127, 53, 37,186,226, 70,111,220,219,219, 27,113, 55,255, 98,110,170, 63, 91,
-106,176,208,163, 7,144,153, 9,184,187, 87,166, 52, 51, 19, 6, 0, 63,204,159, 15,153, 76, 86, 93, 21, 85,101, 76, 26,148,211,
-235,245, 36, 55, 55,151,106,181,218, 88,157, 78,103,170, 37, 51,144,214,174,182,191, 45,152,247, 86,243,150,173,218,184, 71, 28,
-218,142,123,247,210,145,157, 93,251,249,177,182,182, 46, 51, 26,141,214, 85, 39,246, 42, 97,152,124,229,149, 43, 59, 1,196, 53,
- 85,147, 16,114,100,220,184,113, 67, 67, 67, 67, 73,251,246,237,101, 39, 78,156, 48,241, 60,255,128,185,106,172,102,125,120,120,
-120,244, 27, 59,118,236,167,147, 39, 79,198,200,193,253,241,122, 31,127,164,100, 23, 25, 1,156,168,111,146,230, 42,147,117, 93,
-173, 86,191, 60,122,244,232,111,124,125,125,189, 1, 32, 32, 32, 0, 47,191,252, 50, 86,173, 90,133,240,240,240, 95, 0,108,140,
-142,142,190,210,200,139, 82,229,224,224,176,239,196,137, 19, 78, 42,149, 10,199,142, 29, 67,121,121,249, 95, 34, 87, 75,150, 44,
- 81, 36, 37, 37,173, 56,122,244,104,123, 0, 76,213, 52, 61, 34, 34, 34, 34, 34,255, 14, 44,240, 32,213,247,253,131,148,210,161,
- 53, 13,211,195, 70,203,252,217,188,222,210,165, 75,135,214, 52, 95, 0,176,108,217,178, 37, 53,150,203,255,142,157, 50, 27,172,
- 48, 66, 8, 5, 16, 70, 41, 61,221, 20, 33,163,174,180, 73, 35,150,202,148,205,176, 98,227,218,202,131,196, 61,216, 46,203,226,
- 8, 86, 35, 6, 75,181, 36,130,101, 48, 24,132,194,194,194, 36,141, 70, 19,125,243,230,205,191,152, 7, 79, 79,207,165,221,122,
-118,237,222,166,115,136, 50,226,200,110,220,185,157,140,188,188, 98,128, 82,109,109,122,142,142,142,249,204,180,105,214,170,204,
-204, 34, 70, 16,210,125, 98, 99, 95,124, 84,205,243,231,207,191, 22, 26, 26, 26,120,225,194,133,112, 91, 91, 91, 0,160, 53,205,
- 85, 83, 52,107, 49, 85,221, 56,142,219,207, 48,140,114,224,192,129,152, 49, 99, 6, 86,173, 90,101, 42,172, 48, 44, 92,177,255,
-210,155, 26,157, 97, 90, 67,230,202, 76,116,116,116,248,152, 49, 99, 58, 94,189,122,213,131, 82, 58,200,193,193, 97,133,209,104,
-132, 32, 8,160,148, 30, 48,153, 76,183,131,130,130,182, 58, 59, 59,247,205,201,201,217, 26, 29, 29, 61,179,129,139,140,145, 74,
-165,191, 28, 63,126,188,131,135,135, 7,194,195,195, 81, 94, 94, 94, 29,185,122,237,181,215, 30,136, 92, 93,184,112,161, 64, 52,
- 87, 34, 34, 34, 34,255, 74, 44,246, 32,102,211,244,176,201,106,140, 57, 3, 80, 49,111,222,188, 15, 8, 33, 7,171, 34, 92, 21,
- 0, 50, 30,247, 78, 49, 85, 9, 62, 93,229, 30, 79, 61,184, 39,150,151, 69, 6,125, 73,147, 18,208,250,233, 45, 8, 28,113, 26,
-247, 12,111, 34,155,153,250,112, 36,201, 50,131,181,123,119,101,244, 42, 51,243,255, 35, 89, 85,209,172,166, 24,172,178,178,178,
-235, 5, 5, 5,177,197,197,197,151, 0, 8, 15, 69,221,166,118,238,220,249,181,245,191,108,182, 57,112,228,100,121,116,228, 13,
- 77,118, 78, 17,202, 13, 70, 67,108, 74,246,154,218,244, 92, 92, 92, 10, 41, 80,192, 25,141,199,101,215,175,239,172, 37,146,215,
-104,205,170,200, 80, 12,128,131, 71,142, 28,185,195,178,236,183,143, 67,179,166,185,106,214,172,217,190,205,155, 55, 43,119,237,
-218,133, 9, 19, 38,224,203, 47,191,196,145, 35, 71,158,215,104, 52, 43,202,180,250, 86,148,210,227,150,158,231, 85, 83,136, 91,
-111,167,157,238, 28,199,217, 53,107,214,108,209, 43,175,188, 2,147,201,132, 62,125,250,192,217,217,121,155, 84, 42, 61, 61,113,
-226,196,225,203,151, 47, 87,181,108,217,114,146, 90,173,118,107, 64,242,179, 45, 91,182, 12, 14, 8, 8,192,249,243,231, 81, 92,
- 92, 12,119,119,119,188,253,246,219,178,101,203,150,109,253,246,219,111,181, 75,151, 46,149,246,239,223,127,197,209,163, 71,187,
-148,151,151, 15, 16,205,149,136,136,136,200,191,143, 58, 61, 72, 61, 38,171,137,219, 49,255, 79,178,116,233,210, 27,148,210,161,
-203,150, 45, 91, 2, 64,249,183, 69,176,170,156, 35, 0,132, 61,232,175,202, 44,143, 96,105,235, 55, 88,239,140, 74,187, 37,240,
- 60, 86,205, 97, 33, 83, 54, 67,235,167,183, 52, 24,149,106,108, 27,172, 90,220,234, 95,150, 45, 49, 88,229,229,229,209, 57, 57,
- 57,119,239,223,191,127,182,230, 32,162,222,222,222,195, 92, 93, 93, 23,111,217,178, 69,153,145,145, 1,175,182,254,182,107,119,
-254,174,115, 85,201,181,169, 69, 5,147,175,165,149,237,169, 77, 79,161, 80,196,211,164,164,155,178,132,132,163, 4,184,241,144,
- 17,106,146,166,153,139, 23, 47,190, 86,139, 97,123, 36, 77, 15, 15,143,110, 78, 78, 78,251,190,255,254,123, 85, 70, 70, 6,164,
- 82, 41,172,173,173,113,226,196, 9,100,100,100, 28,111,108, 38, 91, 51,137,124, 40, 19,240, 62,120, 48, 61,188,211,117, 47,190,
-255,189,210,209,209, 17, 87,174, 92, 65,135, 14, 29,176,124,249,114,217,173, 91,183,218,183,107,215, 14,183,111,223, 70,102,102,
-102,124,116,116,116, 86, 61, 79, 33,195, 39, 79,158,252,206,243,207, 63,143,203,151, 47, 35, 51, 51, 19,211,166, 77,211,191,253,
-246,219,210, 87, 95,125,149, 20, 23, 23,143, 94,179,102,205,203,247,239,223, 23, 35, 87, 34, 34, 34, 34,255,114,234,242, 32,245,
-112, 8,192,179, 15, 71,181, 30, 54, 95,230, 8, 85,205,229,135,215,175,250, 93,251,119,236, 23, 87,181, 49,242, 87,131, 3, 65,
- 48,228, 83,198,107, 28, 17, 50,119, 83,240,117,108,159,101,193,201,172, 81, 81, 94, 42, 80,250, 96,180,167, 38, 2,207, 59,213,
-108,204,206,178,108,157,237,161, 88,150,133,157,157, 29, 74, 75, 75, 1,192,216,192, 62,240,198,231,159,103,101,207, 61, 7,131,
-155, 27,168,193, 80, 25,197, 2,128, 15, 62,120, 96, 69,169, 84,106,142,138,213, 91,173, 85, 82, 82,114, 57, 58, 58,250, 2,165,
- 52, 7, 0,122,247,238,189,154,231,249, 97, 86, 86, 86,246,147, 38, 77, 50,228,229,229, 97,207,158, 61,248,233,167,159, 42, 52,
- 6, 54,166, 72,111,122, 35, 49,189,172,206, 17,237,243,242,242,254,244,142,143,223, 85,243,187, 71,213,172,141,199,161,233,225,
-225,209,205,197,197,165,218, 92,201,229,114, 88, 91, 91, 35, 61, 61, 29, 28,199, 53,122,144,206,173,111, 18,123, 80,188, 59,229,
-157, 41, 12,195, 48,204,250,213, 63, 42,237, 85, 20,191,254,250, 43,118,236,216,145,224,239,239,223,110,226,196,137,240,243,243,
- 67, 66, 66, 2, 86,174, 92,153, 97, 48, 24, 94,168, 55,211,114,220,107,139, 23, 47,166, 25, 25, 25,228,238,221,187,213,145,171,
-165, 75,151, 86,183,185,186,119,239,158,216,230, 74, 68, 68, 68,228,191, 35,130,101, 73,251,171,188, 42,243,148, 93,203, 50, 91,
-195, 88, 61,188,156,243,208, 50, 0,232, 31,250,253,234,223,102,176,106,221, 97,130,239,199,140,236, 59,235,147,247,166,184,182,
-247,155,167,160, 57,127,128, 22, 71, 83,152,155,220, 16, 6, 50,107, 39,128,147,211,168,155,121,101, 39, 99, 43,242, 40,193,247,
-150,110,184,125,251,246,200,202,202, 66, 65, 65, 65,245,119, 12,195,192,209,209, 17, 10,133, 2, 81, 81, 81, 56,127,254,188, 17,
-192,226, 6, 78,204,178, 87, 95,125,117,254,155,111,190,201,132, 76,152, 0,195,217,179, 15,116, 15, 35,132, 64,161, 80, 64,169,
- 84, 34, 61, 61, 29,183,110,221, 18, 40,165,203,234,211, 76, 76, 76, 60, 79, 41,205, 5,128,176,176,176,113,142,142,142, 99, 38,
- 76,152,160,188,124,249, 50, 62,251,236, 51, 46, 60, 60,220, 16, 25, 25,105, 18, 4, 97,126, 90, 90,198,134,134,246,245,230,205,
-155,145, 53,151, 31,135,230,195, 60, 14, 77, 79, 79,207,174, 30, 30, 30,251,190,249,230, 27, 85, 86, 86, 22,228,114, 57,108,108,
-108,144,146,146,130,197,139, 23,107, 76, 38,211,115,143, 35,211,105,181, 90,236,218,181, 43,211,215,215, 55,228,218,181,107,125,
-230,206,157,187,218,199,199,199, 35, 37, 37, 37,137,231,249,103, 35, 35, 35,147,235,251,191,189,189,125,168,179,179, 51,185,120,
-241, 34,166, 77,155,166,159, 62,125,186, 24,185, 18, 17, 17, 17,121,178,185,220,192,242,191,142, 58, 39,123,190,121,143,254,148,
-120, 43,117,248,184,201, 31,110,125,227,237,249,233,183,243,154,233,136,235, 8, 66,228, 30,144,219,186,195,214,221, 31,247,115,
-185,138,239,118,101,164, 29,140,168,216, 89, 81,134,145, 55,239,209,159, 30, 10,251,249,215,136, 74,229,174,216,184, 22, 43, 54,
-174,133, 73,144,232, 95,127,253,117,228,229,229,225,222,185, 87, 16,179,175, 55,124,165,107,224, 70,215, 33, 55, 55, 23, 63,252,
-240, 3, 13, 15, 15,223,109, 52, 26,187,100,100,100,124, 95,151, 38, 0,196,196,196, 44, 73, 79, 79,239,246,193, 7, 31,132,191,
- 89, 90,138,248, 53,107, 32,123,245, 85, 48,157, 58, 65,165, 82,193,201,201, 9, 26,141, 6,167, 79,159,198,181,107,215,194,117,
- 58, 93,183,152,152,152, 37,245,105,154,205, 85,143, 30, 61,172,139,138,138,190,126,245,213, 87,149, 26,141, 6,121,121,121,200,
-203,203, 67, 68, 68,196, 9,189, 94, 31,156,150,150, 86,167,105,169,169, 73, 41, 77, 53,127,126, 92,154, 53,121, 92,154, 42,149,
-106,230,158, 61,123, 84, 12,195, 64, 46,151,195,206,206, 14,169,169,169, 88,180,104,145,166,162,162,226,185,140,140, 12,139, 6,
-232,172,169, 57,118, 13, 45, 2,193,215,235,190, 89, 39,172, 89,185,150, 82,199,222, 80,218,121,194,206,206,206,113,231,206,157,
-194,213,171, 87,143,123,120,120,180,187,125,251,182,191, 78,167, 11,190,116,233, 82,114, 67,154,121,121,121,103,146,146,146, 96,
-101,101,133,233,211,167,203,150, 44, 89,178,245,219,111,191,213, 46, 89,178,164, 81,109,174,234, 58,158,143,130,168, 41,106,138,
-154,162,166,168, 41, 82,111, 4, 11, 0,174,167,208,251, 0,222,233,220,154, 4,188,244,230,242,153,189, 66, 90,117,125,251,165,
- 96,135, 18,161,152,238,217,127,167,224, 94,106,217,101,142,197,170, 27,247,104,131,225,181,119,190, 54,181,168,185,252,157,151,
- 87,240,132, 9, 19, 62,155, 51, 38,167,123,205,170,195,205,219, 55,159, 37,132,124,152,153,153,105,113,151,253,232,232,232, 27,
- 0,158, 11, 12, 12,236, 57,123,246,236,197,163,188,189,131,198,133,133, 65, 34,145, 32, 50, 50, 18,249,249,249, 81, 0, 62,142,
-137,137, 57,215,152,131, 83, 82, 82,242,137,159,159,159,244,230,205,155, 72, 76, 76,196,173, 91,183,192,243,252,221,180,180,180,
-231,155,122,192,255,205,154, 90,173,246,171,207, 62,251,172,239,194,133, 11,229, 54, 54, 54,184,114,229, 10, 22, 46, 92,168,209,
-106,181, 22,155,171,218,120,243, 71,250,249,170, 41,228,167,243,247,124,251,119,240,236,182,198,104, 52,194,197,197, 69,214,181,
-107, 87,119, 0, 25, 59,118,236,224, 1,220,107,132,228,199, 1, 1, 1,126,159,125,246, 89,235,215, 94,123, 13, 69, 69, 69, 98,
-228, 74, 68, 68, 68, 68,228,191,199, 96,153,185,150, 72,175, 2,120,181, 83, 43,210,231,108,228,221, 73,149,246, 21,235,227,238,
-211, 83, 77,221,112, 90, 90, 90, 36,128,254, 43,102,145, 7,198,159,200,204,204, 28,212, 84,205, 42, 3,213, 59, 32, 32, 96,248,
- 30,150,125, 15,247,238,129,231,249,175,174, 94,189,186,191, 49, 58, 93,187,118,245, 41, 45, 45,253,209,104, 52,118,230,121, 94,
-118,250,244,105,104,181, 90,196,197,197, 85, 8,130,176,167, 41,105,251,111,208, 76, 77, 77,141,246,240,240, 24, 74, 8, 57, 56,
-119,238, 92,249,162, 69,139, 30,217, 92,153,153,185,142,102,109, 86,171, 79,177,183,110,241, 70,163,145, 53,153, 76,224,121, 94,
-218, 20, 45, 74,105, 34, 33, 36,100,214,172, 89, 31,191,251,238,187, 51,151, 45, 91, 38, 21,219, 92,137,136,136,136,136,252,215,
- 25, 44, 51,177,119,233, 73, 0, 39, 31,103, 2,170,170, 14,157,205,159, 31,135,102,149,161,218,223,212,255, 23, 23, 23,127, 90,
- 80, 80, 16, 82, 82, 82, 98,186,119,239, 94, 5, 33,132,103, 24,166, 66, 16,132,165, 60,207,111,120,146, 53, 51, 50, 50, 46,186,
-187,187,247,191,112,225,194,244,242,242,242,117, 25, 25, 25,151, 30,215,185,142,142,142, 78, 85,171,213, 31, 77,154, 52,233,101,
-147,201,244,123, 84, 84, 84, 82, 83,181, 40,165,122, 0, 31, 17, 66,246,197,198,198,254,122,225,194,133, 44,209, 92,137,136,136,
-136,136,252, 87, 26,172,191,131,135,171, 14,255, 13, 36, 36, 36,188, 6,224,181,255, 69, 77, 0,200,204,204,140,249, 59,116,171,
- 76,214,183, 0,190,125, 92,122,148,210,104, 66, 72, 7, 84,246, 18, 17,205,149,136,136,136,136,136,104,176, 68, 68, 30,147,201,
-162, 16,231, 22, 20, 17, 17, 17, 17,249, 23, 65, 0,248,215, 81,104, 89, 60, 83,118, 83,122, 19, 52,164, 47,106,138,154,162,166,
-168, 41,106,138,154,162,230,147,167,217,144,118, 99,252,199,191,218, 96, 53,102, 30,191, 70,139, 19,226,255,184, 15,148,168, 41,
-106,254, 39, 52, 73,229, 52, 0,164,242, 90,183,252, 34, 17,143,167,168, 41,106,138,154,162,166, 8, 32, 86, 17,254,231, 29, 45,
- 33, 12,254,127,252, 49,161,177, 5,184,200,223,126,126,204,198,138, 3,192, 2,224, 9, 33, 38,241, 60,137,136,136,136,136,252,
-173, 6, 43, 52, 52,180, 53, 0, 68, 68, 68, 36,254, 27,118,160, 75,151, 46,167, 91,181,106,213,252,206,157, 59, 70, 66, 8,106,
-190, 0, 64, 38,147, 93,184,112,225,194,235,255,134,180,118,236,216, 81,250,212, 83, 79,237,151, 74,165,189,106,126,175, 86,171,
-205, 31, 5,107,107,107,167, 83,167, 78,233,158,180,140,102,101,101,165, 97, 89,150, 48, 12, 3,150,101,241,240,123,109,223, 17,
- 66, 92,226,226,226, 52,117,105,142, 27, 55,206,166,172,172,108, 40,165, 52,134, 16, 18, 72, 41,141,225, 56, 46,208,100, 50, 61,
-240, 46,147,201, 78,109,219,182, 45,211,146,116, 6, 6, 6, 42, 56,142,139, 55,153, 76, 78, 15,255,166, 86,171,193,178, 44, 46,
- 95,190,172,122,146,206,141,191,191,255,137,144,144, 16,191, 43, 87,174, 24, 40,165,213,215, 15,195, 48, 32,132, 64, 16,132,204,
-168,168,168,238, 79,242,141,208,221,221,189, 39,128,229, 85, 29, 38,106,114,139, 16,242,110,122,122,250, 41,136,136,136,136, 60,
- 78,131, 21, 18, 18,210,134,231,249, 94,132,144,158,148,210,158,237,219,183,119, 41, 47, 47,135, 90,173,206, 33,132,156,163,148,
-158, 99, 89,246,236,229,203,151,239, 52,164,213,189,123,247, 40,189, 94,223,190, 81, 9,228,184, 82,133, 66,209,250,212,169, 83,
-181, 22,180,174,174,174, 45, 55,111,222,236, 24, 27, 27, 11, 43, 43,171, 7, 94, 28,199,161,107,215,174,193,255, 22,115,197,178,
-236, 1, 15, 15,143,238,251,247,239, 71,108,108,108, 77, 99, 5,158,231,209,171, 87, 47,198,201,201, 73, 6,192, 34,131, 21, 26,
- 26,154,100, 50,153,156, 27,147, 14,169, 84,154,123,241,226, 69,139,122,110,246,232,209,195,218,100, 50,205, 98, 89,182,183, 32,
- 8, 29, 0,128,101,217,155, 38,147,233, 52,199,113, 43,207,159, 63,111,241,108,224, 44,203,146,188,188, 60,108,219,182, 13,254,
-129,161,160, 20, 8,232,216,166,218, 8, 71,196,220, 4,207,243, 56,127,234, 8,230,204,153,131,192,192, 64,104, 52, 26,182, 62,
- 77, 65, 16,142, 88, 89, 89,117, 54, 47,215,156,220,251,161,137,190,163, 1, 60,221, 80, 26,213,106,181, 82, 34,145, 36, 40,149,
- 74,199, 35, 71,142,224,210,165, 75,104,211,166, 13,120,158, 7,165, 20,148, 82,140, 28, 57,242,137,187, 9, 48, 12,227,185,110,
-221, 58,187, 99,199,142, 65,169, 84, 86, 95, 63,214,214,214,176,178,178,194,179,207, 62,203, 63,174,109,169,213,234, 45, 0, 70,
- 84, 45,158,138,142,142,126,182,169, 90, 78, 78, 78,214,114,185,124,150, 92, 46,239,109, 50,153, 58, 16, 66, 32,145, 72,110,234,
-116,186,211, 21, 21, 21, 43,243,242,242, 44,206,159,132,144, 47, 55,108,216,208,161,121,243,230,200,206,206, 70,110,110, 46,138,
-139,139, 81, 90, 90,234,183,113,227,198, 85, 0, 58,137,197,133,136,136,200, 99, 49, 88,106,181,122, 15,128,158,237,219,183, 87,
-246,239,223, 31,129,129,129,240,241,241,129, 66,161, 0, 0, 20, 20, 20,184,196,197,197, 61,127,229,202,149,231, 47, 94,188, 8,
-181, 90, 93, 65, 8,185, 24, 21, 21, 53,188,158, 2,209,235,200,145, 35,112,114,114,178, 40,113,130, 32, 96,240,224,193,146,226,
-226, 98, 21,128, 90, 13, 86, 86, 86,150,240,201, 39,159, 20,159, 63,127,222,192, 48, 12, 40,165,164, 70, 53, 15, 76, 38, 83,193,
- 63,125,144, 9, 33,204, 83, 79, 61,181,175,202, 92, 49, 18,137, 4, 81, 81, 81, 72, 79, 79,135,139,139, 11,172,172,172, 32,151,
-203, 33, 8, 2,238,223,191,159, 25, 18, 18, 34, 40,149,202, 6, 35, 89, 38,147,201,249,220,185,115,213,231,164, 33,120,158, 71,
- 72, 72,136, 69,134,172, 75,151, 46, 79,203,229,242, 95,167, 77,155,102,215,189,123,119,206,203,203, 11,132, 16,100,101,101,133,
- 92,184,112, 33,112,205,154, 53, 19,187,116,233, 50,254,202,149, 43,103, 44, 52, 88,216,180,105, 19, 62,251,236, 51,204,254,232,
- 75,188, 61, 97, 52, 8, 33,144,203,229, 40, 46, 46, 70,104, 96, 7,172,221,180, 15,219,182,109, 67, 69, 69, 5, 88,150, 69,203,
-150, 45, 27,138,138,181, 91,189,122, 53,102,205,154,133,149, 43, 87, 86,191,207,158, 61, 27, 43, 86,172,192,156, 57,115,176,124,
-249,114,204,153, 51, 71,253,250,235,175,203,127,254,249,103, 93,125,231, 40, 36, 36, 36,190,202, 92, 17,169, 84,138,194,222,189,
-145, 12,192, 38, 46, 14,214,214,214,208,235,245, 96, 89, 22,106,181,186,188, 41,145,172, 78,157, 58,157, 99, 89,214,211,130,243,
-148, 30, 27, 27,219,243, 17,242, 91, 63, 0,115,170, 22,151, 83, 74,143, 55,112,157,165, 79,157, 58,213, 42, 38, 38,166,174, 8,
- 86,206, 35, 24,170,102,132,144,239, 0, 40, 89,150,125, 23,192,160,240,240,112, 48, 12,131, 1, 3, 6,132,169,213,106, 63, 0,
- 75, 85, 42, 21,213,235,245,211, 34, 34, 34, 44,218,150,151,151,215,211,182,182,182,191,206,159, 63,223,174, 71,143, 30,156,179,
-179, 51, 34, 34, 34, 96,111,111, 31,114,246,236,217, 46, 63,254,248,227, 68, 47, 47,175,241,105,105,105,103, 44, 76,106, 91,111,
-111,111,124,252,241,199,176,181,181,133,163,163, 35, 28, 28, 28,224,232,232, 8,119,119,119,223,241,227,199,103, 22, 20, 20,148,
- 93,191,126,125, 33, 33,228,116,106,106,106,166, 88,124,136,136,136, 52, 53,130, 53,224,244,233,211, 48, 26,141,176,177,177, 1,
-203, 62, 24, 76,112,116,116,196,211, 79, 63,141,208,208, 80,244,235,215, 15, 9, 9, 9,202, 47,190,248,226,153,134, 54,168, 82,
-169,112,241,226, 69,152, 76, 38, 68, 71, 71,163,180,180, 20,195,135, 15,135, 68, 34,129, 68, 34, 1,199,113,213,239,174,174,174,
- 80, 40, 20,164,184,184,184, 78, 61, 59, 59,187, 86,135, 14, 29, 98,228,114, 57,181,182,182,166,167, 79,159,166, 0, 40, 30,161,
-205, 76,112,112,176, 43,199,113,159,241, 60, 63,146,231,121, 89, 61,166,193, 40,149, 74, 15,104,181,218,143,162,163,163, 83,235,
- 40,236, 8, 0, 70, 46,151, 63,189,107,215, 46, 72, 36, 18, 0,128, 76, 38,131, 92, 46,135, 66,161,168,126,247,243,243,195,140,
- 25, 51, 48,121,242,100,139, 35, 89, 10,133, 2,167, 78,157, 2,199,113,232,216,171,178,230, 49,229,234, 85, 72, 36, 18,184,119,
-236, 8, 0, 40, 75, 73,129, 68, 34,129,155,155,155, 69,251, 31, 16, 16,208,175,121,243,230, 91,191,249,230, 27, 37,203,178,184,
-125,251, 54, 8, 33, 96, 89, 22, 57, 57, 57,232,217,179, 39,231,239,239,223,108,254,252,249,187, 2, 2, 2,198, 94,189,122,245,
-184, 5, 81, 18,188,250,234,171,248,234,171,175, 48,125,226,104,152,231, 59,212,235,245,213,235, 76,123,117, 4,126, 89,179, 20,
- 31,127,252, 49,254,248,227,143,134,162,119,183, 66, 67, 67,101,185,185,185, 80, 40, 20,200,201,201,129, 82,169,124,224, 93,161,
- 80, 32, 59, 59, 27, 74,165, 18, 87,174, 92,185, 19, 22, 22,214,242,212,169, 83,166, 58,206, 17,103, 50,153,156,142, 28, 57, 2,
-169,180,114,128,249,114, 0, 60, 0,103,103,103,232,116, 58, 40, 20, 10,180,104,209, 2, 31,126,248, 33, 94,127,189,241,181,206,
- 44,203,122,198,196,196, 52,104,112, 3, 3, 3, 31,245,186,158, 67, 41,237, 89, 35,146, 87,239,249,185,126,253,250, 51, 0, 48,
-106,212,168, 19,254,254,254,126,241,241,241, 6,243,127,171, 94,238, 47,191,252,114,146,217,116, 81, 74, 51,127,251,237, 55,139,
-170, 12, 9, 33,203, 15, 28, 56, 48,204, 96, 48, 96,194,132, 9,209,190,190,190,156,157,157, 29, 54,110,220, 8, 7, 7, 7,232,
-245,250,203, 95,127,253, 53,151,156,156,140,239,191,255,126, 93,141,232, 86,157,120,120,120,244,243,245,245,221,186,125,251,118,
- 37, 0,220,187,119, 15,105,105,105, 56,118,236, 24, 94,122,233, 37,140, 30, 61, 90,210,163, 71,143,102,211,167, 79,223,229,225,
-225, 49, 54, 35, 35,227,184, 37,105,181,183,183,231,231,206,157,203,170, 84,170, 7, 34,225,135, 14, 29, 34, 95,124,241,133,237,
- 55,223,124, 99, 51,116,232,208, 57, 63,252,240, 67, 87, 47, 47,175,101,105,105,105, 25, 98, 17, 34, 34, 34,210, 20,131, 5, 43,
- 43, 43, 68, 70, 70,130, 16, 2, 27, 27, 27,216,218,218,194,206,206, 14, 37, 37, 37,136,139,139, 67,124,124, 60,238,223,191, 15,
-134, 97,208,170, 85, 43,152,163, 70,102,106,235, 97, 96, 46,168,147,146,146,144,149,149, 5,134, 97,112,230,204, 25, 12, 26, 52,
-232, 1,115,101, 54, 34, 15,243,176,230,169, 83,167, 76,239,190,234,118,194,160,215, 56,153, 76,250, 11,167, 40,157, 22, 24, 24,
-120,218,197,197,197, 43, 32, 32,128, 55, 87, 21,213,215, 46,235, 97, 77,150,101,151,190,249,230,155,207,143, 25, 51,134,225, 56,
-238,129, 8,144, 94,175,135, 94,175,135,209,104, 68, 69, 69,133,100,215,174, 93,207, 29, 60,120, 80, 5, 96, 84,125,233,228,121,
- 30,113,113,113,184,118,237, 26, 24,134,129,131,131, 3,108,109,109,161, 80, 40,160, 84, 42, 33,147,201,160, 82,169,160, 80, 40,
- 32,145, 72,112,255,254,253,204,206,157, 59, 11, 37, 37, 37, 78, 73, 73, 73,186,186,142, 39, 0,112, 28,135,154,233, 52, 31,195,
-186,150,235, 75,103,104,104,168,141, 76, 38,251,105,197,138, 21,202,156,156, 28,196,198,198,162,115,231,206,248,240,195, 15,161,
-209,104,176,124,249,114, 36, 38, 38,194,197,197, 5, 31,124,240,129,242,221,119,223,253, 41, 52, 52,180, 67, 68, 68, 68,105,125,
-231,157, 97, 24,108,216,176, 1, 38,147, 9, 12, 83,217,198, 95,167,211, 65, 46,151, 63,156, 30, 44, 88,176,160,122,157,186, 52,
- 5, 65,112,115,113,113,193,169, 83,167,160, 84, 42,113,250,244,105, 40,149, 74,156, 57,115, 6, 10,133, 2,103,206,156,169, 94,
-182,178,178,130, 32, 8,118, 85,249,221, 84,139, 38, 65,101,131,118, 92,185,114, 5, 89, 93,187,162, 28,128,205,254,253,176,109,
-209, 2,112,118,134, 19, 0, 77, 94, 30, 84, 42, 21,228,114,121,157,145, 44, 75,122,213,196,199,199, 67,167,251,171,119,150,203,
-229,104,223,190,125,131,231,168,150,107,170,147,139,139,203, 15,126,126,126,254, 0,240,244,211, 13,214,134,214,117,109,122,126,
-244,209, 71,118,155, 55,111,134, 92, 46,135, 82,169,132, 74,165,130, 74,165,122,224,243,135, 31,126,200, 91,170, 9, 64,150,144,
-144, 0, 27, 27, 27,172, 95,191,158,115,116,116, 68,116,116, 52, 56,142,195, 43,175,188,130, 78,157, 58,113,230,243, 87, 86, 86,
-214,160,102,235,214,173,109,100, 50,217, 79, 91,183,110, 85,206,155, 55, 15, 65, 65, 65,240,243,243, 3, 33, 4,163, 70,141, 2,
-165, 20, 69, 69, 69,112,118,118,198,215, 95,127,173,156, 60,121,242, 79,173, 91,183,238,144,152,152, 88,218, 64, 58,169, 78,167,
-163, 10,133,162,250,161, 71, 46,151, 67, 42,149,162,164,164,132,190,255,254,251, 37, 44,203, 50, 35, 70,140,240,125,235,173,183,
-152,133, 11, 23,246, 1,240, 91, 99,206,123, 99, 17, 53, 69,205,255, 53,205,134, 98, 31, 0,106, 62,160,234, 1,152, 3, 32,121,
- 85,247,241,102, 15,125, 15, 0,230, 25, 98,156,235, 88,206, 3, 16, 7,160, 67,213,119, 60,128,203, 0, 10, 31,139,193, 34,132,
-208, 26, 7,141,212,114, 32, 81, 82, 82,130,146,146, 18,164,166,166, 98,237,218,181,213,133, 54,199,113, 96, 24, 6, 38,147,229,
-227, 60, 74, 36, 18,164,166,166, 34, 32, 32, 0, 46, 46, 46,248,249,231,159, 49,116,232,208,106, 61,243,171,166, 41,170,143,238,
-125, 94,110,255, 92,135, 91, 54,111, 46, 11,167, 64,101,187,172,125,251,246, 57,222,190,125,187,218,192, 40,149,202,106,243,210,
- 80,187, 44, 65, 16,134,141, 30, 61,154, 9, 15, 15,135,201,100, 2,199,113,144, 74,165,144,201,100, 96, 89, 22, 82,169,180,250,
- 53,108,216, 48,102,247,238,221,207,132,133,133,113,181, 69, 71,104,101,157,165, 64, 8,129, 90,173, 70, 94, 94, 30,164, 82, 41,
-108,108,108, 96,103,103, 87, 93, 96,203,100, 50, 88, 89, 89, 65,161, 80,160, 83,167, 78,152, 60,121, 50, 38, 77,154,196, 56, 58,
- 58, 54, 24,201,170, 25,185,226, 56, 14, 30, 53, 34, 87, 28,199, 65,225,238,110, 78,140, 37,167,103,230,132, 9, 19,108,228,114,
- 57,174, 95,191, 14,185, 92, 14,141, 70,131, 17, 35, 70,160,172,172, 12, 38,147, 9,114,185, 28, 58,157, 14,174,174,174,232,215,
-175,159, 85,120,120,248, 76, 0,139, 26,136,222,224,141, 55,222,192,234,213,171,241,205,143,219,241,206,164, 23,254,178,206,154,
- 95, 42,167, 79, 92,184,112, 33, 78,157,106,184, 77,241,128, 1, 3,112,230,204, 25,120,122,122,162,160,160, 0, 94, 94, 94, 40,
- 44, 44,132,143,143, 15,138,138,138,224,235,235,139,210,210, 82,244,238,221,187,161,136, 24,173,186,168,224,239,239, 15, 1,149,
-221, 59,109, 91,180, 64,179,102,205,160, 64,101,183, 79,185, 92, 94,109,130,155, 26,201,162,148, 98,238,220,185,197, 25, 25, 25,
-134, 90, 34, 51,210,221,187,119,219, 53, 38,240, 74, 8,233,220,190,125,251,163, 39, 78,156,176,118,117,117,133,201,100,130,209,
-104,132, 70,163,193, 11, 47,188, 0, 0,123, 26,145,182,244,207, 62,251,204,170,150, 8,214, 3,213,134,148, 82,139,171, 12, 57,
-142,155, 55,119,238,220, 65, 35, 70,140,224,108,108,108, 32,145, 72, 32,147,201, 32,147,201, 32,149, 74,145,148,148, 4,163,209,
-136, 29, 59,118, 80,150,101,223,107, 72, 79,167,211,205,252,224,131, 15,108, 36, 18, 9,218,181,107,135,153, 51,103, 98,203,150,
- 45,240,240,240,128, 76, 38, 67, 51, 85, 22, 24,134,131,142, 87,161, 77,155, 54, 24, 58,116,168,213,238,221,187, 27,204,159,148,
-210,235,122,189, 62, 80,169, 84, 86, 71,148,205, 85,239,233,233,233, 55,207,156, 57, 19,226,230,230,214,190, 93,187,118,235,194,
-194,194,252,155, 53,107, 22, 76, 8,217, 44,246, 44, 21, 17,121,116, 26,242, 32,102, 67, 68, 8, 57, 88, 99,189,161,230,229,121,
-243,230,125,176,116,233,210, 27,132,144,131, 53,191, 55,175, 87,181,141,131,181, 45, 87,253,183,217,252,249,243,253,151, 45, 91,
-182,164, 91,183,110,219, 46, 92,184,112,239,177, 25,172,170,118, 75,180,158, 29,251, 75, 20,234, 97, 44, 49, 88,230,155,180, 78,
-167, 67, 94, 94, 30, 6, 12, 24, 0,165, 82, 9,134, 97,144,154,154,138,182,109,219,130,227, 56, 92,189,122, 21,159,124,242, 9,
- 58,118,236, 8,131,193,208, 96,154,142, 30, 92, 95,113,225, 56, 95, 33, 8,149, 55,254,236,236,108,186,116,233,210,178,240,240,
-112,253,255,111,186, 90,134, 52,212, 46,139, 82,202,113, 28, 7,163,209,248, 64, 47, 55, 66, 8,250,244,233,131,179,103,207, 86,
-127, 87, 21,129, 97, 30,142,142,212, 82,128, 67, 16, 4,184,184,184, 64, 38,147,161,230,141,220, 92,224,152,205, 86,205,155,123,
-163, 78,230, 67,145,191,250, 34,129,117,193, 48, 76, 88,175, 94,189,184, 91,183,110, 85,167,203, 96, 48,160,119,239,222, 96, 24,
- 6, 41, 41, 41,213,223, 83, 74,209,165, 75, 23,233,217,179,103,195, 26, 42,192, 24,134,193,218,181,107, 97, 52, 26, 1, 0,223,
-255,180, 27,111, 79, 24, 85, 29,201,249,254,167,221,213,235,125,244,209, 71,127,137, 96,213, 70,231,206,157, 81, 86, 86, 86, 29,
- 21,229, 56,238, 47,239, 12,195,160, 89,179,102,168,175, 28,172, 50,193, 38,115, 62,182,141,139,131,139,139, 11,224,228, 4, 57,
- 0,133,201,132,220,220, 92, 56, 85, 25, 44,121,141,247,198,154, 43,189, 94,143,140,140, 12,195,213,171, 87,255,210,209, 32, 32,
- 32, 32, 73,175,215,195,210, 50,155, 16,226, 98, 54, 87,148, 82, 60,251,236,179,152, 57,115, 38,130,131,131, 81, 90, 90,138, 57,
-115,230,160,168,168,104,101,167, 78,157,190,184,126,253,250,135,148,210, 53,245,233,237,222,189,251, 47, 85,252, 29, 58,116, 56,
-209,181,107, 87,191,152,152,152,154,166,203, 61, 56, 56, 56,137, 82, 90,111,239, 66,115,131,246, 78,157, 58, 97,202,148, 41,216,
-181,107, 23,126,254,249,103,240,124,101, 0,108,228,200,145,120,238,185,231,144,155,155, 11, 87, 87, 87,146,158,158,126, 77,173,
- 86,215,219,240, 93,161, 80,132,245,236,217,147, 75, 78, 78, 70,183,110,221, 48,121,242,100,188,241,198, 27,216,191,127, 63,154,
-187, 1,209,251,199,162, 83,191,245,144, 90, 73, 65, 8, 65,207,158, 61,165,225,225,225, 13,230, 79,142,227,222,235,219,183,239,
- 18, 0, 29,107,222, 7, 9, 33,241,132,144, 15, 1, 32, 43, 43, 43,126,216,176, 97, 73,125,251,246,237,210,170, 85, 43,167,216,
-216, 88, 14,128, 81, 44, 30, 69, 68, 30, 57, 26,102,177, 7, 49, 27,164,135,141,214,210,165, 75,135, 62,252, 93, 77, 51, 85,219,
-231,154,255, 93,182,108,217,146, 26,218,229,143, 99,191, 30,219, 56, 88,230,130,179, 33,244,122, 61, 98, 98, 98,208,166, 77, 27,
- 40,149, 74,112, 28,135,192,192, 64,196,196,196,160, 67,135, 14, 16, 4, 1, 31,124,240, 1, 22, 44, 88,128, 29, 59,118, 32, 46,
- 46,142,115,117,117,173, 87,115,221,174, 82,223,154,203, 54, 54, 54,190, 59,118,236,120,164,118, 89,132,144,234,130,122,248,240,
-225, 56,124,248, 48, 36, 18, 73,117, 97,174, 86,171,171,171,251, 44,200, 16, 84,173, 86,195,100, 50,193,218,218,186,186,253,149,
-217,168,200,100, 50, 48, 12, 83,221,216,221, 28,109, 3, 0,123,123,251, 6,245,147,175, 92,129, 68, 34,129,199, 83, 79, 1, 0,
- 74,147,147, 33,145, 72,160,240,240,168,140, 24,150,149,213, 89, 69,248, 48, 60,207,119,240,244,244,196,173, 91,183,170,211,216,
-188,121,115, 76,159, 62, 29,229,229,229,216,176, 97, 3,138,138,138, 32,147,201, 32,145, 72,208,186,117,107,232,245,250, 14, 13,
-233,178, 44,139,169, 83,167,226,167,159,126,194,218,229,149, 85,128, 63,172,168,124,175, 57, 60, 3,195, 48,248,252,243,207,209,
-167, 79, 31,139, 77,229,166, 77,155,170,207,153, 89,195,252,154, 62,125,186, 69,134,133, 82, 42,168,213,106, 80, 74,171,163,139,
-166, 42,231,108,110,127,200,178,108,181, 49, 54, 71,178,154, 98,176,234, 74, 15,165,180,214,170,195,250,130,120,243,230,205,179,
- 22, 4, 1,125,250,244,193,132, 9, 19, 16, 20, 20,132,239,190,251, 14,231,207,159,199,143, 63,254,136, 45, 91,182,192,100, 50,
- 73, 7, 14, 28, 56, 19,192,154,198, 94,215, 44,203,122,174, 91,183,206,110,239,222,189,176,182,182,134,189,189, 61,108,109,109,
- 97,111,111,143,231,159,127,190,161,222,133,131,194,195,195,225,224,224,128,168,168, 40,200,100,149, 81,123,107,107,107,199, 83,
-167, 78,233, 86,175, 94, 93,162, 84, 42, 57,153, 76,134, 79, 62,249, 4, 50,153, 12,111,188,241, 70, 88, 88, 88,152,188,174, 14,
- 30, 70,163,177, 67, 70, 70, 6, 14, 31, 62,140,161, 67,135, 98,210,164, 73, 72, 77, 77,197,184,113, 47, 99,233, 12, 41,252, 3,
- 39, 64,106,223,171, 58,111,180,111,223, 30, 90,173,182,193,252,153,154,154, 26, 13,160,191, 37,231, 80, 68, 68,228, 31,141,118,
- 29,124,216,100, 61,138,214,188,121,243, 62, 0, 64,231,205,155,247,129,121,121,233,210,165, 21, 0, 30,185,141,229, 99, 51, 88,
-150, 68,176,122,245,234,165, 88,189,122, 53,220,220,220, 16, 24, 24, 88, 29, 97, 81,171,213,248,238,187,239, 48, 97,194, 4,252,
-241,199, 31,232,208,161, 3, 6, 13, 26,132,167,159,126, 26,157, 58, 53,220, 59,250,221, 9,158,231, 76,186, 82,123,131, 94, 23,
-185,102,183, 97, 66, 73, 73,201,217,214,173, 91,187,167,164,164,152, 74, 75, 75,171, 27, 13, 19, 66, 16, 28, 28, 12,142,227, 46,
- 95,188,120,241,101, 75, 10,239,209,163, 71, 99,239,222,189, 24, 57,114, 36,142, 29, 59, 6, 0, 8, 14, 14,198,205,155, 55,161,
- 82,169, 44,142, 16, 17, 66,192,243, 60,148, 74,101,117,117,163,217,192,152, 49, 71, 69,204,133,184, 37,213,163, 64,195,109,174,
-204,209,156, 70,100, 58, 72,165, 82, 48, 12, 83, 93,149, 83, 86, 86,134,226,226,226,234,180,155, 95,150, 86, 13,179, 44,139,239,
-190,251, 14, 70,163, 17,211,230, 44, 4,203,114,152,246,234,115, 96,217, 74,131,186,118,211, 62,240, 60,143,237, 63,175,194,188,
-121,243, 44,222,119,142,227, 48,105,210,164,234,125,172, 45,138,213,216,130,209,213,219, 27, 20,128,188,234, 63, 70, 66,208,172,
- 50, 4,249, 72, 17, 44,243, 3, 70, 83, 13, 88, 45,236,127,255,253,247, 39, 26, 12,134,246, 33, 33, 33,202,201,147, 39, 35, 53,
- 53, 21, 43, 86,172,208, 22, 22, 22,174,233,223,191,255, 68,107,107,107, 59,141, 70,163,185,127,255,254,215, 77,185,174, 5, 65,
- 72,159, 50,101,138,149,121,140, 44,115,207, 66,150,101, 45,234, 93,200,243, 60,214,175, 95, 95, 93, 53, 88, 91,190,168,153,167,
- 44,161, 99,199,142,176,178,178, 2,165, 20, 70,163, 17, 95,124,241, 5, 94,120,126, 32, 14,159,163,232, 63,254,125, 8,148, 64,
- 34,145,224,167,159,126,130,175,175,111,131,122,117,140,129, 37,142,127, 37, 34,242,239,140,118, 13,125,156, 90,230, 8,214,210,
-165, 75,111, 44, 93,186,244, 47,209,176,191,213, 96,177, 44, 91, 29,210,175,171, 48,182,180, 13,214,185,115,231,180, 39, 78,156,
-176, 78, 75, 75,171,142, 16,113, 28,135, 86,173, 90,129, 16,130, 63,254,248, 3,155, 55,111,198,135, 31,126, 8,142,227, 96,107,
-107,139, 46, 93,186, 24, 51, 51,235,239, 17,221,253,233, 23, 91, 85,181,193,226, 1,192,205,205,205,115,199,142, 29,245,181,193,
-234,108, 73, 65, 40,145, 72,112,240,224, 65, 12, 24, 48,160,186, 49, 53, 0,196,197,197, 33, 32, 32, 0,183,111,223,110, 84, 21,
- 28,165,244, 1, 99,101,238,173, 86,211, 96,177, 44, 91,221,200,214, 82,106, 70,174, 56,142,131,178, 70,228,138,101, 89,232,148,
- 74,232, 0,216, 91, 80,112, 75,165,210,248,172,172,172, 32, 23, 23, 23, 20, 20, 20, 64, 38,147, 61, 96,206, 56,142,123, 32,250,
- 86,213, 78, 43,190, 33, 93,115, 52,233,247,223,127, 7, 0, 76,123,245, 57,168, 84, 74,232,245,122,104,181, 90, 76,123,117, 4,
-214,110,218, 7,134, 97,176,116,233, 82, 12, 24, 48,192, 98,115,185,113,227, 70,152, 11,127,243,203,156, 47,103,205,154,101,110,
- 55,212,232,139, 35, 43, 43, 11, 64,101,171,201,135,207,145,217, 4, 63,238, 8,150, 37, 6,139, 16, 50,165, 67,135, 14,115, 20,
- 10, 69,106,118,118,246,118, 55, 55,183,233,223,124,243,141,119,114,114, 50,108,109,109,113,228,200, 17,197,140, 25, 51,222,188,
-124,249,242, 88, 74,105,120, 67,233,242,247,247, 63, 17, 26, 26,234, 87,115,152,134,170,235, 62, 51, 46, 46,238, 81, 6, 24, 61,
- 62,104,208,160,103,109,109,109, 49, 97,194, 4, 72,165, 82,140, 26, 53, 10,118,118,118, 5,235,215,175, 71, 80, 80, 80,181,137,
- 95,176, 96, 1,146,147,147, 65, 8, 57, 94,223,240, 36, 50,153, 44, 62, 57, 57, 57, 72,165, 82,193, 96, 48, 84, 95,127, 7,255,
- 56, 3,142,147, 84,155, 43,169, 84,138,233,211,167,155, 59, 59,196, 55,112, 60,151,110,216,176,161,131,139,139, 11, 50, 50, 50,
- 80, 80, 80,128,210,210, 82,191,213,171, 87, 47, 7, 72, 32, 22,130, 96, 1,168,151,151,103,171, 41, 83,166,120,153, 76, 38, 33,
- 41, 41,169, 0,226, 4,227, 34, 34,255, 72, 4,171,166,209,170, 17,133,170,139,220,154,237,178,234, 50,104, 53,219,100,193,194,
-177, 40, 45, 54, 88, 15,215,125, 82, 74, 19,175, 94,189,218,250,169,167,158, 66, 74, 74, 10,138,138,138,106, 21,176,178,178,130,
- 82,169,196,157, 59,119, 64, 41, 77,108,168,128, 97, 24,166,250,166, 88,179,199,224, 7, 31,124,128,121,243,230,161,127,255,254,
-232,209,163, 71,163,118,226,232,254, 31, 74,206,133, 11, 26, 94,160, 25, 0,144,157,157, 45, 44, 94,188, 88,115,236,216, 49,125,
-205,134,242,230,234, 60,158,231,179, 26, 56,129,166,146,146, 18, 78, 38,147,129, 16,130,243,231,207, 87, 15, 35, 17, 23, 23, 7,
-137, 68,130,164,164, 36, 72,165, 82, 24, 12, 6,160,178, 77,180, 69, 55, 91,115, 4,171, 54, 99,166, 82,169, 64, 8,121,192, 96,
- 89, 82, 69, 88,211,252,212,212,109,108,228, 10, 0, 12, 6,195,169,136,136,136,128,126,253,250,113, 26,141,166, 86,131,101, 54,
- 87,114,185, 28,151, 46, 93,210, 87, 84, 84, 52,248,148,207,178, 44, 86,174, 92, 9,131,193, 80, 61, 76,131,185, 58,204, 60, 22,
-214,180, 87, 71, 96,207,230,213,120,239,189,247, 44,170,122, 53,167,103,218,180,105,181, 70,174,204,159, 31, 30, 98,164,161,116,
-234,203,202, 32,149, 74,225,106, 62,150,130,240,192, 57,170, 25,109,180, 4, 55, 55, 55, 39,103,103,231,111, 28, 28, 28, 20, 90,
-173,246, 47, 6,170,230,239,245, 69,184,204,248,250,250,190,127,245,234, 85,215,194,194, 66,143,131, 7, 15,118,117,113,113,129,
- 92, 46,199,115,207, 61, 87, 46, 8, 2,243,205, 55,223, 40,126,248,225, 7,197,220,185,115,215, 0,104,101,129,249,245,252,225,
-135, 31,236,206,156, 57,131,154, 67, 20,140, 29, 59,246,145, 6, 24,141,142,142,126,161,107,215,174, 62, 60,207,199,118,238,220,
-153, 75, 78, 78,198,208,161, 67,161, 84, 42,171,207,139, 70,163, 49,183, 75,163, 28,199, 5, 52, 52, 67,132, 86,171, 61,117,246,
-236,217,206, 47,189,244,146,164,184,184,184,250, 30, 66, 72,165,177, 54, 95, 91,230,247, 83,167, 78,233, 53, 26, 77, 67,249,179,
-157,151,151, 23, 22, 44, 88,128,102,205,154,193,197,197, 5,190,190,190,112,119,119,111, 61,110, 92, 96,166, 70, 83,161,167,195,
- 76, 23,167, 77,235,234,209,187,119,216, 83,183,110,221,186,159,147,147, 19, 41, 54,112, 23, 17,121,172,145,169,134,170, 45,114,
- 31, 50, 71,250, 26,203,185,168,156, 91,121,104,213,103,212,248, 28, 9, 32,248,161,117,205,191,235, 31,122, 55,255,126,245,111,
-141, 96,177, 44, 59,114,210,164, 73,223,246,239,223, 63,108,206,156, 57,176,182,182, 70,102,102,102,117,164, 74, 38,147,193,219,
-219, 27, 21, 21, 21, 56,115,230, 12,138,138,138, 78,179, 44, 59,189,161, 13, 26,141,198,234, 6,227, 53,123, 12,250,250,250, 98,
-223,190,125,127, 49, 4, 66,141,194,173, 46,214,237,209,248,213, 92,142,137,137,241, 1,128, 69,139, 22, 53,233,160, 72, 36,146,
- 3, 59,119,238,124,126,224,192,129,140, 57,130,103, 78, 71,205,161, 36,116, 58, 29,126,253,245, 87,170, 80, 40, 78,212,214,131,
-240,161,200,144,177,119,239,222, 18,153, 76,134, 62,125,250, 84,119,125,175, 25, 93,115,112,112,168, 54, 88,150,154, 2,163,209,
-136,146,164,164, 7,122,117,178, 37, 37, 15, 44,219, 89,112, 12,107,152,203,149,107,215,174,125, 35, 48, 48,208,193,221,221, 29,
-229,229,229, 32,132,192,217,217,185,186,157,148, 66,161,128, 84, 42, 69,124,124, 60,194,195,195,203, 41,165, 43, 45,137, 96,205,
-156, 57, 19,123,247,238,125,192, 60,153,205,149,217,172, 80, 74,241,213, 87, 95,225,217,103,159,173, 55,114,106,142,158,114, 28,
-135,245,235,215, 63, 16,193, 50, 27, 37,134, 97,240,254,251,239, 91,108, 50, 57,142, 67,239,222,189,193,113, 28,194,194,194,170,
- 59, 27,212,124, 53,107,214,236,129, 72, 86, 67,120,122,122,118, 10, 13, 13, 61,184,110,221, 58, 71, 39, 39, 39,100,100,100, 60,
-144,167, 61, 61, 61, 59,133,132,132, 28, 92,183,110,157,163,179,179, 51, 82, 82, 82, 26,220,239,123,247,238,173, 29, 54,108,216,
-167, 35, 70,140, 32,253,250,245,131, 82,169,196, 71, 31,125,132,155, 55,111,190, 13, 32,118,255,254,253, 87, 38, 79,158,140, 22,
- 45, 90,184, 89,120, 99,171, 30,104,180,102, 84,154,231,249,156, 71,189,193,152, 76,166,101,223,126,251, 45,167, 82,169, 80, 81,
- 81,129,220,220,220, 7,170, 4,203,203,203,225,230,230,134,183,223,126,155,172, 90,181,234, 43, 52, 48, 14,150, 84, 42, 93,185,
-113,227,198, 55,122,245,234,229,224,234,234, 10, 65, 16, 30, 48, 84, 53, 63, 95,189,122, 21,251,246,237, 43,231, 56,174,161,252,
- 73,220,221,221,133, 15, 63,252,144,177,177,177,169, 30,146,102,247,238, 93,204, 87, 95, 45,183,249,246,155,111,240,252,243,163,
-134,155, 76, 38,225,214,237, 59,247,215,172, 89,115, 73, 16,132,211, 98,145, 40, 34,242, 31, 37,242, 31,250,239,227, 55, 88,145,
-145,145,247, 1, 60, 27, 24, 24,248,194,153, 51,103,190,152, 61,123,182, 83,207,158, 61, 81, 80, 80, 0, 31, 31, 31,184,187,187,
- 35, 42, 42, 10, 87,175, 94,205,167,148,206,139,138,138,218, 86, 75, 1,248,151,217,182, 43, 42, 42,176, 97,195, 6,204, 56,120,
- 16,203,159,122, 10, 5,245, 68, 1, 86,173, 90,101,142, 16,213,171,249,112, 27,172, 46, 93,186, 92,108,222,188,185,123, 74, 74,
-138,169,102, 4,203,252,249,225, 54, 88, 15,107,234,116,186, 15,182,111,223, 46,249,237,183,223,158, 21, 4, 65, 82,143, 9, 53,
- 41, 20,138,112,189, 94,255, 94, 67,251,126,225,194, 5, 59, 0, 8, 14, 14, 46,159, 52,105, 18, 28, 28, 28,234,140,100,153, 27,
- 79, 63,220, 14,169,182,125,215,235,245, 88,185,108, 25,150, 95,184,128,183,186,117,171,215, 60,172, 94,189, 26, 13,165, 51, 34,
- 34,162,180, 75,151, 46,147,223,123,239,189, 95, 23, 45, 90,164,116,118,118,134,201,100,194,119,223,125, 7, 65, 16, 32, 8, 66,
-181,185,154, 51,103, 78,121,121,121,249,228, 43, 87,174,148, 54,148, 78,150,101,241,213, 87, 95,193,100, 50, 85, 15,211, 96, 30,
-104, 84,161, 80, 64,171,213,226,167,223,255, 0,195, 48,152, 51,103,206, 95,170,166,107,211, 52, 26,141,144, 72, 36,152, 49, 99,
- 70,173,189, 8, 37, 18, 9, 24,134,169,211, 96,213,178,239, 42, 0, 80,171,213,229,115,230,204,169, 30, 7,169,174,104,163, 37,
-154,205,154, 53,155,185, 97,195, 6,199,138,138, 10,196,199,199, 35, 62, 62, 30, 12,195, 36, 60,252,187, 70,163,193,245,235,215,
-113,243,230, 77, 16, 66, 18,234,211,164,148,126, 77, 8,217,114,244,232,209, 17,114,185,124,164,139,139,139, 87, 74, 74,202,239,
-148,210, 29, 0, 48,109,218, 52, 24,141,198,134,170,246,171, 53, 99, 99, 99,235, 28, 32,184,102,245,161, 57, 79, 82, 74, 51, 99,
- 98, 98,186, 91,114,189, 3,208,239,223,191, 31,214,214,214,216,187,119,175,201,193,193,129, 91,184,112, 33,100, 50, 25, 62,253,
-244, 83,164,164,164,152,222,120,227, 13, 78, 16, 4, 80, 74,245, 13,105, 38, 38, 38,150,122,121,121, 77,158, 62,125,250,166, 85,
-171, 86,169,204,205, 11,126,254,249,103, 76,153, 50,229, 1,115, 53, 97,194,132,114,157, 78, 55, 57, 45, 45,173,161,252, 73,121,
-158,167, 53,171,190,171,218, 29,210,249,243,230,149,149,105,202,116, 95,126,241, 69,100,114,106, 74, 97,122,122,102,180, 32, 8,
- 39,178,178,178, 82, 44,216,247, 71,173, 10, 17, 53, 69,205,255, 41,205, 39,141, 6, 31,237, 99, 98, 98,182, 7, 4, 4, 28, 91,
-182,108,217,226, 61,123,246,188, 62, 99,198, 12, 98,107,107,139, 29, 59,118,208,194,194,194,223, 20, 10,197, 7,231,206,157, 43,
-178, 48, 66,112,235,248,241,227,157,103,207,158, 45, 97,223,123, 15, 31, 63, 52,201,239,195,196,199,199, 83,141, 70,195,107,181,
- 90, 77,125,186,143,187, 13, 86,116,116,116, 22,128,113,127,199, 1,151,201,100,198,145, 35, 71, 74,228,114, 57, 6, 12, 24, 80,
- 61, 76,131,121, 96, 67,153, 76, 6,123,123,251,234, 72, 76,125, 85,132, 10,133, 34,249,252,249,243, 94,139,191,252,146,213, 49,
- 12, 86, 85, 29, 79,243, 49,125,152,243,231,207, 83,153, 76, 86,220, 80, 26,175, 92,185,114, 68,173, 86,191, 60,125,250,244,159,
-134, 13, 27,166, 10, 10, 10,146,250,248,248,128,227, 56,164,164,164,224,236,217,179,250, 35, 71,142, 84,232,116,186, 9, 87,174,
- 92, 9,183,100,191, 25,134,193,187,239,190, 11,134, 97,224,215,170, 57,142,157,137,124,160,199,220,254, 99,231,224,230,210, 12,
- 79, 61,245, 20,190,248,226, 11, 60,247,220,115, 22, 69,239,220,220,220, 80, 85, 56,195,220,126,200,108,232,154, 82, 69,104, 54,
-163, 3, 7, 14,180, 40,146,101, 65, 4,167,125, 97, 97, 33, 52, 26, 13,162,162,162,232,234,213,171,243,138,139,139, 23,212,252,
-189,170,205, 15, 46, 95,190, 76,127,252,241,199,188,210,210,210, 5, 22, 68,157,178, 0,172,173,122, 61, 64,118,118,118,185,193,
- 96, 80,101,102,102, 62,242, 16, 2,230,234,195, 75,151, 46, 85,247,174,108, 76,213, 33,165,116,206,177, 99,199,164,168,154, 42,
- 39, 55, 55,247,178, 68, 34,145,201,100, 50,164,167,167, 67, 16,132,144,245,235,215, 47, 5, 96,224, 56,110,134, 37,154,105,105,
-105, 71, 60, 60, 60,198, 77,152, 48,225,167,145, 35, 71, 42,123,247,238, 45,243,243,243, 67, 89, 89, 25,174, 94,189,138,240,240,
-112,253,222,189,123, 43, 42, 42, 42, 38,100,100,100, 88,146, 63, 19,116, 58, 93, 39, 71, 71, 71, 72, 36,146,234,104,106, 90, 90,
-250,237, 83,167,206,168,177, 16,100, 33,128,237, 59,169, 32, 22, 25, 34, 34, 34, 22,155,208,198, 52, 35, 8, 13, 13, 13, 21, 4,
- 97, 23,207,243, 18, 66,200,168,232,232,232,243,141,113,184,161,161,161, 54, 82,169,244,120, 69, 69, 69, 71, 11,205, 72,145,209,
-104,124, 54, 50, 50,242, 90,125,174,121,202, 72,171, 91, 42,133,192,150,107,141,137,235,246, 24, 7, 7, 6, 6, 38, 15, 25, 50,
- 68, 81, 87, 27, 44,131,193,112, 39, 42, 42,170,239, 63,233,238,213,106,117,249,174, 93,187,208,172, 89,179, 58,163, 36, 33, 33,
- 33, 8, 8, 8,112, 95,183,110, 93, 73, 29,199,211, 69, 34,145,156,212,106,181, 62,150,164, 73, 46,151,103,234,116,186,129,209,
-209,209,247, 44, 73,103,207,158, 61,237, 77, 38,211, 59,114,185,188,143, 78,167,107, 15, 0, 74,165, 50,190,162,162,226, 36,199,
-113,223,212,101,172,107,211,236,220,185,179,134,101, 89, 82,115, 72,134,218,222,107, 14,215, 80, 86, 86,230, 98,158,228,251, 97,
-205,238,221,187,223,210,235,245, 94,141, 48,182,249, 82,169,212,183,102, 85,174, 37,231,232,232,209,163,245, 70,178,130,130,130,
- 16, 29, 29,173,170, 75,211,199,199, 39,192,202,202,106, 61, 42, 71, 22,190, 91, 92, 92, 60, 35, 61, 61, 61,189,230,239, 74,165,
-114, 61, 0, 25,195, 48,127,249,189, 41,249,147, 16, 50,185, 93,187,118,239, 37, 36, 36,172,172,107,236, 43, 75, 53, 59,117,234,
-116, 34, 36, 36,196,239,202,149, 43, 6,243, 53, 84,215,248, 87,150,104,170,213,234,237, 0,158,173, 90,255,120, 84, 84,212,136,
-166, 94, 71,205,155, 55,183, 7,240,142,149,149, 85,159,138,138,138,246, 85,145,197,248,242,242,242,147,130, 32,124,147,146,146,
- 98, 81,254,124, 28,189, 8,197, 72,134,168, 41,106,138, 60,146,193, 18, 51,202,227,211, 12, 10, 10, 42,166,148, 74, 26, 48, 68,
- 66,235,214,173,157,204,147, 20,255,147,251,110, 30,169,213,146,134,189, 79,202, 57, 10, 13, 13, 45,111,168,119,172, 68, 34,193,
-165, 75,151, 84, 98,158, 23,243,167,168, 41,106,138,154, 34, 53,225,196, 67,240,207, 16, 21, 21,101,247,223,148,222,255,197, 30,
- 83,230, 54, 89, 34, 98,254, 20, 17, 17, 17,105, 44,140,120, 8, 68, 68, 68, 68, 68, 68, 68, 68, 30, 47, 4,128,127, 29, 79,132,
-141,105,243,225,223,132, 39,206,235,162,166,168, 41,106,138,154,162,166,168, 41,106,254,111,105, 54,164,253,164, 84, 61,138,109,
-176, 68, 77, 81, 83,212, 20, 53, 69, 77, 81, 83,212,252,199, 53,159, 52,196, 42, 66, 17, 17, 17, 17, 17, 17, 17,145,199,140,216,
-200,189, 9,120,120,120, 40, 1, 12,229, 56,110,156,131,131, 67, 80,126,126,254,231,105,105,105,223, 61,161,251,218,150, 82, 58,
-142, 97,152, 23, 0, 64, 16,132, 29,132,144,223, 50, 50, 50,110,139, 57, 65, 68, 68, 68, 68, 68,228, 17, 12, 22, 33,132,237,208,
-161,245, 43, 44, 33, 61, 0,216, 3, 40,226, 41, 61,127,243,102,226,111,148,210, 38,205, 87, 22, 22, 22,198, 85,104, 52, 99, 57,
-150, 29, 76, 41,245, 7,165, 4,132, 92, 55,153, 76, 71, 84, 54, 54,155, 27,154,122, 6, 0,198,140, 25,195,166,165,165,221,226,
-121,222,185, 81, 59,205,113, 89, 23, 47, 94,244,107, 74,186,189,188,188, 70,121,122,122,174,237,218,181,171,170, 75,151, 46,144,
- 74,165,248,242,203, 47,103, 0,176,216, 96,145,176, 48,206,181,176,217, 88, 70,194, 13, 1,168, 63,165, 0, 37,220,117, 24, 12,
- 71,178, 29,243, 54, 83, 11,246, 29, 0, 2, 3, 3,223, 35,132,140,171,234, 65,245, 75, 76, 76,204,170, 71,201, 12,159, 76, 98,
-179, 41, 21,172, 5, 74, 80,166,149, 24,118,157,118,188,209,165, 75,151,192,247,222,123, 15, 93,187,118,133, 32, 8, 56,115,230,
-204,172,149, 43, 87,206,114,119,119,143, 98, 89,118,179, 84, 42,221,121,239,222,189,146,198,108, 39, 52, 52,212,159, 82, 58, 7,
- 64,144, 32, 8, 30, 28,199,101, 16, 66,162,140, 70,227,170,168,168,168, 70,207, 1, 69, 8, 33, 33, 33, 1, 35,109,109,201, 96,
-134, 32,128,130, 18, 2,114,173,160, 16, 71,162,162,174,236,162,180,233, 3, 68, 6, 5, 5,237,166,148, 14,172,218,206,209,168,
-168,168, 81,143,251, 34, 92,243, 6,121,151,161, 8, 2, 0,129, 32,234,205, 13,244,235, 71,209,179,118,235,208,193,202,218,118,
-182,201,100, 24, 40,145,200,255, 44, 45, 46, 89,174,201,185,241,143,134,242,187,117,235,166, 48,153, 76,147, 89,160, 47,165,244,
-169,170,227,121,131, 7,254,228, 56,110,253,197,139, 23,181,226,237, 88, 68, 68,228,127,202, 96, 17, 66, 88,255,142,109,151, 79,
-158, 50,181,253,200,145, 35,221,149, 42, 27, 69, 74, 74, 98,198,250, 31,214,216,177,132,233, 76, 8,153,211, 88,147, 21, 26, 26,
-218,158, 8,194,214,105, 19, 38,180, 8,234,222,157,115,117,119,135,182,184, 24,137, 9, 9,222,145,151, 47,247,219,119,252,248,
- 44,181, 90, 61, 46, 58, 58,250, 70,125, 58,121,121,121, 18,142,231, 93, 78, 46, 89,194, 50, 14, 14,160, 38, 19,180,173, 91, 87,
-142,234,205,243,144, 71, 68, 0, 70, 35, 40,207,163,226,233,167, 1, 0, 38,147, 9,195,134, 13,243,106,202,193,242,246,246,118,
-111,211,166,205,134,249,243,231, 75,117, 58, 29,174, 92,185,130, 11, 23, 46, 8,185,185,185,203, 45,213,112,235, 50,162,189, 27,
-220,182,140, 24, 57,164,249,179,253,157,101, 62,110,206, 16, 4, 57, 18,238, 25,189,195,207,198,244, 63,252,199,177,153,174,254,
- 35, 94,201,190,190,175,222,125, 15, 9, 9, 25,192, 48,204,167, 81, 81, 81, 0, 0,181, 90,253,185, 90,173,254,188,161,237, 91,
- 89, 89,229,104, 52,154,137,209,209,209,181, 12,160, 40,168, 22,206,152, 10,129, 2, 63, 30, 74,144,198,175,217, 23,104,107,107,
-251,192,148, 61, 3, 6, 12, 64,255,254,253,145,146,146, 18,180,103,207,158,160, 13, 27, 54,124,233,229,229,245,105, 90, 90,218,
-183,150,152,234,178,178,178, 79, 28, 29, 29,223,156, 62,125,186,162, 85,171, 86, 80,169, 84,200,202,202,106,158,144,144,224,189,
-121,243,230, 33,221,187,119,255, 65, 42,149,126,122,202, 66,147, 25, 28, 28,220,114, 64,255, 46,155,159, 27, 25,214,206,205,173,
-163, 84, 34,113, 2,165, 20, 70, 99, 65,155,220,220,155,207, 57, 56,224,221,208,208,208,151, 27,154, 68,184, 70,222,116, 49,153,
- 76,223, 2,144, 50, 12, 51,135, 82, 58,240,200,145, 35,224,121, 30,207, 62,251,236,192,224,224,224,150,130, 32, 44,183,178,178,
-162, 58,157,110, 90, 68, 68,196, 35,207,215,199, 49,108,240,228,121,139,134, 64,208,227,135,165,139, 30, 73,203,198,195,175,109,
-219, 54,109, 79,175, 91,189, 82,225,219,194,155, 68, 94,137, 31, 53,125,214,187,131,172, 92,158,234,219, 88,147, 21, 20, 20, 20,
- 32,151,203, 63, 47, 42, 42, 26, 19, 23, 23,167,233, 52,109,175, 51,103, 84,218, 72,148,130, 46,226,219, 65,233,150,234, 4, 7,
- 7, 7,113,132,108,249,250,253,137,110,237, 58,117,102, 20,206, 78, 32,201, 57, 40,228, 43,250, 92,184,126,179,215,170, 53,155,
-223, 10, 14, 14,126, 57, 50, 50, 50, 74,188, 37,139,136,136,252,207, 24,172, 14, 29, 90,191, 50,113,210,164,246, 83,167,189,173,
- 54, 24,116,229,215,162, 79,159,224,164, 12,251,246,244, 73,118, 5,133,185, 78,148, 10,175, 0,248,165, 17,230,170,181,167,171,
-107,248,178, 47,190,176,119,116,118, 70, 86, 86, 22, 82,211,210,144,121,253, 58, 8,128,254,253,251,203, 2, 58,119,110,181,114,
-221,186, 35,193,193,193, 3, 34, 35, 35,111,214,167,199,114, 28,136,149, 21,210, 3, 3, 65, 37, 18,164, 29, 59, 86,249,189,201,
- 4,143, 97,195, 0, 0, 84, 34, 65,209,133, 11, 96, 89, 22,222,222,222, 77, 62, 88,148,210,208,158, 61,123, 74, 1,224,221,119,
-223, 45,213,104, 52, 95, 17, 66,182,167,167,167,103, 88,242,127,231,128,231, 91,187, 56,185, 28,251,122,241,100, 7,127,223, 86,
-208, 27,141, 72,203, 73, 7,133, 28,110, 46,214, 24,247, 92,128,180, 71,144,164,245,242,239,255, 60,234,214,121, 88,255,172,107,
- 7,234,220,119,150,101,151,207,155, 55, 15,219,183,111, 7, 0,108,217,178, 5,109,219,182,109, 48, 13, 23, 46, 92,112,121,255,
-253,247,215, 2,168, 53,130, 39,208,202,169, 98, 90,181,106, 13, 59, 59,187,186, 76, 55,124,124,124, 48,107,214, 44, 4, 6, 6,
-202, 94,121,229,149,197, 0, 26, 52, 88, 26,141,230,211,174, 93,187,190,185,120,241, 98, 89, 68, 68, 4, 78,159, 62,141,195,135,
- 15,195,195,195, 3,190,190,190,100,201,146, 37,138, 85,171, 86, 77, 73, 74, 74, 98, 0,124,208,144,158, 90,173,246,238,208,161,
-217,201,229, 95,127,226,116,224,224, 13,124,253,245, 79, 72, 76,172,244, 81,173, 90,181,194,203, 99,199, 72, 54,255,182,174,195,
-220,185, 11, 78,132,132,132,244,189,124,249,242,157,134, 52, 77, 38,211,183, 75,151, 46,125,214,218,218, 26,243,230,205,187,234,
-235,235, 11, 91, 91, 91,172, 91,183, 14, 14, 14, 14, 48,153, 76, 87,191,248,226, 11, 46, 35, 35, 3,223,124,243,205, 90, 0, 35,
- 31, 75,180,138,106,129,146,207, 44,141,216,177,117, 61,212, 40, 20,214, 31,126,179,124,153,210,193,217, 27, 9,153, 60,138,136,
- 27,233, 53,124,138,114,199,143, 95,206, 1,240,106, 35,174,211, 64,153, 76,246,135,193, 96, 80, 90, 89, 89,169, 0,104, 56,163,
-210, 70,144,114,163, 13, 84,184,217,233,189,112, 67,236, 87,253,115, 45, 49, 87,237, 91, 55, 63,244,205,231, 31, 90,177,185,183,
-161, 33, 87, 80,152,109, 0,150, 31, 0, 99,235,140, 62,239,190,205,117,238, 18,224, 49,239,195,165,135, 66, 66, 66,134, 92,190,
-124, 57, 90,188, 45,139,136,136, 60, 9, 52,216,200,157, 37,164,199,115,207,141,116,214,235, 43, 52, 90,173,166,232,126,114, 84,
-230,137, 19, 27,174,223,186,121,246,246,128,129,221, 12, 12, 75,122,212, 99, 72, 30,120, 98, 30, 51,102, 12,203,240,252,239, 95,
-124,245,149, 61, 43,149,194,104, 52,194,199,199, 7, 90,173, 22, 37,133,133,200, 74, 73,193,249,131, 7,161,201,203,195,244,113,
-227,236, 37,132,108, 81,171,213,146,250, 52, 65, 41,240,208,104,219, 15,207, 63, 71, 8,169,119, 78, 58, 75,123, 66, 8,130,144,
-148,145,145, 1,149, 74,133,246,237,219, 91, 17, 66, 46,164,165,165,101, 88,162, 73,198,140, 97, 37, 18,118,231, 87,139,199, 58,
- 16,246, 22,110,165, 68,129, 99,229,104,102,231, 13,189, 1, 56, 23,125, 24, 63,237,252, 24,105,233, 17,152, 60,174,141,157, 82,
- 73,119, 17,245,148, 58,247,221, 96, 48,180,104,221,186, 53,252,253,253,209,169, 83, 39,240, 60,143, 27, 55,110, 32, 54, 54, 22,
- 87,174, 92, 65,116,116, 52, 34, 35, 35,113,233,210, 37, 92,184,112, 1, 99,166,175,192,212,233,239,161,172,172, 12, 53,167,152,
-121, 48,157, 76,249,196,143,127,253, 63,246,206, 59, 58,138,234,111,227,207,157,217,190,217,108, 26, 33,201, 38, 33, 16,122, 47,
- 73, 0, 17, 5,149, 14,130, 40,160,136,138,130, 74, 17, 65, 16, 41,190, 10,130, 18, 16, 65, 65,133, 32,162,128, 40,210, 4, 5,
- 69, 64,138, 34, 36,164, 24, 58, 1, 2, 33,101,211,123,178,217, 54, 51,247,253, 35,229, 23, 16,146,221, 0, 18,241,126,206,217,
-179, 59,187,179,207,220,185, 51,115,231,153,239,109, 56,112,206,134,156,124, 51,182,110,221,138,188,188, 60,124,255,105, 79, 68,
-204,243, 67,196, 60, 63,124,179,188, 11,242,243,115, 17, 25, 25,137,165, 75,151,162,180,180, 20,162, 40,202,106,203,207,208,208,
-208, 78,122,189,126,226,252,249,243,149,155, 54,109, 66, 76, 76, 12,236,118, 59, 26, 52,104,128,147, 39, 79, 98,203,150, 45, 8,
- 9, 9,193,236,217,179, 53, 10,133, 98,124,104,104,104, 88,141,249, 73, 8,241,242,148, 54,127,252,241, 59, 13,120,238, 44, 60,
-221,150,224,196,137, 63,145,153,153,137,204,204, 76, 68, 69, 29,131,135,251, 90,200,100,231,176,124,249,124, 79,119,119,225, 59,
- 66, 8,231,192,113, 87,156, 63,127, 30,101,101,101,216,188,121,179, 44, 60, 60, 28, 81, 81, 81,208,104, 52, 24, 59,118, 44, 86,
-174, 92, 41,243,244,244,196,213,171, 87, 81, 82, 82, 66,156, 61,151, 56,138,208, 9,115, 23, 14,158, 48,119,193, 96,142, 34,116,
-213,120,242,166, 40,137, 33,171,195,223,199,234,213,200,146, 8, 98,106,211,156, 63,127,190,111,251,246,237,155, 16, 66, 52, 55,
-113,200, 3,131,155, 4, 33,179, 64,196,174,227,233, 88,177,243, 10,120,183, 38,132, 74,182,199,106,210,236,213,171,215,164,238,
-221,187,231,135,133,133, 21, 63,244,208, 67,155,120,158,255,229,131, 15, 62,208,170,213,106,171,224, 17,228, 18,242,234,111,129,
- 10,185, 82,160,132,179, 80, 17, 11,228,197, 10,143,102,175,239, 85,214,164,249,192, 3, 15,168,229, 28,247,237,202,240,255,115,
-177,199,236, 0,252,252,209, 48,248, 21,232, 60,186,131, 22,148, 65,136, 63,143,226,143, 62,131, 76, 45,225,255,222,158,229, 66,
- 36,233,155,102,205,154, 41,235,114,109, 58,249,160,196, 52,153, 38,211,172,135,154,255,185, 8, 22,225,224,174,213,106, 20,199,
-255,220,185,215,152,122, 54, 39, 61,243,116, 33, 7,202, 25,141, 49,133,193,205, 31,241, 66,121,155, 44,135,184,114,229,202, 51,
-111, 76,152, 16,236, 86, 30, 9, 64,131, 6, 13,144,154,154, 10,179,217, 12, 83, 81, 17,202, 74, 74, 96, 41, 42,194,185,131, 7,
-209, 99,224, 64,244,239,220, 57,112,119, 92,220,139, 0,190,184,149,166,157,227, 96,110,211, 6, 41,135, 14,129,179,219, 17,248,
-200, 35, 85, 81,171,220,168,168,114, 99, 37, 8,208,247,237, 11,162,213, 66, 54,127,126,157, 51,203,104, 52,198, 7, 5, 5,237,
- 27, 48, 96, 64,191, 87, 94,121,133,203,200,200,216,229,235,235,251,104, 70, 70,198,249,218,254,235,115, 81, 26,243,194, 43,157,
-155, 52,112, 35,248,233,216,175,232,222,122, 56,180, 42, 25,178,243, 77,224, 8,193,229,171, 7, 32,138, 46,136, 63,159,140, 30,
-237, 93,208,179,155,222,191,244,183,252,151, 0,172,185,149,166,217,108, 70, 86, 86, 22,236,118, 59, 4, 65,192,136,145, 35,177,
- 97,253,122,148,150,150,194,108, 54,195,106,181, 66,146,202,155, 31,101,100,153, 17, 21,247, 11, 66, 58,220, 58,202,181, 96,173,
-232, 99, 48, 24, 76, 27,126, 90,131,253,251,203,231,200,221,181,107, 23,204,153,137,152,252, 76,121,211,163,143, 55,108,198,199,
-203,151,193,102,151, 42,141,158, 99, 78,158,227,166, 77,154, 52, 73, 21, 27, 27,139,130,130, 2,184,185,185, 65,175,215,195, 96,
- 48,224,252,249,255,101,159,191,191, 63, 38, 78,156,168, 89,181,106,213,100, 0,209,183,210,235,218,181,211,240,215, 94, 27,210,
- 74,163,214, 32, 53,249, 19,180,110,173,192,140, 55,188, 16,190, 36, 7, 0,240,250,107, 1, 8, 13,245, 66, 81,193, 54, 52,104,
- 56, 23,111,206, 24, 30, 92, 82,130,209, 0, 54,213,146,206, 25,155, 54,109,138,239,215,175,159, 44, 46, 46, 14, 42,149,170,106,
-162,112,141, 70,131,140,140, 12, 88,173, 86,108,217,178, 69,224, 56,110, 70,109,251,109, 48, 24,222, 4,202, 35, 86, 0, 98,222,
-233, 15,128,218,129,162,242,170,192,138,234,193,134, 21,213,131, 49, 19,215,213,222,254,170, 81,163, 70,194,202,149, 43,221, 62,
-249,228,147, 94, 30, 30, 30, 41,249,249,249,103, 43, 76,103,128,127,211,142,153, 71,142,199, 5,153,213, 77,201,239,167,179,224,
-227,174,196,201,232,227, 18,199,201,126,173, 73, 83, 20,197, 89, 27, 55,110, 84, 54,104,208, 0, 83,166, 76,233, 59,110,220, 56,
- 77, 72, 72, 8,161,148,130, 42,155,187,137, 50,218, 75,128,112,130,183,138,187,161,224,251,137, 50,219, 24,119,145, 95, 3, 32,
-181,134,104,224, 43, 75,223,127,221,135,106,178,160,120,116, 32,184,108,130,180, 9, 67, 33, 21,155, 97,251, 96, 50, 36,170,128,
-197, 42,131,237,137,201, 80, 4,183,196,107, 93,194,252, 86,196, 69,191, 12,224, 51, 86, 52, 51, 24,140, 27, 8, 3, 80,217,222,
- 58, 7,229,227,120,122, 1,168,140,164,123, 3,176,162,124,222,215, 74,110, 92,174,190,238,141,203,213, 63,231, 0,160, 21,159,
- 69, 0, 39, 0,228,215, 41,130, 69, 8,161,213, 34, 3,215, 15,140, 69, 73, 78,106,234,149, 60,139, 45,223, 60,160,119,143, 55,
-134,116,243,125,239,197,103, 38,205,115,115, 85,107,146,147, 46, 83,194, 33,215,209,141,169,228,242,126, 33,221,187,203, 51, 50,
- 50,224,230,230,134,180,180, 52, 92,188,120, 17,102,179, 25,165,133,133,176,228,231, 67,200,205, 5,114,115,145,244,251,239,104,
-101, 48, 40,121,160,175, 3, 78,186,106,130,224,155, 69,173, 56,158, 7, 92, 92, 0,157, 14,148, 16,167, 50,200, 96, 48, 12,105,
-221,186,245, 97,131,193, 48,171,194, 80,188, 17, 30, 30,158, 75, 41,197,172, 89,179, 92, 93, 93, 93, 55, 53,110,220, 88, 85,155,
-142,206, 83, 24,222,173, 67,115, 62, 33,249, 20, 66, 91, 60,133,198,126, 15,227,114, 90, 33,178, 11,205,200,200, 43, 69,203,150,
- 51,225,109,120, 5,110,190, 19,112,242, 66, 10, 12,190,193, 28, 39, 87,212,184,239, 25, 25, 25,215, 45,127,247,237,183, 48,153,
- 76,104,222,188, 57,158,121,230, 25,188,245,214, 91,120,250,233,167, 97, 48, 24,208,179, 41,240,210,115, 35,144,149,229, 92,147,
-161,128,128, 0,144,255, 69,240, 32, 8, 2,236,246,255,153, 42,171,213,234,168, 84,104, 96, 96, 32,174, 93,187, 86,101,174,244,
-122, 61, 6, 13, 26,132,168,168, 40,196,198,198,130, 16, 2,189, 94,143,142, 29, 59, 18,142,227,194,106, 18,211,235,185, 1,161,
-161, 61,149, 5,249, 95, 1, 40, 55,123, 47,189,232,141,163, 71,218,225,207, 63, 66, 48,229,181,166,224,136, 26,132, 83,192, 84,
-250, 27,218,180,109,175,112,117,165, 3,107, 76, 96,104,232, 14, 73,146,206,180,107,215, 78, 54,113,226, 68,168, 84, 42,108,216,
-176, 1,171, 87,175,198,242,229,203,145,144,144,128,160,160, 32,248,249,249,193,199,199, 71, 38, 73,210,153,208,208,208, 29,181,
-237,247,213,171, 87, 7, 95,189,122,117,112,223, 86, 69,207, 80,130,208,213,139, 23, 96,245,106,128, 18,132, 82,208,144,242,234,
- 65,199,219, 94,253,242,203, 47, 57,187,119,239,230, 87,175, 94,157, 61,110,220,184,246,141, 26, 53, 26, 73, 8, 81, 54,104,208,
-224,133,215, 39,188,120,244,255,222,121,215,190,119,239, 62,169,169,151,132,148,115, 71,164,243,127,124, 85, 38,218,203,150,215,
- 98,176,148, 60,207,131, 82,138,241,227,199,107, 91,182,108, 73, 4, 65, 0,165, 20, 74, 91,169,141,147,208,146, 16,238, 73,194,
-243, 54, 17,100, 19,161,252, 67,146, 32, 83,212, 24,253, 6, 30,107,219,177, 35,111, 42, 75,130, 78, 31,130,220, 15,223,133,148,
-145, 15,154, 85, 4, 81,166, 69,153,164, 70,145, 85,142,188, 14, 93, 96,140, 63,143,134, 90,189, 76, 70, 72, 31,118, 31, 97, 48,
-254, 91,212,232, 65,254,135, 55, 33,100, 55, 33,100,247,156, 57,115, 30, 1,224, 69, 8,217, 93, 97,130,188, 43, 62, 43, 43,215,
-185,197,178,119,117,157, 27,254, 91,253,115,131, 57,115,230, 60, 74, 8,217,221,163, 71,143,231, 42,140,220,157,143, 96,137,162,
-120,232,243,207, 87,249,188, 60,110,168,207,182,221,235,194,183,239, 56,217,241,217,167, 51,206, 26,252, 59,120,111, 90,245,167,
- 82, 16,232,110,135,183, 38, 73, 29,188,124,124,144,148,148,132,232,232,104,152,205,102, 88, 44, 22, 88, 44, 22,216,242,243, 97,
- 47, 40, 0, 41, 46,134, 82, 16, 96, 78, 78, 70,211, 14, 29, 64,128, 54,142, 26,172, 27,171, 0,171, 12, 22,165, 32, 46, 46,229,
-175, 91, 84, 19,222,194, 92,117,238,220,185,243,198, 47,190,248, 66, 49,125,250,244,176,224,224,224,136,244,244,244,228,192,192,
-192, 65, 31,125,244,209,239, 11, 23, 46, 84,141, 25, 51,166,197, 23, 95,124,241, 44,128,117, 53,105, 41,212,230,118, 65, 62, 45,
- 80, 92,214, 21, 90,165, 18,121, 69, 22,228, 23, 91,144, 83, 96,198,142, 93,163, 97, 49,155, 32, 88,172, 16,109, 2,116, 62,195,
-209,220,243, 17,128, 94,106, 91,147,102,100,100, 36,206,156, 57, 83, 21,193, 50,155,205, 24, 48, 96, 0,134, 15, 31,142,164,164,
- 36,196,197,197,193,205,205, 13,222,222,222,216,186,117, 43, 78,157, 58,133,144,144, 16,167, 79, 18, 94,229,133, 79,191,253, 30,
-102,179, 25,148,211,129, 86,171, 89,118, 52,130, 37, 73,146, 65,169, 84, 86,152,163,114,115,229,230,230,134,207, 63,255,220,244,
-218,107,175,253,109,206, 63,181, 90, 93,163, 19, 38,144, 58,121,120,182,129, 49, 37,188,226,162,148,129, 64,133, 71,251,198,195,
-102,147,144,112, 97, 0,212, 42, 21, 56,162,130, 32,228, 66,239,230, 3,128,180,173,229, 60,234,191,119,239, 94,232,245,250,170,
-106, 65, 0, 24, 50,100,200, 12,157, 78,215,211,108, 54, 15,219,189,123, 55, 10, 10, 10, 16, 28, 28,140,134, 13, 27, 34, 42, 42,
-170,191, 3,133, 7,178,179,179,225,167, 23,220, 39,206, 89,216, 16,156,103,197,197,149,209,112,245,226,133, 89, 17,139,222,223,
- 67, 9, 66, 65, 16, 26, 49,142,108,169,173, 39,225,214,173, 91, 69,131,193,112, 57, 51, 51,179,231,210,165, 75,179, 91,182,108,
- 25, 56,127,254,252,185, 6,131,193,115,230,140,215,147,186,119,239,254,221,226, 21, 95,246,216,183,229,147, 70,146, 68,127, 37,
-176,204, 47,201, 72,184, 88,219, 53,116,250,244,105,184,186,186, 34, 49, 49, 17, 94, 94, 94, 16, 69, 17,146, 36,129, 32,171, 88,
- 84,200,190,231,237,194,215,188, 92,189, 26,176,157,151, 40,109, 77,101,146,130,188,247, 30, 71,231,205,147,110,161,217, 78,169,
- 82,161,180,148,162,248,207, 61,144,242, 76,160, 5,101,128,201,138,210, 50, 30,197, 38,130, 98,147,132,178,142,161, 16,247, 69,
-194,163,208, 12, 74,105, 7,118,187, 97, 48, 24, 53,148, 85, 67, 8, 33,187,195,195,195,135,212,244, 59,165,116, 8, 0,235, 13,
-203,112,228, 51, 0, 44, 94,188,120, 81,181,101,211, 93, 49, 88,103,206, 93,222,218,190,125,243,182, 1, 1, 30, 45, 66,218,183,
-247, 14,240,191, 92,212,192, 59,192,245,231,189,167, 52, 89,153,249, 23,206,156,185,244,131, 51, 70,181, 44, 47, 15,198,147, 39,
- 81,148,151,135,178,210, 82,152,139,139, 33,228,231,195,175, 85, 43,208,146, 18,240,101,101,144, 89, 44, 80, 72, 18, 52, 90, 45,
- 42,194,128,183, 68, 46, 73, 80,253,241, 7,252,134, 15, 7,149,203,145,119,226, 68, 85,181,160,107,255,254,128, 86, 11,206,221,
- 29,182, 29, 59,192,243, 60, 36, 15, 15, 96,197, 10, 71,204,149,151,175,175,239,214, 79, 63,253, 84,145,147,147,131,179,103,207,
-158,186,114,229, 74, 81,131, 6, 13,116, 50,153, 76,186,112,225,194,161, 11, 23, 46, 12,108,210,164, 9, 68, 81,108, 90,155, 94,
- 73,129,206,102,179, 75, 72,203,186,134,212,244,211,112,211, 53, 2,229, 2,145,153,103, 2, 65, 67,216,203, 46, 64,170,104, 75,
-102, 41, 75, 69,169,197,177, 72,155,205,102,131,205,102,131, 32, 8,176, 90,173,120,254,249,231,113,236,248,113,124,187,235,119,
-164,164,164, 32,216, 71,131,103,158, 30,129, 78,157, 58,161,178,199,161, 35,134,181, 58, 77,186, 46,131, 82,169,196,182,109,219,
-160,213,106,255,182,125,135, 78, 52,153,204,152,156,156,220,200,219,219, 27, 28,199, 85, 69,177, 6, 14, 28,168, 73, 74, 74,202,
-177,219,237, 93, 78,156, 56,145,231,204,201,187,103,207,113, 76,152,112, 22,217,217,229,145,221,239,191,253,159,127, 74,186, 98,
-195,128,193,123, 1, 0,238,238,238, 88,182,204,177,217, 30, 68, 81,196,154, 53,107,170,170, 5, 1, 64,169, 84,118,159, 62,125,
-250,176,155,173,223,182,109, 91,135,242,179, 42,159,168, 29,200,159,116,211,245, 38,206, 89,216, 16,212, 62,216,145,158,132, 70,
-163,177,204,211,211, 51,178,168,168,232,241, 77,155, 54,229,135,133,133,241,238,238,238,121, 0, 84,132,218,108, 39, 14,253,144,
-100, 46, 42, 26,111,179,217, 28,110, 52,158,151,151, 7,139,197,130,171, 87,175, 66,163,209, 64, 46,151, 87, 24,172,202, 29,169,
-248,104,151,236, 84, 70, 56,153,157,231,230, 99,222,173, 47,118,142, 3,174,102, 0,159,237, 66,222,216,193,176, 47,156, 12, 81,
- 80,160,164, 72,130,117,240,107,176,218, 36,216,121, 37,202, 90,183, 67,254,130, 15, 96,209,105,128,211,127,178, 59, 8,131,193,
-168,233,129,117,247,236,217,179,231, 58,184,250, 1, 0,131,157, 49,110,149,203,179,103,207,158, 91,185,173,240,240,240, 50, 0,
- 70,103,211,234,208, 72,238,146,164, 88,181,111,111,148,156,147,203,184, 38, 65, 46,133,128, 21, 39,162,211, 92,236,162,252, 11,
- 39,115,230, 84,226,197,139,160,146,132,146,130, 2,152,243,242, 96,207,202,130, 61, 43, 11,164,184, 24,178,178, 50,200,204,102,
-200,173,102,168,101, 50, 20,102,102,130,112,220,217, 90, 51,198,110,175,138, 20, 92, 87, 45,168,211,129,232,116,128,139, 75,213,
-247,196,193, 42, 66,149, 74,245,245,154, 53,107,124,253,252,252,176,110,221, 58,248,250,250,182,124,236,177,199,114, 30,122,232,
-161,204,161, 67,135,198,188,245,214, 91, 3, 67, 67, 67,145,147,147, 3,158,231, 19,107,211,179,219, 84,127,157, 75, 20,145,157,
-243, 23,162, 98,191,198,238, 95,231,224,252,213,179, 72,207, 45,133, 75,195,113,144,233, 30,170, 90, 87,169,239,141,204,204, 28,
-128,212,188,239, 55, 26, 33, 74, 41, 78,158, 60,137, 13, 59,143,193,208,246, 49,200, 93,188,113,250,244, 57, 28,222,191, 15, 1,
- 1, 1,181,154,161,119, 95,230, 51, 31,235, 82,136,253, 91, 94, 65,214,165,175, 29, 54,120, 14, 94, 20, 49,151, 46, 93,162,174,
-174,174,215, 85, 17,246,235,215,143,140, 28, 57,210, 85,169, 84,238,232,221,187,183,195, 3,223, 82,144,147,146,152,139,166, 77,
-255,231,109, 55,124,147,141,184,152, 62, 56,123,234,113,236,252, 49,189,234,251, 70,141, 26, 33, 35,227, 10, 0,122,182,150, 52,
-254, 58,120,240, 96,236,222,189, 27,106,181, 26, 90,173, 22,195,135, 15,135,201,100,122,170,226,137, 6,132, 16, 16, 66, 48,191,
-162, 45,159,201,100,178, 56,106,176,146,242, 20,218,183,103, 45,201,122,123,145, 50,235,237, 69,202,172, 21,159,146,210,137,115,
- 22, 54,156, 48,231,157,193, 0, 26, 86,111,155,229,160, 33, 42, 62,126,252,248, 31, 51,102,204, 8,104,215,174,157,201,223,223,
-223, 94, 84, 84,196, 15, 31, 62, 60, 32, 55, 55,247, 13,103,204, 21,165, 20,185,185,185,200,201,201, 65,106,106, 42,178,179,179,
-145,147,147, 83, 62,228, 9, 26,186,242, 54,225,105,240,220, 15,162,221, 98,177,203, 72, 11,128, 94, 17, 37,155,117,222, 60, 72,
- 53,136,158, 49, 21, 21,131, 51, 83, 72,127, 37,193, 42,169, 81,104,149,161,192,194,163,216, 44,162,136, 40, 80,204,169,144,215,
-163, 55, 44, 34,143,162,194, 34, 16, 66, 78,177, 91, 8,131,193,168,201, 8, 45, 94,188,120,209,221,210,174,252, 28, 30, 30,126,
-166,218,182, 52,183, 19,193,234, 93,173,222,179,247,141, 43,157, 61,123, 54,115, 64,255,199, 26,174,252,252,112, 83,155, 85, 20,
-118,253,188,223,102,183,233,202,206, 93, 72,116,170, 65,143, 77,146,246,197,198,196, 12,232,217,163,135, 42, 41, 46, 14,246,252,
-124,136,249,249,144,219,108,144,149,150,130,179, 88,192,151,149,161, 81,103, 45, 64,125,113, 34,209, 40,216, 68,241, 64,173, 38,
-163,194, 96,161,210, 92, 85, 84, 23, 86, 85, 11,234,116, 85,223, 59, 98,176,124,124,124,180, 3, 7, 14,236,221,165, 75, 23, 80,
- 74,177,116,233, 82,216,108, 54,165,205,102,131,221,110,135,205,102, 67,113,113, 49,182,111,223,142,141, 27, 55, 30,215,235,245,
-223,212,110, 2, 45,251, 14,254, 25,223,255,249,225,143, 42,247, 31,254, 18,118,139,128, 18,179, 59, 74,205, 86, 20,151,201, 97,
- 85,245, 3, 33,191,131,227, 85,232,209,185, 25, 14, 29,189,104,150,236,182,253, 78, 58,123, 88, 44, 22,100,101,101, 35,175,228,
- 55,160, 48, 21, 13,108,197, 40,185,122, 25,157,159,127,161, 86, 51,196,113,208,174, 91,248, 60,100, 50, 25,182, 31, 47,129, 76,
- 38,131, 32,220,124, 56, 42,158,231,225,230,230,134,146,146, 18, 0,168,213,101,217,237,246, 79,118,236,216, 49,168,105,211,166,
-234,192,192,192,235,170, 9, 39, 79,158,172, 60,123,246,108,235,132,132,132, 15, 1, 76,119,100, 95, 11, 11,165, 95,243,242, 46,
- 13, 31, 54,108,152, 34, 50, 50, 18,148, 82,180,104,225, 14,189,171, 14,132, 83,161, 77, 27,111, 0, 23, 64, 8, 65,239,222,189,
- 97,179, 25,133,210, 82,212,216,208, 59, 38, 38,230,201,176,176,176, 38,130, 32,196,119,232,208, 65,150,145,145,129, 17, 35, 70,
-224,251,239,191,175,124,162,193,236,217,179,175,143, 76,150,148,212,106,176, 36, 73,130,205,102, 67,196, 79,105, 46, 10,133,194,
- 5, 40, 31,143, 45,252, 5,175, 44, 80,187, 11,138, 22, 2, 64, 86, 68,248,130, 24,160,124,248, 6, 71,143,121,126,126,126, 74,
-227,198,141, 47,125,246,217,103,173, 95,123,237, 53,203,107,175,189, 22, 80, 86, 86,182,149, 82,122,205,201,130,197,154,158,158,
-174,211,104, 52, 56,117,234,148, 85,163,209, 40,124,125,125, 9,165, 20,130,204, 69, 38,113, 72, 0,165, 39,136, 40, 42,120, 94,
-246, 52, 8,249,157,240,124,141,199, 93, 4,126,187,116,246, 92,175,230,254, 45,184,226,195,103, 80,216,229, 33, 20,151, 2,165,
- 37, 4,162, 92,131, 82,153, 10, 37, 77, 91,160,216,203, 23, 50,112, 48,166, 36,217, 5, 74, 15,176, 91, 8,131,241,159,163, 70,
- 15,114, 99, 4,235,129, 7, 30,216, 92, 61,202, 84,249, 25,128, 5, 64, 77,109,162,179,171, 71,170,170, 27,170,155,109,231, 6,
-221,186, 25, 44, 74,233, 17,212, 80, 21, 23, 24, 24,216,115,218,180,105, 29, 95,125,245, 85,148,148,148, 96,195,134, 13, 88,181,
-106, 21, 2, 3, 3,123,166,164,164, 28,117,116, 99,141, 27, 55,254,238,199,253,251,223,232,216,170, 85,139,198,141, 27,227,194,
-165, 75, 80,216,108,144, 9, 2,120,147, 9,114,187, 5,141, 67, 93,160, 80, 55, 64,122,146, 9,155,207,156,185, 70, 41,253,170,
-198, 27, 55,199,161,244,209, 71, 81, 20, 23, 7, 78, 16,224, 58,104, 16,136, 86, 11,170,215,195,190,101, 11,100, 50, 25, 56, 73,
-130,108,225,194,114,179,213,183,214, 54,243,200,204,204, 52, 53,111,222, 60,238,252,249,243, 33,173, 90,181,194,123,239,189,135,
-148,148, 20, 80, 74,145,149,149,101,206,202,202, 50,230,229,229, 37,115, 28,247, 99, 90, 90,218,215,142,140, 20,158,217,130,219,
-180,127,255,129,105,161,157,219, 54,239,211,107, 62,118,239,126, 23, 5, 69, 69, 40,181,200, 80, 82,102, 67,169,153,194,224,218,
- 20,221, 58,118, 65,118,174, 21, 9,103, 98,211,178, 21, 30, 95, 57,107,176,226,227,227,209,200, 19, 56,123, 33, 6, 13, 44,185,
-104,229,174, 67,151,158, 15,225,202,149, 43, 55,141,122,253,205,100,145,242,155,127, 81, 81, 17,122,180,106,133,204,204, 76,228,
-230,230, 86, 51, 97, 28, 60, 61, 61,161,213,106, 17, 19, 19,131, 63,254,248,195,206,113,220,187,181,165, 45, 38, 38, 38,190, 71,
-143, 30, 17, 27, 55,110,156,240,246,219,111,171, 43,205, 85,101, 68,232,163,143, 62,210,142, 26, 53,106, 76,151, 46, 93,162,226,
-226,226,182,214,166, 23, 29,125,114,135, 94, 79,222, 28, 59,118, 82,219, 49, 99,198, 96,251,246,205,120,233,197,150, 32,156, 10,
-132,168, 48,244,241,214, 88,176, 48, 6,221,186,245, 70,131, 6, 10, 28, 56,112, 38, 73, 38,115,251,206, 1, 51,180,108,201,146,
- 37, 50,181, 90, 13,171,213,138,146,146,146,170,253, 95,188,120, 49,230,204,153, 3, 0,152, 55,111, 30,230,207,159, 15,179,217,
- 92,107, 7,135,202, 8, 86, 98, 98, 98,149,209,231, 56,174, 42,162, 5, 40,145, 94, 36, 43,216,127, 65, 31, 99, 52, 26,157, 30,
-197,253,218,181,107, 7, 87,174, 92,217, 78, 46,151,251,236,221,187, 87, 42, 45, 45,221, 94,135, 39,183, 37,145,145,145,239, 83,
- 74,101, 90,173,246,151, 83,167, 78,245, 41, 45, 45,213, 82, 74, 65,196, 43, 69,156,181,219,118,145,200, 56, 42,227, 7,131,160,
- 57,120,188,171, 80,106,115,106, 44, 92,100,178, 47,230,110,218, 57,121,109,196, 71,134,162,210, 66,148,125,176, 6,182,216,179,
-176, 41,117,200, 93, 24, 14,147, 85, 66, 89,126, 9, 92,215,126, 14,141,175, 47, 14, 23, 39,102, 21, 22, 21,173,101,247, 26, 6,
-227, 63, 23,149,170,209,131, 84, 55, 71, 21,159,243, 0, 36,133,135,135,231, 84,107,139,149, 13, 32, 30, 64,167,138,245,178,111,
-248, 95, 54,202,123,166,135, 85,211,201,174,102,180,170,127,182,222,176, 78,124, 93,246,203,161, 42,153,148,148,148,163, 97, 97,
-229,157,186,202,202,202,144,154,154, 10, 65, 16, 96, 52, 26,143,214,114,195,191,110,182,237,173, 91,183,138,221,186,117, 27,245,
-201, 87, 95, 29,154,242,228,147, 30,221,135, 14, 69,234,241,227,176, 25,141, 80, 10, 2,148, 10, 53,236,165, 13,145,151,102,198,
-151,103,206, 20, 89, 69,113,116,108,108,172,189, 38,205,202, 8, 65,101, 99,118,232,116,229,237,174, 92, 93,203,205, 21,199,129,
- 39,164, 60,138,229,234, 10, 40, 20,181,166,179, 98, 63,159,125,229,149, 87,162,126,254,249,103,247,209,163, 71, 99,232,208,161,
-241, 69, 69, 69, 3,114,114,114, 74, 28, 52, 59,215,105,210,173, 91, 69,239, 78, 79,141,252,124,245,218, 67, 99,199,142,245, 24,
- 58,108, 21,226,206,158, 70,126,105, 67, 0,128,161,129, 11,186,181,122, 11, 89,185, 22,252,250,203,238, 2, 42,153,158,165,127,
-109,174,113,223,189,189,189,175,139,200,241, 60,143,195,135, 15, 99,234,212,169,104,160, 59,140,226,164,203,232,240, 80,111,244,
- 29,243, 2, 94,122,233, 37,240, 60, 15, 47, 47, 47,100,102,102,222, 84, 83,146, 96,154,183, 50, 66, 39,136, 28,178, 11,149,226,
-247,251,158,231,166, 79,159, 78,210, 79,206, 66, 89, 73, 6, 26, 41, 44, 80,112, 13,144,145, 59, 18, 27, 55,110,164,185,185,185,
- 59,228,114,249,123,169,169,169, 87,107,203, 79, 0, 80, 40, 20,243, 51, 51, 51,165, 55,222,120, 99,226,248,241,227,213, 29, 58,
-116, 32, 77,154, 52, 65, 90, 90, 26,226,227,227,169,197, 98,225,244,122,189,143, 67,249, 73,169,212,181,107,215,167,247,239,255,
-225,200,227,143, 63,233,213,191,255, 3,240,245, 45,134, 32,228,128,112, 10,168,212, 13,177,118,237, 98,100,101,230,225,216,241,
-227,249,101,101,202,209, 81, 81,215,143, 14,127,139,116,218,246,238,221, 11,181, 90,141,237,219,183, 11, 62, 62, 62, 50,119,119,
-247, 91, 70,176,202,202,202, 84,181,105, 86, 26,172, 74, 99, 85,105,178, 86,255,152,234,162, 80, 40, 92, 8, 33, 16, 4,161, 97,
-139, 22, 45, 66, 29,217,247,155, 20, 78, 2, 33,100,195, 59,239,188,243,118, 94, 94,222, 18, 71, 12,255,141,154,209,209,209,171,
- 0,172,170, 92,238,214,173, 91,151, 43, 87,174,252, 34, 73,146, 70,150,123,197,244,215,158,129, 89, 33,175, 30, 10, 22, 57,234,
- 2, 66,223, 17, 56,146,247,215,242,238,230,154, 52,143, 31, 63,110, 14, 11, 11,123,118,193,162, 79,246, 76,154, 50,197, 69, 28,
-255, 50, 74, 47,189,143, 98,155,132, 98, 59,129, 69,226,224,245,203, 54,200, 26, 52,196, 33,174,160,212,202,243,207, 94,190,124,
-217,234,204,190,215, 5,166,201, 52,153,102,253,212,172,237,185,250,102,177, 11, 7,214,139,118, 64,231,174,224,144,193,170,136,
- 96, 97,194,132, 9, 40, 46, 46,198,230,205,155,241,235,175,191, 58, 29,193, 2,128,168,168,168,203,221,186,117,235,247,254,250,
-245,223, 13,110,213,170, 81,171,166, 77, 21,158,109,219, 66,163,213,162, 32, 55, 23,241, 73,233,226,198, 11, 23,174,154, 5,225,
-185,216,216,216,115, 14, 68, 28, 32, 8, 2,188,188,188, 64, 5, 1,154, 89,179, 64, 9,129, 68, 8, 74, 8,129, 36, 73, 16, 5,
- 1,170,174, 93, 33,200,100,200, 43, 40,112, 40,157,105,105,105,105,129,129,129,163, 95,123,237,181,159, 55,108,216,192,245,238,
-221,187,227,143, 63,254, 72,111, 39,179,179,227,183, 95,246,237, 60,172,223,202,149,171,190,237, 18,214, 45,176,113,147, 38,170,
-158,129,110,176,217, 69,100,102,229,226,200,177,115,150,132,179,127,165, 66, 48, 63,151,121,250,167, 26,247, 93,161, 80, 36,185,
-187,187, 55,158, 63,127, 62, 4, 65,128, 36, 73,176,219,237,200,206,206, 70, 92, 92, 28, 66,186, 63,128,214,227,198, 35, 47, 47,
- 15,235,214,173, 67, 64, 64, 0, 6, 13, 26,132,130,130, 2, 92,184,112, 33,233,102,154, 11,214,138,215,153, 27,131,193,208,121,
-220,184,113, 31,188, 49,170,248,161, 55,199,141, 5,165, 20,225,107,190,196, 55, 59, 55, 30, 5,200,220,244,244,244,191,156,217,
-255,138,233,111,222,237,214,173,219,246,181,107,215,206,224, 56, 46,180,172,172,204,160, 86,171,115, 8, 33, 39, 77, 38,211,251,
-209,209,209, 39, 29,213, 59,113,226, 68, 82, 72, 72,200, 35,153, 25,171,191,155, 56,161, 95, 51,187, 61, 84,169,119,123, 8,148,
- 10, 40,200, 79, 1,161, 39,109, 63,236,252,237, 74,113,177,226, 25, 71,167,202,145,201,100,175,255,244,211, 79, 64,197, 84, 57,
- 70,163,241, 76,229,240, 31, 55,139, 96, 57, 66, 89, 89, 25,236,118, 59, 8, 33,215, 25,172, 75,151, 46, 93, 23,209,114,162, 96,
-235, 1, 96, 32, 42,186, 21, 3,104, 8,192, 59, 39, 39,199, 27,192, 80, 66, 72,118,197, 83, 87,229,107, 63,165,244,176,147,215,
-105, 92,104,104,104,127, 66,200, 7,165,165,165, 38, 0,144,148,214, 98,174,140,219, 70,120,222, 22,255,217,163, 14, 53, 15,136,
-142,142,142, 9, 11, 11, 27, 60,107,230,172,111,159,120, 98,148, 79,224,139,207,242,228,228, 5,216,212, 74,168, 18, 18,192,233,
- 92,233,158,194, 43,153,197,114,254,153,232,232,104, 54,138, 59,131,193,184,111, 32,181, 85, 25, 85,187,217,154,130,130,130,224,
-233,233,137,188,188, 60, 92,187,118, 13, 70,163, 81, 91, 87,135,123,227,100,207,132, 82, 66, 29,152,236,185,186,102,239,222,189,
-101, 22,139,229,138,221,110,119,106,140, 10,185, 92,158, 29, 25, 25,217,216,145,116,250,251,251,143, 12, 8, 8, 88,152,150,150,
-182, 43, 53, 53,117,214,157,112,247,149,147, 61, 67,166, 24, 8, 42,181, 7, 64,192,241,181, 78,246, 92, 93, 51, 36, 36,164,183,
- 66,161,248,212,102,179, 53,190,113, 61,155,205,134,220,220, 92, 88, 44,229,213,198, 74,165, 18, 94, 94, 94, 80, 42,149,224,121,
- 62, 73, 20,197, 41,149,115, 17, 58,242, 20,242,225, 84,185,105,250, 75,227, 40, 0, 44, 93,251, 5,185,100,162,158, 95,127, 77,
- 45,245,229,105,137, 16,194,245,232,209,121,132,171,142, 12,144,168,212,177,226,187, 51, 37, 37,248,213,207, 47,248,251,173, 91,
-183,138,117, 77,103,104,104,232,142,146,146,146,254, 9, 9, 9,183, 74, 23, 40,165,218, 91,105,222, 48,208,104,109,220,180,138,
-240,126,120,162,173, 62,217,179, 76,146,218,219, 9,161,142, 76,246,204, 34, 4, 76,147,105,178, 8,214,191, 21,135,123,109, 25,
-141, 70, 45, 33,228,109,148,207, 17,183,136, 82,250,193,237,108,184,194, 64,109,172,120,221,142, 70,163,187,153, 65,105,105,105,
- 91, 1,108,189,147,154,244, 14,236,123,133, 65,106,251, 79,156, 36,130, 40, 88,150,173, 91,163, 2, 0, 9,176, 5, 93,131, 80,
-159, 78,226,138, 42,177, 45, 21,175, 59, 74, 76, 76,204,147, 6,131,225,152,151,151, 87, 83,139,197,162, 40, 43, 43,147, 83, 74,
-171,234,101, 53, 26, 77, 78, 45,215,205, 71,172,152, 41,175, 46, 4,176,162,226,197, 96, 48, 24,204, 96,221,112, 35,251, 0,192,
- 7, 44,219,254, 91,204,253,140,122,254,151,247,223,104, 52,246, 96,103, 1,131,193, 96, 48,156,129, 99, 89,192, 96, 48, 24, 12,
- 6,131,113,103, 33, 0,110, 58,196,181, 51,117,171,132,144,246,206,110,184, 54,125,166,201, 52,153, 38,211,100,154, 76,147,105,
-222,127,154,181,105,223, 47,109,187, 28,110,228, 94, 39,113,214, 0,144,105, 50, 77,166,201, 52,153, 38,211,100,154,255, 65, 88,
- 21, 33,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48,
- 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,163,222,112, 87,123, 17, 50, 24, 12, 6,131,193, 96,252, 23, 97, 17, 44,
- 6,131,193, 96, 48, 24,140,187, 97,176, 8, 33,180,250, 59,131,193, 96, 48, 24, 12,198, 63,193,253,234, 65, 88, 4,139,193, 96,
- 48, 24, 12, 6,131, 25, 44, 6,131,193, 96, 48, 24,140,127,135,193,234, 93, 17,154,235,205,178,132,193, 96, 48, 24, 12,198, 63,
-200,125,233, 65,170,122, 17, 18, 66, 40,165,148,176,227,204, 96, 48, 24, 12, 6,227, 31, 53, 35,247,161, 7, 97,195, 52, 48, 24,
- 12, 6,131,193, 96,220, 97,238,106, 27, 44, 66, 72,123,166,201, 52,153, 38,211,100,154, 76,147,105, 50, 77,102,176, 24, 12, 6,
-131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12,
- 6,131, 25, 44, 6,131,193, 96, 48, 24,140,123, 4, 1,112,211,158, 0,148,210,211, 14,139,212,161, 55, 65,109,250, 76,147,105,
- 50, 77,166,201, 52,153, 38,211,188,255, 52,107,211,118,198,127,212,107,131,117, 55,199,193, 34,132,180,191,211, 25,197, 52,153,
- 38,211,100,154, 76,147,105, 50,205,251, 79,243,126,131, 85, 17, 50, 24, 12, 6,131,193, 96,220, 97,100, 44, 11, 24, 12,231,240,
-241,241,209,202,100,178,246, 70,163, 49,154, 82, 42,178, 28,169, 31,199,132,227,184,206,148,210,132,140,140,140,156, 59,161,105,
- 48, 24,188, 0, 52,151, 36,233,242,157,210,100, 48, 24,204, 96,161,107,215,174, 9,162, 40, 6, 56, 35,166, 84, 42, 83,143, 29,
- 59,214,242, 86,191,135,133,133, 37, 72,146,244, 55, 77,185, 92, 46,217,237,246,155, 70,211,228,114,121,118,100,100,100,227,250,
-146, 97,132, 16,127, 0, 31,184,184,184,244, 38,132,112, 37, 37, 37, 71, 0,188, 77, 41, 77,174,163,158, 43,128, 23, 1,132, 84,
-124, 21, 11,224,107, 74,105, 49, 59, 61,235, 31,254,254,254,131,120,158,223,232,239,239, 47, 81, 74,243, 3, 3, 3,199,164,164,
-164,196,176,156,185, 55, 4, 4, 4,180,147, 36,105,170,135,135,199,208, 54,109,218,104, 18, 19, 19, 97, 48, 24,162,100, 50,217,
-203,201,201,201, 87,235,104,172, 2, 1,172,245,246,246,126,176, 89,179,102,184,124,249,242,109,107, 50, 24,245,149,198,141, 27,
-187, 21, 23, 23,175,226, 56,174,147, 90,173,246,113,117,117,133, 78,167,203, 84,169, 84, 39,221,220,220, 38,238,220,185,179,144,
-229,210, 29, 54, 88,148, 82,223,223,126,251, 13,122,189, 30,162, 40, 66,146, 36, 72,146, 4, 74,105,213,123,117,108, 54, 27,250,
-247,239,239, 91,211,198, 40,165,126,135, 14, 29,130,171,171,235,117,255,123,224,129, 7,184,163, 71,143, 66,173, 86, 95,183,190,
-213,106, 69,143, 30, 61,188,235,145,185, 50,232,116,186, 19, 3, 6, 12,176,133,133,133,105, 20, 10, 5,205,201,201,121, 96,221,
-186,117, 39, 8, 33,221, 40,165,215,156,212,235,170,215,235, 87, 61,249,228,147,150,192,192,192, 70, 58,157, 14,102,179,185,201,
-170, 85,171,158, 39,132, 76,162,148,158, 96,167,104,253, 33, 56, 56, 88,239,225,225,241,213,146,197,139, 85,191,252,252, 51, 82,
- 83, 83, 53,162, 40,126, 71, 8,105, 69, 41, 21, 88, 14,253,243,199,131, 16,178,235,195, 15, 63,244, 25, 53,106, 20,120,158,135,
-217,108,198,182,109,219,186, 45, 92,184, 48, 50, 32, 32,224,193,212,212,212,203,206,104,250,248,248, 52,214,106,181,145,225,225,
-225,186, 17, 35, 70, 0, 0, 76, 38, 19,118,236,216, 81,103, 77, 6,163,190,226,237,237, 61,182,168,168,232, 99,173, 86,171,112,
-119,119,135, 70,163,129, 66,161,128, 82,169, 12,244,240,240, 8,212,233,116,253,159,125,246,217, 55,190,253,246,219,245, 44,183,
-238,160,193, 2, 0,173, 86,139,205,155, 55, 67, 38,147, 65,161, 80, 64, 46,151, 67, 46,151, 67,169, 84, 66, 38,147, 85, 45, 43,
- 20, 10, 4, 4, 56, 30,236,250,241,199, 31,225,230,230, 6,189, 94,143, 54,109,218, 0, 0, 84, 42, 21, 14, 28, 56, 0,133, 66,
- 81,165, 29, 26, 26,122, 79, 50,101, 84, 31,146, 79, 1,229,183,115, 91, 89,229, 60, 81,142, 90,120,222, 74, 1,229,136, 94,174,
-146, 91,163,222,220,162,143, 62, 75,115,119,247, 56,100,183,219,119, 29, 58,116,168,157,159,159,223,136,137, 19, 39, 46, 6,240,
-180, 19,230,202,213,205,205,109,213,107,175,189,230, 61,118,236,216, 51,190,190,190, 27,138,139,139,143, 69, 70, 70,182, 88,187,
-118,237, 27, 19, 39, 78, 92, 69, 8,233,237,108, 36,171,122,148,144,231,249, 92,141, 70, 19,124,248,240,225,123,126,243, 39,132,
-248, 1,248, 0,128, 0, 96, 25,165, 52,161,218,111,205, 21, 10,197, 7, 54,155, 45, 31,192,251,148,210,212,250,120,177, 88, 44,
-150,208,247, 23, 46,148, 95, 73, 76,196, 79,123,246, 84,126,237, 26, 16, 16,208, 29,192,209,127, 50, 45, 97, 97, 97, 77,148, 74,
-229, 7, 0, 58, 89, 44, 22, 67,197,245,106,148, 36,233,199,178,178,178,247, 98, 99, 99,203,234,120,156, 2, 0,180, 65,121, 15,
-227,155, 62, 39,133,135,135, 95,154, 61,123,246,213,123,169, 9, 0,102,179,121, 65,223,190,125,125, 70,143, 30,141,125,251,246,
- 97,255,254,253,232,218,181, 43,250,247,239,143,196,196, 68,151,117,235,214,189, 4, 96,142,147,251,255,252,203, 47,191,172, 27,
- 49, 98, 4,246,236,217,131,223,126,251, 13,221,187,119,191, 45, 77, 70,253,133,231,249, 66, 73,146,228, 0, 60, 41,165,150,218,
-150,239,167,125,111,208,160,193,203,121,121,121,159, 24, 12, 6,120,123,123,131,144,242,203, 83,146, 36,148,150,150,162,172,172,
- 12,193,193,193,138, 54,109,218,124, 62,121,242,100,249,231,159,127,190,150,157, 49,206,193, 17, 66,122,221, 80,192, 84, 45, 75,
-146, 84,101,172,170, 27, 42,158,231,171, 62, 87,254, 86,241,223, 27, 35, 86,167,111, 88, 38, 37, 37, 37, 85,230,202,205,205,173,
- 42, 18,102,183,219,175, 51, 87,114,185, 28,162, 40,222, 44, 10,118,199,123, 45,220, 76, 83, 43,192, 83,222,251,188, 7, 30, 58,
-167,221,114,128,122,108, 61, 64,181, 63, 71, 11, 57, 45,219, 63, 84,234,238,238,113,146,231,249,131, 25, 25, 25,103,151, 46, 93,
-186,166, 87,175, 94, 58, 31, 31,159,135,156, 76,231,139, 79, 61,245,148,101,204,152, 49,167,131,131,131, 31,214,104, 52,222, 62,
- 62, 62, 10,157, 78,183, 67, 16,132,117, 43, 86,172,176,162,188,234,208,169,125,167,148,250,238,219,183, 15, 7, 15, 30, 4,165,
-212,189, 54, 19,253, 79,229, 39,128, 89,153,153,153, 35,147,146,146, 70,123,121,121, 29, 38,132,116,172, 56,103,218, 13, 27, 54,
-236,143,210,210,210,129,145,145,145, 99, 42, 76,216,189, 76,231,223, 48, 24, 12, 63, 24, 12, 6, 19,207,243, 63, 94,185,114, 69,
-182, 42, 34, 2,130, 80,229, 89,229,114,185,252,244, 63,153,206,144,144,144,150, 74,165,242,207,101,203,150, 13,217,183,111, 95,
-192,241,227,199,185, 63,254,248,131,251,228,147, 79, 2,194,194,194,198,169,213,234,227, 33, 33, 33,242, 58,238,123,155, 35, 71,
-142,152,140, 70, 99,209,205, 94, 23, 47, 94, 52,205,158, 61,251,161,122,160, 9, 66,200, 71, 7, 14, 28,216, 63,102,204, 24,140,
- 31, 63, 62,101,203,150, 45, 83,166, 79,159,126, 37, 33, 33, 1, 3, 6, 12, 0,207,243,163,111,150, 15,183,210, 36,132,240, 60,
-207,143,121,250,233,167,113,229,202, 21, 76,152, 48, 33,101,199,142, 29, 99,103,204,152,113, 37, 33, 33, 1, 3, 7, 14,116, 90,
-243,159, 56, 63,235,179, 38, 33, 36,131, 16, 98, 34,132,232,239,132,102,133, 94,126,229, 75,161, 80,228,187,186,186,230,123,123,
-123,231, 7, 5, 5,229,139,162,248, 21, 0,185,163,154,228,127, 55,173, 14,132, 16,174,182,229,250,112,140, 8, 33,254, 60,207,
-127,199,113, 92, 58,199,113,153, 60,207,111,245,243,243,107,228,140,166,191,191,191,103,113,113,241, 82,131,193,128,134, 13, 27,
-130, 16, 2,158,231,209,173, 91, 55,116,232,208, 1, 28,199, 65,146, 36, 92,190,124, 25,105,105,105,104,219,182,237,210,240,240,
-112,207,187,177,239, 53,121,144,127,189,193, 2,112,248,134,157, 58, 92,249,163, 40,138,215, 25,169, 27, 77, 85,245,101,142,115,
-168, 67, 34,177, 90,173, 85,230, 74,175,215, 67, 46, 47,191, 22, 4, 65,248,155,230,205, 12,150,163,120,120,120,252, 72, 8,121,
-172, 46,255,221,242,110,107,124, 61, 47,232,102, 39, 2,212,106, 53, 68, 81,252,225,242,229,203, 39,154, 52,105,146, 93, 88, 88,
-232,230,230,230, 6,158,231,157,221, 76, 72, 80, 80, 80,163,128,128,128, 88, 0, 91, 0,236, 59,117,234, 84,114,159, 62,125,232,
-218,181,107,127,111,223,190,125, 16,254,215, 46,203, 41,220,220,220,112,240,224,193,250,118,174,185,151,149,149, 33, 47, 47, 15,
- 17, 17, 17,174, 94, 94, 94,123, 9, 33,207, 14, 27, 54,236,183,109,219,182,233, 10, 11, 11, 97,179,217, 0,192, 92,223, 18,110,
-179,217,214,235,245,122, 58,124,248,112, 68,172, 89,195, 23, 22, 22,138, 0, 74, 0,152, 56,142,123,249,202,149, 43, 69,255,100,
-122, 84, 42,213,180,247,223,127,223,181,109,219,182, 36, 39, 39, 7, 70,163, 17, 57, 57, 57,104,208,160, 1,222,124,243, 77,117,
-243,230,205, 13, 42,149,106,102, 93,203,187,102,205,154,221,242,194,115,113,113, 17,225,124,239,227,155,106, 10,130, 64,186,119,
-239,254, 70,199,142, 29,215,214, 65, 19, 70,163, 49,213,104, 52, 62,113,228,200,145,241,146, 36,189, 98, 52, 26,191,226, 56,110,
-237,174, 93,187,224,237,237,141,214,173, 91,123,101,103,103,119,115, 84,207, 96, 48,180,235,208,161,131, 95,163, 70,141,176,121,
-243,102, 0,248, 58, 45, 45,109, 91,117,205, 54,109,218, 56,165,201,168, 34, 93, 46,151,155, 60, 60, 60,244,183,169,163,172,124,
-201,100, 50,165, 82,169, 84,170,213,106,165, 90,173, 86,170, 84, 42,229,253,158,137,132, 16, 3, 33, 36, 86, 38,147, 13,112,119,
-119,215,123,122,122,234, 2, 3, 3,251, 52,109,218, 52,250,197, 23, 95, 12,114, 84,167,172,172,236, 75,141, 70, 35,247,246, 46,
-111,129,211,175, 95, 63,108,218,180, 9, 79, 63,253,180,212,175, 95, 63,105,228,200,145,240,241,241, 1, 0,196,199,199, 67,169,
- 84,202,117, 58,221,151,119,105,183,110,233, 65,254,237,200,110,216,201,235, 66, 80,146, 36, 93, 23,173,186,209, 0, 85,127, 57,
-138, 40,138,240,245,245,133, 86,171,133, 86,171,189,110, 91, 55,106,222,206, 24, 93,205,155, 55,239,165,213,106,123, 16, 66, 70,
- 82, 74, 15,221,129, 19, 91, 14,224,212,213,171, 87, 31,216,190,125,123,255,111,191,253, 54, 62, 44, 44,204,255,227,143, 63,158,
-116,238,220,185, 82,163,209,232,116, 67,103,189, 94,143,194,194,194,163, 26,141, 70,119,236,216,177,212, 7, 31,124, 48, 31,128,
-103, 81, 81,145,167,139,139, 11,113, 84,167,122,181,160, 90,173,182, 18, 66,100,238,238,238,112,115,115,179,229,231,231,231,133,
-132,132, 64,169, 84,230, 42, 20, 10,135,171, 11,187,118,237,154, 36,138, 98,141,237,223, 20, 10, 69,246,241,227,199, 29,237,128,
-240, 94,167, 78,157, 30, 90,181,106, 85,131, 22, 45, 90, 32, 34, 34,194,117,219,182,109, 95,108,218,180, 9, 5, 5, 5,184,122,
-245, 42, 94,122,233,165, 98, 0, 31,215,179, 2,205,255,177,199, 30, 91,214,169, 83, 39,178,121,243,102, 74, 41, 37,132, 16,112,
- 28, 55, 73, 16,132,163, 70,163, 49,231, 30,164,169, 79,171, 86,173, 72, 97, 97, 33, 40,165,224,121,254,186,215,204,153, 51, 53,
-227,198,141,155,213,163, 71,143,105,114,185,188, 88, 16,132,109, 38,147,105, 73,124,124,124, 97,125,202,219,135, 31,126,248,181,
-148,148,148,129, 65, 65, 65, 63,223,142,142,209,104,220, 92,109,241,132,209,104, 4, 0,232,116, 58,136,162,168,114, 34, 95, 21,
-238,238,238, 0,128,107,215,174, 1, 64,252,237,106, 50,202,225,121, 30, 42,149, 10, 50,153, 44,189, 81,163, 70,224, 56,206, 51,
- 41, 41,169, 46, 85,110,190, 0, 50,100, 50,153, 82,165, 82, 65,173, 86,163,242,253,204,153, 51,219,120,158,127, 21,128,221,137,
-104, 17,117,102,249,158, 71, 68, 56,238, 67,153, 76,166,244,242,242, 82, 84,123, 0, 84,120,120,120, 32, 48, 48,112, 57,128,225,
- 14, 74,117,108,208,160, 1, 8, 33, 80, 40, 20,120,249,229,151, 17, 29, 29,253, 99, 74, 74,202,203, 89, 89, 89, 40, 41, 41, 89,
-171,215,235,135,102,101,101, 65, 20, 69, 36, 37, 37,161, 83,167, 78, 29,239,242,238,253,205,131,220, 23, 6,171,210, 57,222, 24,
-154,187,153,233,169,110,178,170,127,118,240, 34,147,158,121,230,153,155,134,122, 4, 65,248, 91, 21,225,237,156,219, 42,149, 10,
-131, 6, 13, 82,107,181,218,239, 43, 76,214, 17, 71,255, 59,106,193,121,104, 4,224,235, 94, 85, 5,175, 95, 96, 96,224,175,195,
-135, 15, 15,182, 88, 44,200,205,205, 29,188, 98,197,138, 33,238,238,238,184,112,230,184,106,226,196, 25,165, 0,102, 59,153,196,
- 88,147,201,212, 36, 54, 54,182, 67,114,114,242,174,183,222,122,139, 2,240, 4,224, 49,109,218,180,193,153,153,153,201, 40,239,
- 81,232, 72, 33,225,123,224,192, 1, 84,220, 28,148, 86,171, 21,238,238,238,136,136,136, 80,235,245,122,232,245,122,244,232,209,
-195, 93,161, 80,200, 80,222, 6,202, 17, 35,236,125,228,200, 17,184,184,184,160,180,180, 20, 22,139, 5,130, 32,128, 82, 10,153,
- 76, 6,181, 90,141, 94,189,122,121, 59, 81,144, 93, 33,132,244,157, 52,105,210,254, 85,171, 86, 53,104,214,172, 25,222,123,239,
- 61,228,230,230, 34, 57, 57, 25, 99,198,140, 41,190,114,229,202,128,234,109,179,234,129,185, 10,232,219,183,239,161,205,155, 55,
-251,237,223,191, 31,185,185,185,100,223,190,125, 20, 0, 39,147,201,126, 73, 77, 77,189, 39,109, 50, 68, 81,212, 41,149, 74,216,
-237,118,200,100, 50,240, 60, 95,245,206,243, 60,252,253,253,177,127,255,126,153,201,100,146,229,230,230,106,215,173, 91, 55, 33,
- 38, 38,198, 7, 55, 84, 57,255,211, 68, 68, 68, 4,142, 31, 63, 62, 85, 38,147,209,129, 3, 7, 62,115,237,218,181,199,253,252,
-252, 14, 31, 60,120,112, 37,128,230,206,104, 61,248,224,131, 9, 22,139,229,111, 13, 63, 61, 61, 61,171,202, 35,185, 92,142,134,
- 13, 27,174,239,221,187,119, 35, 71, 30, 44, 12, 6,195,183, 42,149,170,170,252,240,246,246,222, 21, 18, 18, 2, 47, 47, 47, 84,
-255,222,215,215,247,235,222,189,123, 7,213,135,182,141,255, 6, 56,142,131, 74,165,170,122, 85,152,162,188,238,221,187,227,207,
- 63,255,220,226,140, 41,162,148, 90,229,114,121,149, 78,229, 75,165, 82,129,227, 56,169, 14,215,146, 91, 69,115, 5,226,200,242,
-189,134, 82,250,144,139,139,139,226,198,239,243,243,243, 21, 45, 91,182,236,225,168,142, 90,173,246,212,104, 52, 0,128, 94,189,
-122, 33, 43, 43, 75, 12, 14, 14,126, 97,228,200,145,118, 0,120,245,213, 87, 95,200,202,202,202,179,219,237,188, 76, 38, 67,118,
-118, 54,154, 54,109,234,121, 23,203,218,155,122,144,127,189,193,170,120, 34,167,213,223,171, 29,204, 90, 35, 87,149,191, 57, 82,
- 69, 40, 73, 18,189, 69, 47,194, 42, 51,119, 39, 13,150,187,187, 59, 70,143, 30,173, 77, 75, 75,251,194,217, 2,188,218,129,247,
- 9, 10, 10,218, 31, 23, 23,215, 56, 57, 57, 25, 83,167, 78,197,103,159,125,118, 98,201,146, 37,237, 57,142,227,186, 6, 23, 43,
-181,162,181,167, 51, 61, 8, 43,162, 97,113,187,118,237,154,215,166, 77,155,119,252,253,253, 93, 31,124,240,193,227, 54,155, 77,
- 63,121,242,228,254, 3, 7, 14,236,219,169, 83,167, 76, 0, 95, 59,168, 7, 73,146,176,103,207, 30,184,186,186, 66,175,215,195,
-221,221, 29,149,230,170,174, 36, 38, 38, 34, 53, 53, 21, 46, 46, 46,112,113,113,129, 78,167,131, 78,167,131, 82,169, 68,229,197,
-233,100,225,112,137, 16, 50,115,199,142, 29,235, 23, 45, 90,132,130,130, 2,152, 76, 38,204,155, 55, 15,137,137,137, 51, 41,165,
- 39,235,147,185, 26, 48, 96,192,225,205,155, 55,251, 70, 70, 70, 34, 53, 53, 21,123,246,236, 73, 17, 69,241, 29,149, 74, 53,246,
-218,181,107,247,236,230, 42,138,162,130,231,121,112, 28, 7,142,227,254, 22,193,170, 52, 91, 26,141, 6, 13, 26, 52,192,156, 57,
-115, 20,195,134, 13, 27,120, 47,243,243,195, 15, 63,108,186, 98,197,138,213,235,215,175,223,247,220,115,207,109, 63,125,250,244,
-115,122,189,254,204,129, 3, 7,150,168, 84, 42,167,111,140,118,187,221, 55, 38, 38,230,186,118,159,162, 40, 66, 20, 69, 8,130,
- 0,187,221,142,101,203,150, 97,248,240,225,186,138, 7, 73,193,129,243,211,123,237,218,181, 32,132,224,243,207, 63,175,122,200,
-172,174,185,116,233, 82, 12, 27, 54,204,213, 81, 77,102,174,184,235,140,144, 70,163,185,206, 28,213, 5, 65, 16,124, 85, 42, 85,
- 70, 69,213, 32, 84, 42, 21, 98, 98, 98,156,142, 94, 85, 59,238, 39,157, 89,190,151, 84,150,195,118,187,253,111,223,183,104,209,
-194, 97, 29,157, 78, 71, 42,239,177,118,187, 29,233,233,233,226,233,211,167,197, 46, 93,186, 0, 0,252,252,252,196,200,200, 72,
-209, 98,177,240,149,247,107, 55, 55,183,187, 98, 50,107,242, 32,247, 69, 4, 11,192,239, 55,188, 87, 21, 46,149,134,231, 86,145,
-171,202,101, 7,219, 96, 65, 38,147, 97,199,142, 29, 85,237,176, 58,118,236, 88,101,230,110,212,189,177,209,188, 51, 40,149, 74,
-184,185,185, 97,223,190,125,230,248,248,248,201,206,252,119,203,187,173, 1,177,188, 19, 86,163, 70,141,126,136,139,139,107, 92,
- 90, 90,138, 47,191,252, 18,209,209,209,151, 41,165,131,171,162, 93,125, 72,126,199, 64, 56,220,235,141, 16,210,168, 83,167, 78,
-251,199,141, 27,231,159,149,149,133, 57,115,230, 88, 22, 47, 94,220,103,221,186,117, 47,107,181, 90, 98, 52, 26,147, 59,117,234,
-148,153,144,144, 48,201,209, 30,132, 28,199,101,244,235,215, 47, 0, 0, 92, 93, 93,173, 95,125,245,149,210,221,221, 29,207, 62,
-251,172, 57, 35, 35, 67, 93,145, 31, 5,206,220, 16,100, 50, 89,246,248,241,227,189,107,201,227,108, 39, 77, 75,199, 33, 67,134,
-124,246,253,247,223, 35, 55, 55, 23, 38,147, 9, 10,133, 2, 75,151, 46, 69, 74, 74,202, 71,132,144,179,245,161, 48, 35,132, 4,
- 14, 25, 50,228,208,119,223,125,231,123,238,220, 57, 24,141, 70,124,252,241,199, 41, 57, 57, 57, 3, 41,165, 73, 0,182,223,235,
- 36,166,166,166,226,155,111,190,129, 40,138, 24, 51,102, 12, 26, 55,110, 92,101,176, 50, 50, 50,240,213, 87, 95, 65, 20, 69,140,
- 31, 63, 30,141, 26, 53,130,221,110, 87,247,238,221, 91,118,175,162, 46,211,167, 79,191,242,195, 15, 63,236, 75, 77, 77,237,183,
-100,201,146,158,132, 16,105,230,204,153,203,220,220,220,196,219, 56, 78, 40, 43, 43,131,197, 98,185,233, 43, 48, 48,208,233, 50,
-132, 16, 2,155,205,118,157,142,213,106,173,250,108, 48, 24,110,171, 92,250,175, 81, 61,114,165, 82,169,160, 84, 42,161, 82,169,
- 42, 35, 87, 4,192,207, 0,156, 50,216,148, 82,107, 96, 96, 96, 85,228,170,174,209,171,187,197,221,236,153,216,170, 85,171, 63,
-116, 58,221,192, 11, 23, 46, 92, 23,197, 26, 61,122,180,173, 89,179,102,199, 28,213,113,117,117, 45, 80, 42,149,158,102,179, 25,
-199,143, 31, 71,235,214,173, 21,133,133,133, 11, 8, 33,239, 0, 64,199,142, 29, 23,100,102,102, 42,252,253,253, 43,183,139,194,
-194,194,130,192,192,192,187,149,109, 55,245, 32,247,133,193,162,148,246,170,254,126, 99, 4,171,182,234, 65, 71, 35, 88,132, 16,
-148,148,148, 64,167,211,161, 98, 48, 51, 72,146, 84,181,173, 27,171, 8,111,167, 32, 83,171,213, 56,116,232,144,121,205,154, 53,
- 99, 40,165, 7,234, 88,128, 55,158, 50,101, 74,135,188,188, 60,172, 88,177, 2, 95,125,245,149,209,106,181, 14,189,141, 27, 66,
-163, 46, 93,186, 28, 58,114,228,136,207,229,203,151,241,230,155,111,226,236,217,179, 79, 13, 30, 60,184, 61,110, 99,160,209,168,
-168,168,170,193, 93,187,118,237, 90,164,215,235,161,211,233,144,157,157,173,208,233,116,158,135, 15, 31,118,186, 42, 43, 42, 42,
-234,142, 14,238, 74, 8,105,254,248,227,143,239,219,190,125,187, 75, 65, 65, 1,146,146,146,240,214, 91,111,225,243,207, 63,135,
- 94,175,199,238,221,187,117, 67,134, 12,249,149, 16,242, 8,165,244,252, 61, 52, 87,218,129, 3, 7,254,250,253,247,223,251,166,
-166,166, 34, 61, 61, 29,243,230,205, 75,206,200,200, 24,232,236, 56,103,119, 11, 73,146,232,180,105,211,176,118,237, 90,112, 28,
-135, 23, 94,120, 1, 69, 69,255,107,103,239,233,233,121,179,223,248,123, 25,117,145,201,100,244,200,145, 35,203,123,245,234,133,
-212,212,212,126,161,161,161,171, 95,124,241, 69,227,221,220,166,205,102,195,157,110, 66, 99,183,219, 81,207,154,229,252,171, 12,
- 86,108,108,236, 54,185, 92, 78, 1,212, 41,218, 84, 73, 74, 74,138, 71,135, 14, 29,242, 85, 42,149,242,216,177, 99, 91,234, 26,
-189,186, 75,101, 72,245,158,135, 49, 21, 70,242,150,203,148, 82,135,205, 97,203,150, 45,223,242,243,243,123,180, 75,151, 46, 56,
-119,238,156, 66,165, 82,225,185,231,158,179, 13, 30, 60,216,198,243,252,116, 39,238,143,231, 93, 93, 93,123, 86, 62, 64,252,246,
-219,111,240,240,240,120, 99,200,144, 33,147,210,211,211, 97, 52, 26,149, 21,198, 21, 28,199,225,145, 71, 30, 65, 94, 94,222, 93,
- 43,151,111,229, 65,238,151, 8,214,173,118,218,161,234, 65,103,204,144,217,108,174,170,106,114,117,117,173, 50,102,132,144,191,
-105, 58, 26, 21,187, 25,113,113,113,145,137,137,137, 43, 41,165,191, 58,251,223,202, 54, 88, 0,174,173, 95,191, 62,254,196,137,
- 19,157, 78,159, 62,125,205, 98,177, 12,188,113,196,246,234,209, 46, 71,205, 85, 82, 82, 18, 54,109,218,132,200,200,200,203,148,
-210,195,184,195,189, 38,234, 82,125,119,183, 81,171,213,175,109,219,182,205,165,160,160, 0,137,137,137, 24, 51,102, 76, 97, 82,
- 82,210,180,225,195,135,127,252,203, 47,191,184,123,122,122, 98,223,190,125,186,192,192,192, 5, 0,158,186, 87,233,108,216,176,
-225,242,111,191,253, 54,192,100, 50, 33, 43, 43, 11,111,188,241,198, 53,163,209, 56,168,190,152, 43, 0,136,137,137,113,123,252,
-241,199,127, 6,208,235,220,185,115,144, 36, 41, 50, 54, 54,182,170,199,108, 77,191, 57,226,223, 76, 38,147, 76,171,213, 10,183,
- 56,183,228,206, 70, 28,170,107,254,249,231,159,203,150, 45, 91,246,227,140, 25, 51, 18,111, 83,179, 86,163, 99,181, 90,113,167,
- 53, 43,122,186, 50, 28,164, 50, 98,117,254,252,249, 74, 99,245,202,157, 50, 66,149, 17,172,255, 18, 27, 54,108, 48,126,249,229,
-151, 33, 1, 1, 1, 31, 62,255,252,243,189, 12, 6, 3,167, 84, 42,255,224,121,126, 38, 0,135,103, 19,209,104, 52, 19, 60, 60,
- 60, 78,243, 60,207,167,165,165,225,226,197,139,224,121, 30,148, 82,101, 89, 89, 25,124,124,124,170,122,198,143, 30, 61, 26, 1,
- 1, 1,226,249,243,231, 39,176, 51,250, 14, 26, 44, 0, 88,184,112, 33,126,186,114, 5,143, 7, 7,215,184,222,142, 29, 59,110,
-102, 42,254, 54,219,182,221,110, 71,120,120,120,213,242,143, 63,254, 88,101,176, 38, 77,154,116,221,255,119,238,220,233,144,230,
-205,184,124,249,114,127, 39,158, 56,110,170, 89, 81, 41,252, 80,116,116,116, 99, 0,105,148, 82,107, 93, 53, 13, 6,195,178,223,
-127,255,221, 39, 41, 41, 9,235,215,175,199,154, 53,107,140,102,179,217,169,104,152, 35,251, 46,151,203, 51,122,244,232, 17, 80,
- 81,184,213, 90, 45,248, 79,205,178,110, 54,155, 17, 25, 25, 9, 0, 24, 55,110, 92, 97, 82, 82, 82, 95, 74,233, 57, 66,200,249,
- 65,131, 6,237,251,249,231,159,221, 43, 86,205,187, 87,233,148,203,229, 61,215,172, 89, 51,200,213,213,149,251,233,167,159, 44,
- 83,167, 78, 77, 73, 73, 73, 25,230,204, 52, 72,255, 84,126,102,102,102, 78,153, 48, 97,194,167, 22,139,133, 55,155,205, 83, 28,
-253,173,182,116,126,255,253,247,137,205,154, 53,235,137, 91, 15,155, 32, 1,136,186, 29,205, 21, 43, 86, 0, 64,139,219,209,188,
- 29, 51,244, 79,107,222,201,227,254,111,211, 76, 79, 79,223, 83,113,159,113,202, 88, 57,146,206,168,168,168, 29, 21,218,191, 58,
-162,253, 79,237,251,237,246, 76,172, 45,157,227,199,143, 79, 3, 48,250,118,210,185,119,239,222,107,207, 60,243,204,226,246,237,
-219,191,173,211,233,144,144,144, 80, 53, 44, 82,229, 3, 58, 33, 4, 35, 71,142,196,196,137, 19,177,127,255,254,197, 79, 63,253,
-244,181,187,157,159,255, 25,131, 37,151,203,147, 19, 19, 19, 27,111,216,176,129, 43, 36, 4,223, 84, 12, 68, 86,209, 69, 29,149,
-141,108, 43, 93,238,161, 67,135, 4,165, 82,153, 84,203,205, 63,249,196,137, 19,141,190,252,242, 75,153,139,139, 11,212,106, 53,
- 46, 93,186, 4,153, 76,134,107,215,174,225,187,239,190,187,174,209,238,254,253,251, 69,141, 70,243,143,143,234, 93, 61, 42, 85,
- 17,190,189, 82, 91,180,235,235, 90, 2,155,110,110,110, 29,206,156, 57,131, 29, 59,118, 96,205,154, 53, 70,147,201,212,167,174,
-243, 23,214,196,159,127,254,217,178,158,158,107,239,247,234,213, 75, 2,224, 5,224, 61, 74,233,229,138,252, 61, 71, 8,233,221,
-178,101,203,215, 1,104, 0,188,127,175, 18,200,243,252,140, 71, 30,121,132,159, 58,117,106,230,214,173, 91,127,203,206,206,158,
- 78, 41, 53,213,199,204,140,142,142,190, 10, 96,144,179,191,213,198,168, 81,163,174,212,116,190,215, 23,205, 74, 51,164, 80, 40,
-192,113, 92,229,244, 30, 80,169, 84,176, 88, 44, 48,155,205, 48,153, 76, 78, 87,231, 85, 70,237, 85, 42, 85,213, 16, 53, 74,165,
- 18, 10,133, 2, 10,133, 2,101,101,101,172,138,208, 57, 94,254,151,106,215,153,127, 75,207,196,205,155, 55, 47,154, 52,105,146,
-172, 91,183,110, 51,195,194,194,184,171, 87,175, 34, 59, 59, 27, 60,207,163, 69,139, 22,232,223,191, 63,130,130,130,164, 95,126,
-249,101,233, 19, 79, 60,177,136,157,202,119,208, 96,137,162,216,103,198,140, 25, 7, 45, 22,139, 67,109,113, 52, 26, 77, 90,105,
-105,105,159, 90, 78,188, 62, 17, 17, 17, 7, 63,249,228,147,198,213, 76, 87,153,221,110,127,123,210,164, 73, 31, 8,130,160,185,
- 65, 51,213,102,179, 61,114, 79,114,134,211,228,141,234, 67,172, 55,155, 50,231,198,101, 71,228,206,157, 59, 55,125,192,128, 1,
-239,153, 76,166,124,187,221, 62,238,110,152,171,250, 12,165, 52, 27,192,180, 91,252,118, 25,192,148,123,157, 70,171,213, 58,181,
-101,203,150, 43, 68, 81, 92,102,183,219,143,178,226,161,254, 34,151,203, 51,186,118,237, 26,224,192,122, 14,119,238,184, 27,154,
-140,255, 38,255,150,158,137,171, 86,173, 90, 48,125,250,244, 77, 65, 65, 65, 95,246,236,217,179,101,179,102,205, 92, 93, 93, 93,
- 81, 84, 84, 84,146,151,151,151,240,211, 79, 63,141,123,241,197, 23,217, 4,231,119,218, 96, 69, 69, 69,101, 1,104,123, 39, 55,
- 86,139,230, 23,245, 38, 87,122,158,243, 0,128, 45, 55, 52,141,175,109,185,150, 11,110, 55,128,221,236,148,171,215,133, 98, 50,
-128, 97, 44, 39,234, 63,119, 35, 82, 91,143,163,191, 12,198, 93, 99,249,242,229, 87, 1, 60, 2, 0, 35, 71,142,228, 1, 96,235,
-214,173, 98, 61, 76,106, 24, 0,111, 0,149,189,215,189, 1, 88, 81, 30,228,200, 6, 16,253,175, 49, 88, 12, 6,131,193, 96, 48,
-254, 59,212, 83, 99, 85,137, 55, 33,100, 55,165,116, 8, 0, 84,126,174,254, 93,125,131, 99,167, 20,131,193, 96, 48, 24, 12,198,
-157,133, 0,104,127,179, 31,156,233, 29, 64, 8,105,239,236,134, 29,152, 49,156,105, 50, 77,166,201, 52,153, 38,211,100,154,247,
-153,102,109,218,183,248,255,224, 90, 34, 88,123,234,157,193,186,155, 61, 98, 88,215,101,166,201, 52,153, 38,211,100,154, 76,147,
-105,222, 1,254,117, 6,139,181,193, 98, 48, 24, 12, 6,131, 81,223, 41,155, 61,123,246, 92, 66,200,110, 0,152, 61,123,246,220,
-250,158, 96,102,176, 24, 12, 6,131,193, 96,212,119,142,133,135,135,155,194,195,195, 43, 27,180,103,163,188, 22,110, 8,254,215,
-179,240,223,109,176,102,247, 9,126,208, 16,104,248,170, 48, 55, 55, 94,178,150, 76,156,247,107,106,126, 93, 54, 76, 8,241, 84,
- 42,149, 35,180, 90,237, 35,148,210, 96,158,231, 47, 20, 21, 21, 29,178,219,237, 91, 41,165,165,236, 92, 98,220,107, 66, 66, 66,
-218,201,229,242,233,132,144, 48, 65, 16,252,229,114,121, 58, 33, 36,218,106,181,126, 18, 19, 19, 19,207,114,232,254, 37, 52, 52,
-116, 7,165,180,127, 69, 89,245,107, 76, 76,204,147, 44, 87, 24,140,123,138, 21,192,137,127, 83,130,157, 54, 88,132,210,103,198,
-189,252,130,161, 32, 37,193,176,113,243,222, 22,239, 13,106,220,127,222,207, 73,153,206,104,104, 52,154, 17,237,218,181,251,232,
-211, 79, 63,245,108,210,164, 9,209,104, 52, 72, 79, 79,111,121,242,228,201,161,243,231,207,159, 43,151,203, 95,181,219,237, 7,
-111,103,199, 8, 33,110, 94,174,178,233, 57, 69,246,119,217,121,201,112,134,145, 35, 71,242, 41, 41, 41,111,123,122,122, 78,157,
- 53,107,150, 42, 56, 56, 24, 58,157, 14, 89, 89, 89,129, 23, 47, 94, 12, 88,181,106,213,160, 30, 61,122, 68, 40, 20,138,249,135,
- 15, 31,102, 3, 78,222, 7,116,235,214,173,161, 32, 8, 43, 9, 33, 74,158,231,103, 82, 74,251,239,221,187, 23,162, 40, 98,240,
-224,193,253,187,117,235,214, 76, 20,197,165, 90,173, 86,178, 88, 44, 19, 43,198,244, 99,252,203,233,218,181,107,146, 40,138,222,
-142,174,175, 84, 42, 83,143, 29, 59,198,198, 75, 99,220, 29,131,197, 83,252,186,103,251,150, 23, 30,127,184, 21,121, 97, 88,151,
-102,155,126,140, 61, 52,163, 95,211,126,203,246, 37, 58, 52,165,141, 86,171,157, 52, 97,194,132, 5, 11, 22, 44, 80, 95,184,112,
- 1,103,207,158,133, 32, 8,112,117,117, 69,251,246,237,185, 61,123,246,248, 78,153, 50,229, 91,165, 82, 57,193,106,181,238,170,
-235,142,249,120,242,139, 92,213,178, 81, 42,153, 44,218, 34, 8,123,234,233,197,253,147,221,110, 95,246,215, 95,127,253,254,111,
- 57, 97,194,194,194, 30,144,201,100,115,149, 74,229,176,251,213, 92, 92,187,118,109,238, 67, 15, 61, 52,117,254,252,249,170,171,
- 87,175, 34, 33, 33, 1,233,233,233,104,210,164, 9,154, 52,105, 66, 86,174, 92,169,254,244,211, 79, 39,196,199,199,115, 0, 28,
-110, 7, 64, 8,225,252,252,252,198, 62,250,232,163, 79,120,121,121,233,211,211,211,139,142, 29, 59,182, 59, 45, 45,237, 43, 74,
-105,157,242,146, 16,194,121,123,123,143, 25, 60,120,240, 19, 30, 30, 30, 30,233,233,233,249, 7, 15, 30,220,157,149,149,181,190,
- 98,154,167,186, 62,160,248,162,188,135,177,103,197, 87, 25,193,193,193,231, 18, 19, 19,179,239,160,102,122,112,112,240,249,186,
-104, 62,240,192, 3, 6,155,205,182, 7, 64,243, 91,173, 67, 41, 61, 47,151,203, 7, 59, 98,134, 4, 65, 88,249,225,135, 31, 14,
-118,117,117,197,172, 89,179,226,131,130,130,160,215,235,177,102,205, 26,120,120,120, 64, 20,197,248,143, 62,250,136,164,164,164,
-224,147, 79, 62, 89, 13, 96, 56,187,125, 56,116,204,191, 1,224, 14, 96, 44,165, 52,183,218,247, 94, 0,190, 7,144, 77, 41, 29,
-125,175,210, 39,138,162,247,145, 35, 71,160, 82,169, 32, 73, 18, 36, 73, 2,165,180,234,189, 58, 54,155, 13,253,251,247,247,101,
- 71,149,225,240,249, 95, 83, 47,194, 57,125,154,188,210,190,115,151, 15, 20, 74,153, 70, 18,237,144, 4, 59, 68,187, 21, 60, 21,
-208,182,137, 59,154, 54, 84,162,164,184, 4, 27,247, 93, 42,206, 45,195,195,139,126,190,112,169,150,139, 45, 40, 44, 44,236,248,
-225,195,135,245,191,253,246, 27, 46, 92,184,128, 69,139,202,167, 56,114,113,113,193, 47,191,252, 82, 57,163, 55, 6, 12, 24,144,
- 99, 52, 26, 59, 83, 74,243,235,112, 81, 55,122, 56, 52,224,207, 29, 31, 61,236,209,110,248,182,228,140, 60,107, 59, 74,105,189,
- 27, 64, 45, 36, 36,196, 36,151,203, 77, 86,171,117,196,191,193,100,133,133,133, 61,192,243,252, 78,187,221,174,213,233,116, 94,
-135, 15, 31,182,220,111, 23, 68, 72, 72, 72, 59,119,119,247,195, 59,119,238, 84, 71, 70, 70, 34, 63, 63, 31, 89, 89, 89,152, 58,
-117, 42, 86,175, 94,141,118,237,218,193,197,197, 5, 74,165, 18,147, 39, 79, 46, 51,153, 76,253,163,162,162,226, 28, 49, 66, 15,
- 63,252,240,215,155, 54,109,106,108,183,219, 57,160,124,226,243,228,228,100,113,238,220,185, 41,177,177,177, 47, 58,107,178, 8,
- 33, 92,143, 30, 61,214,109,218,180, 41, 88,169, 84,114,130, 32, 64,146, 36, 92,188,120, 81,124,251,237,183,175,197,198,198,190,
- 84,151,243,158, 16,210, 81,171,213,182,154, 60,121,114,238,176, 97,195,108, 0, 16, 23, 23, 71,226,226,226,220,130,130,130,174,
-205,155, 55,239,100, 29, 52, 59,107,181,218, 22, 83,166, 76,201, 25, 52,104,144,160, 84, 42,165,200,200, 72,254,212,169, 83,110,
-193,193,193, 87,230,206,157,235, 84,111,164, 46, 93,186,156,252,236,179,207,252, 3, 2, 2, 68, 66, 8,173,216, 6, 37,132, 80,
-142,227, 40, 0,156, 63,127, 94,254,230,155,111, 38,199,197,197,133, 58,112,220,119,142, 30, 61,186,111,199,142, 29,209,170, 85,
- 43,240, 60,143,132,132, 4, 92,190,124, 25,106,181, 26,237,219,183,135, 70,163,193,174, 93,187,240,221,119,223,237,143,141,141,
-125,130,221, 62, 28, 58,238, 71, 0,132, 2, 56, 7, 96, 32,165, 52,183,194, 92,237, 5,208, 26,192,113, 74,105,159,123, 89, 6,
- 71, 70, 70, 98,231,206,157, 80, 40, 20,144,203,229,200,205,205, 69, 80, 80, 16,100, 50, 25,228,114, 57,228,114, 57, 20, 10, 5,
- 2, 2, 2,240,216, 99,143, 9,209,209,209,122,118,100, 25,183, 29,193,242,243,109,240,214, 83, 79,245,209, 64, 20, 0, 91, 41,
- 96, 51,129,218, 74, 65,173, 38, 16,165, 6,212,110,134, 11,159,139, 87, 31,107,232,186,253, 88,102,220,156, 71,155, 60, 25,126,
-240,234,254, 91,233,233,245,250,217,107,214,172,209,159, 58,117, 10, 9, 9, 9,248,248,227,143,177, 96,193, 2, 40, 20, 10,228,
-231,231, 99,232,208,161, 56,118,236, 24,172, 86, 43,254,239,255,254,207, 99,246,236,217, 19, 0, 56, 61,201,164,175,167,108,197,
-150,141, 43, 61, 60, 53, 57,120,105,104,180,231,170,173, 73,175, 0, 88, 93, 31, 15,192, 91,111,189,165, 93,186,116,233,182,206,
-157, 59,215,107,147, 21, 22, 22,246,128, 66,161,216,249,206, 59,239,184,188,243,206, 59,226, 29,210,108,195,113,220, 70,171,213,
- 58, 59, 62, 62,254, 64,125,216, 79,133, 66, 49,233,205, 55,223, 84,167,164,164,160,160,160,160,234,201,182, 18,149, 74, 5,142,
-227,160, 84, 42,241,252,243,207,171,215,173, 91, 55, 5,192,216,218,116,253,252,252,198,126,243,205, 55,141,109, 54, 27, 87, 82,
- 82, 82, 53,129,112,135, 14, 29,248,153, 51,103, 6, 76,155, 54,109, 60,128, 8,103,210,234,233,233,249,236, 55,223,124, 19,172,
- 84, 42,185,244,244,116, 60,248,224,131,136,140,140, 68,183,110,221,248,183,222,122, 43,112,202,148, 41, 47, 1, 88,235,108,148,
- 73,171,213,182, 57,122,244,104,170,191,191,127,213,247, 77,155, 54,165,131, 6, 13,202, 59,119,238, 92,139,152,152,152,188,208,
-208,208, 84, 39, 52, 13, 90,173,182,229,190,125,251, 50, 22, 44, 88,240,200,234,213,171,135, 0, 64,215,174, 93,247,132,135,135,
- 31,202,206,206,110, 29, 25, 25,153,215,189,123,119,163, 19,154,205,252,252,252, 74, 38, 77,154,164,187,213, 58, 95,127,253,117,
- 30, 33,164,181, 35,122, 60,207, 79,223,188,121,243,201,252,252,124, 89,108,108, 44,212,106, 53, 52, 26, 77,213,123, 70, 70, 6,
-172, 86, 43,182,108,217, 34,112, 28, 55,131,221, 58, 28,102, 20,128, 95, 1,180, 1,240, 11, 33,228, 57, 0,223, 2,104, 5,224,
- 18,128, 49,247, 58,129,146, 36, 65, 46,151, 67, 38,147, 97,207,158, 61,136,136,136,192, 15, 63,252, 0,131,193, 80,101,176,100,
- 50, 89,229,121,199,142, 40,195, 57,131, 69, 8,161,148, 82, 82,249, 94,249, 99,122,122,214,242,245, 17, 95, 45, 82,202, 57,121,
-159, 30,173,224,161, 18, 64,180,158, 80,244,154, 13,226, 30, 4, 0,160,121,137,176,254, 58, 27, 35, 59,231,112, 27,109,228,251,
- 15,135,182,108,244,214,143, 9, 37,183, 40, 20,187, 54,106,212, 8,191,255,254, 59,154, 52,105,130,119,222,121, 7,173, 91,183,
-134, 86,171, 69,102,102, 38, 74, 75, 75,225,226,226, 2, 81, 20,209,165, 75, 23, 94,167,211, 61,236,172,193, 34,132,116, 26, 55,
-170, 91,168, 76,223, 10, 15, 14, 24,143,125,171,122,185,172,223,147,254, 38, 33,100, 35,165,212, 84,223, 14,192, 19, 79, 60,129,
-204,204, 76,237,166, 77,155,234,108,178,186,118,237,250,147, 40,138,143,214,182,158, 90,173,254,253,232,209,163, 3,235,106,174,
-214,173, 91,231,226,238,238,126, 71, 10,153, 10,115,245,219, 11, 47,188,224,250,205, 55,223,108,238,212,169,211, 51,245,193,100,
- 17, 66,186, 7, 7, 7, 35, 57, 57, 25,153,153,153,176, 88, 44,200,204, 44,111, 98,152,154,154,138,128,128, 0,120,120,120, 32,
- 32, 32, 0, 45, 91,182, 36, 28,199,133, 57,162,219,171, 87,175, 33, 0,184,196,196, 68,100,103,103, 67,175,215, 67,167,211,193,
-223,223, 31,143, 60,242,136,172,105,211,166,253,157, 53, 88,253,251,247,127, 66,171,213,114,201,201,201,184,122,245, 42, 44, 22,
- 11, 46, 93,186, 4,119,119,119, 60,246,216, 99,242,224,224,224,129,206, 26, 44, 0,109, 39, 76,152,144, 93,221, 92, 85,226,226,
-226, 66,218,180,105,147,239,234,234,218, 5, 64,170, 51,154, 83,167, 78,205, 10, 15, 15,239,185,127,255,254,233,149, 95,238,223,
-191,255, 13, 0,248,252,243,207,143,186,185,185,117, 1, 96,116, 38,161,148, 82,105,252,248,241,151,149, 74,101,149, 97,173,252,
-172, 84, 42,193,113,156,155, 35, 58,149, 13,218,219,183,111,143,137, 19, 39,226,135, 31,126,192,134, 13, 27,170,126,127,234,169,
-167,240,228,147, 79,162,164,164, 4, 62, 62, 62, 50,163,209,120, 38, 52, 52,180, 94, 52,124, 39,132,132, 0, 88, 12,192, 6, 96,
- 62,165,180, 94,205,199, 70, 41,205, 34,132,244,175,102,178,142, 3, 80, 85,152,171,254,148,210,123,222,150, 77, 20, 69,200,229,
-114,164,164,164,224,203, 47,191,196, 43,175,188,130, 14, 29, 58,160,176,176,176,202, 96,201,229,114,112, 28,155,248,228, 46,158,
-199, 55,245, 32,247,117, 4, 75,213, 51, 57,226,234,159, 92,135,145,143,247, 24,227,169,215, 64, 42, 54, 66,241,216,124,156,202,
-211,226,147,136, 95, 1, 0,211, 70,116, 65,251,190,239,195,242, 85, 63, 60, 26,100, 85,126,245,151,250, 13, 0, 11,110,166,231,
-237,237,237, 37, 8, 2, 56,142,131,139,139, 11, 60, 61, 61,161,209,104,144,147,147,131,215, 95,127, 29,123,247,238,133,213,106,
-133, 66,161, 64,112,112, 48,108, 54, 91,176,179, 59,228,227, 33, 91,245,201, 71,139,220,114, 19,191, 67,236,133, 2,104,221, 2,
-240,246, 43, 33,238,239,173,142,157, 11,224,237,250,120, 16,218,182,109,139,215, 95,127, 93,251,233,167,159,214,201,100, 81, 74,
- 23,203,100,178,238, 51,102,204,208,140, 24, 49,226,111,191,159, 61,123, 22, 19, 39, 78, 44, 51,153, 76, 75,234, 98,174,228,114,
-249,206, 47,191,252,210,197,205,205, 13,201,201,201,119,204, 92,173, 92,185,210,181,105,211,166,144,203,229,234,175,191,254,186,
- 94,152, 44, 65, 16, 2,180, 90, 45,114,114,114, 48,109,218,180,235,218, 97, 84, 86,103, 3, 64, 66, 66, 2, 2, 2, 2, 96, 54,
-155, 13,142,232,122,121,121,185, 83, 74,241,242,203, 47, 35, 37, 37,165,234,123,131,193,128,212,212, 84, 8,130,224,225,108, 90,
- 61, 61, 61, 61,236,118, 59, 30,126,248, 97,152,205,230,242,112,193,168, 81,144,203,229,200,202,202,130,221,110,247,172, 67, 22,
-120, 13, 26, 52, 40,253, 86, 63,234,116, 58,187,167,167,103, 35,103,147, 58,120,240, 96,227,170, 85,171, 6,223,248,195,137, 19,
- 39, 6,187,185,185, 29,244,242,242,106, 81,151,224,131, 74,165,130, 82,169,132, 92, 46, 71,229,231,202, 23,207,243,146,131,215,
- 79,255,189,123,247, 66,175,215, 35, 42, 42, 10, 26,141, 6, 0, 48,100,200,144, 25, 58,157,174,167,217,108, 30,182,123,247,110,
- 20, 20, 20, 32, 56, 56, 24, 13, 27, 54, 68, 84, 84, 84,255,122, 82,124,124, 0,160,123,197,231, 21,213, 62,215, 55,147, 53, 6,
-192,209, 10,115,101, 5, 48,186, 62,152,171,234, 17,172, 37, 75,150, 64, 16, 4, 28, 59,118, 12, 35, 71,142, 4, 33, 4,132, 16,
-232,245,122,172, 88,177,130,185, 32, 70,221, 12,214,205,156,227,123,239, 17,206,242,103,227,213, 35, 7,119, 31,211, 38,192, 5,
-150,156, 68, 40,117, 94, 32,238,141,241, 73,196,175, 56,151,148, 7, 0,248,100, 91, 28,214,207,233, 15,162,245,132, 95,217, 5,
-232,149,170,161,183, 50, 88,185,185,185, 37, 54,155,205, 67,163,209, 84, 61, 21,228,228,228,224,221,119,223,197,150, 45, 91,208,
-184,113, 99, 8,130, 0,165, 82,137,236,236,108,200,229,114,167,122, 39,202,100,100,192,252,169, 3, 27,187,120,181, 64,110,220,
-123,229, 95,234,187,224,149, 81,156,114,217,198,211,207, 18, 66, 86, 80, 74,235,221,120, 25, 58,157, 14, 29, 59,118,196,179,207,
- 62,171,221,180,105,211, 90,212,208,112,247,102, 68, 71, 71, 31, 15, 11, 11, 27,186,124,249,242, 31,211,211,211, 53,157, 59,119,
-134, 78,167,131, 78,167, 67, 98, 98, 34, 22, 44, 88, 96, 54,155,205, 79,213, 37, 58,198,113, 92,196,184,113,227, 92,244,122, 61,
- 18, 19, 19,225,233,233,121, 91,251, 26, 22, 22,214,134,231,249,223, 86,174, 92,233,218,172, 89, 51,156, 63,127, 30, 33, 33, 33,
-240,245,245, 85,135,135,135,223,115,147,165, 80, 40,210,178,179,179,155, 6, 6, 6, 98,221,186,117,224, 56, 14, 70,163, 17,111,
-191,253, 54,194,195,195,209,189,123,119,232,116, 58, 4, 6, 6,226,210,165, 75,208,104, 52, 25,142,232,166,165,165,229, 3,240,
-254,229,151, 95,144,147,147, 83,245,125,163, 70,141,144,151,151, 7,171,213,154,231,108, 90,141, 70, 99, 30,128,134,241,241,241,
-184,122,245, 42, 6, 14, 28,136, 93,187,118, 33, 36, 36, 4,162, 40,194,110,183,231,213, 33, 11, 68,158,231,107,154,222,129, 0,
-112,214, 12, 10, 50,153,140,214,240,244, 90, 23, 77, 72,146, 68,111,101,174, 20, 10, 5,106,218,230,205,162, 24,107,214,172,169,
-170, 22, 4, 0,185, 92,222,125,250,244,233,195,110,245, 80, 84, 79,168, 30,165,171,151,157, 78, 8, 33,222, 0,190, 1,160,172,
-136,180, 41, 1,108, 32,132, 12,172,222,240,253, 94, 26, 44,158,231,171,150, 93, 92, 92,208,177, 99,199, 42,131,101, 50,153, 32,
-151,203,153, 91,184,187, 38,252,190,139, 94, 1, 21,147, 61, 87, 15,207, 93,103,174, 6,134,142,105, 29,160,198, 95,113,167, 33,
-179,230,129, 90,138,106, 40,161,236, 32, 10, 23,232, 93,100,254, 53, 92,104,241, 73, 73, 73,112,119,119,135, 66,161,128, 74,165,
- 66,251,246,237,113,252,248,113,180,104,209, 2,162, 40, 86, 21,148,103,206,156,129, 32, 8, 71,157,184,136,249, 6,122,217, 71,
-111,205, 93,160, 67,218, 58,184,187,170,240, 72,247,102,128, 75, 27,240,114, 21,150,255,223,227, 30, 62, 13,220, 62,172,143, 7,
- 65,167,211, 33, 45, 45, 13,223,125,247,157,201,108, 54,191, 92, 23,141,232,232,232,227,162, 40, 14,221,186,117,107, 89, 82, 82,
- 18,212,106, 53, 46, 94,188, 88,105,174,158,172,107,251, 46, 73,146, 38,172, 93,187,182,116,247,238,221,208,233,116,112,117,117,
-189,237,200,213,235,175,191,174,107,222,188, 57, 18, 19, 19,225,230,230, 6, 47, 47, 47,244,236,217, 19,159,126,250,169, 90,167,
-211,109,238,212,169,211, 61,107,244, 42, 73, 82,212,165, 75,151,168,155,155, 27, 90,182,108,137,118,237,218,161,107,215,174, 0,
-128,202, 6,208, 77,154, 52, 1, 0, 92,190,124, 25,148,210, 24, 71,116,143, 30, 61,186, 59, 33, 33, 65,244,243,243, 67,135, 14,
- 29,208,165, 75, 23,116,235,214, 13, 65, 65, 65,248,226,139, 47,108,215,174, 93,219,235,108, 90, 15, 30, 60,248,211,233,211,167,
- 5, 63, 63, 63,132,132,132, 64,165, 82,161, 93,187,118,240,243,243,195,154, 53,107,108, 73, 73, 73,123,235,144, 5,169, 39, 79,
-158,228,111,245,163, 70,163,113, 5,224,108,228,193,120,226,196, 9,174, 71,143, 30,127,235,205,219,181,107,215, 61, 26,141,198,
- 13, 64,134,179, 9, 37,132, 72, 74,165, 18,106,181,250, 58,115,165, 84, 42,161, 82,169, 32,147,201, 28,237, 69,185,103,240,224,
-193,216,189,123, 55,212,106, 53,180, 90, 45,134, 15, 31, 14,179,217,252, 20, 0, 44, 94,188,184,234,102, 59,127,254,124, 0,128,
-201,100,170, 47, 29, 60,102, 2, 56, 3,224, 10,128,255,171,135,230,170, 33,202,171, 7, 91,160,188, 90,176,103,197,123,101,155,
- 44,175,122,112,115,135, 66,161,192,194,133, 11, 33,151,203,225,235,235,139,185,115,231,226,157,119,222,193,252,249,243,177,116,
-233, 82,120,120,120,176, 42,194,187,123,158, 92,231, 65,238, 43,131,117, 35,214,200,160,121, 35, 6,116, 30,211,218, 95,133,248,
-184, 51,248,233, 68,250,197,156,156, 2, 72,153,167, 33,101,159,199,180, 17, 93,208,166,177, 39,218, 52,246,196,180, 17, 93, 32,
-101,157, 1,205, 79, 4, 85,123, 34,187,132,220,178,122, 33, 47, 47,239,147, 5, 11, 22, 20,120,120,120, 84, 21,138,169,169,169,
-104,219,182,237,117,133, 36,207,243,120,247,221,119,115,178,178,178,214, 57,108, 82, 52,252, 75, 75,254,239,153,134, 10,149, 43,
-144,247, 59,244,122, 29,214, 69,124, 4, 88,140, 0,167,196,227,125, 58,241,126, 13,221,122, 19, 66,154,215,183,131,144,156,156,
-140,249,243,231,155, 76, 38,211,109, 53,116,143,142,142, 62,110,183,219,135,174, 89,179,166,236,231,159,127,198, 7, 31,124,112,
- 91,230,170,154,113,123, 98,195,134, 13,165,201,201,201,183,101,176,228,114,249,155,130, 32,184,126,252,241,199, 82,223,190,125,
-197,201,147, 39,139, 47,190,248,162,248,228,147, 79,138,125,250,244, 17, 39, 76,152, 32,154,205,102,149, 78,167,251,224, 94, 29,
- 11,155,205, 22, 17, 17, 17, 97,230, 56, 14, 58,157, 14, 74,165, 18,222,222,222, 85, 70,184,178,157,143,205,102,195,170, 85,171,
-202, 44, 22,203,231,142,232,230,228,228,108,152, 57,115,102,210,190,125,251,236,133,133,133, 0,128,244,244,116, 44, 90,180,200,
-182,122,245,106, 99,126,126,254, 87,206,166,181,176,176,240,155, 89,179,102, 93,251,249,231,159,237, 60,207, 35, 63, 63, 31,238,
-238,238, 88,180,104,145, 45, 34, 34,194, 88, 84, 84,228,180,102,207,158, 61, 19, 83, 83, 83, 93, 45, 22, 11,189,201,241, 35, 26,
-141, 38, 20,192, 97,103, 52,187,118,237,154,152,156,156,172,127,255,253,247,255,232,219,183,239,114,189, 94,127, 89,175,215, 95,
-238,219,183,239,199,171, 87,175, 62,162, 86,171, 67, 1, 28,170, 67,116, 85,170, 44, 51,212,106, 53, 84, 42, 85,213, 3,154, 74,
-165,130, 92, 46,119,200, 96,197,198,198,142,162,148,118, 16, 4, 65,232,208,161, 3,180, 90, 45,158,124,242, 73, 40, 20, 10, 0,
-192,236,217,179, 65, 41, 5,165,180,202, 96,149,148,148,212, 11,131, 69, 41,253,131, 82,218,141, 82,218,158, 82, 90, 31, 59,201,
-108,170,102,174,250, 83, 74,207, 2,232, 95,205,100,109,169, 15, 6, 75, 46,151,163,117,235,214,152, 54,109, 26,118,237,218,133,
-164,164, 36, 8,130, 0, 81, 20,193,113, 28,100, 50, 25, 51, 88, 12,167,169,170, 34,172,254,238,235,238,242, 92, 27, 63, 25,226,
-227,207,225,199,152,188, 77, 28,199,239,138,187,106,217,222, 63,184, 24,182, 45,163,209,126,228, 55, 88, 63,167,188, 9,130,148,
-117, 6,182,173,207,129,104, 27,224, 82,145, 22, 38, 91,254,222, 26, 78,228, 24, 79, 79,207,109, 27, 55,110,124, 97,236,216,177,
- 74, 73,146,160,209,104, 48,125,250,116, 80, 74,171,204,213,196,137, 19, 75,179,178,178, 62,165,148, 38, 58,232,126, 53,254,222,
-202, 89, 99, 94,126, 91,141,148, 8,128, 83, 32, 7,157,209,241,225,113,200, 74, 58, 14,148,158, 3,136, 2, 17, 75,198,123, 13,
-125,241,163,207, 0,244,173, 47, 7,224,252,249,243,152, 55,111,222,109,155,171,234,134, 40, 44, 44,108,232,174, 93,187,190, 48,
-155,205,147,239,160,230, 19, 75,150, 44,217,217,176, 97, 67,151,186,234, 24, 12,134,241, 57, 57, 57, 19, 29, 88,245,158, 85,117,
-196,196,196,196, 63,240,192, 3, 95,126,252,241,199, 47, 79,157, 58, 85,173,209,104,160,215,235,145,144,144,128, 70,141,202,155,
- 30,149,149,149, 97,206,156, 57,101,130, 32,108,138,138,138,138,114,176, 16,151, 8, 33,227, 38, 76,152, 48,182, 69,139, 22,131,
- 41,165,158, 54,155, 45,239,218,181,107,123,139,138,138,234, 52, 14, 86,133,230, 75, 19, 39, 78, 28,211,188,121,243, 39,236,118,
-187,167, 32, 8,121, 41, 41, 41,123,138,138,138, 54,212, 69,243,143, 63,254,200, 89,183,110,221, 21,163,209,216,218,199,199,167,
-200,203,203,203,106, 50,153,120, 87, 87, 87, 87,165, 82,217, 25, 64, 20,128, 11,206,104, 70, 69, 69,101,173, 89,179,230,154,201,
-100,106, 17, 17, 17,113,212,221,221,253,144, 40,138, 68,169, 84,122,184,184,184,244, 2,240, 7,128,203,117, 49, 88,149, 15,102,
- 10,133,162, 42, 42, 94,185, 12, 64,114, 66,235,163, 37, 75,150,200,212,106, 53,172, 86, 43, 76, 38, 19,114,115,203,107,175, 22,
- 47, 94,140, 57,115,230, 0, 0,230,205,155,135,249,243,231,163,172,172, 76,197,110, 31, 14,145, 7, 32, 6,192,168,202, 54, 87,
-213, 26,190,111, 2, 80, 88, 95, 12,150, 92, 46,199,216,177, 99, 49,104,208,160,191, 13,211,192, 26,185,223,245, 99,112,157, 7,
-185,111, 34,115, 55, 27, 7,107,118,223,198,175, 6,184,201,223, 52, 22, 9,187,148, 15, 36,205,154, 63, 31,116,206, 99,141,119,
- 61,209,188,244,177, 54,190, 18, 64, 5, 16,125,249,205,134,150, 24, 65, 92,124,145, 47,185, 97,221,193,204, 76,202,113, 93,231,
-253,116, 49,183, 6, 51, 36,119,119,119, 95,214,188,121,243, 39, 23, 45, 90,228,214,170, 85, 43,104,181, 90, 80, 74,113,234,212,
- 41, 76,156, 56, 49, 63, 59, 59,123, 93,110,110,238,123,180,166, 65,186,170,225,237, 46, 95,184,122,254,192,215,158, 28,251,174,
- 2, 23,102, 0, 50, 55,160, 65, 31,100,144, 71,225, 43, 59, 9, 88, 51,202,191,147,187, 97,224,152,197,249,123, 15, 70, 63, 77,
- 41, 61,118,175, 51, 63, 36, 36,196,164, 86,171,239,152,185,186,219,132,133,133, 61,160, 84, 42,119, 90, 44, 22,173,139,139,203,
-125, 57, 14, 86,197,113,145,171, 84,170, 5, 10,133, 98,252,115,207, 61,167,105,213,170, 21,130,130,130,144,149,149,133,132,132,
- 4, 68, 68, 68,152, 37, 73, 90,159,151,151, 55,247,236,217,179,182,251, 49, 15, 46, 94,188,232,215,180,105,211, 48,158,231,155,
-162,124,160,200, 12, 0,251,234, 98,132, 42,185,116,233,146, 33, 40, 40, 40, 76,161, 80, 4, 87,104, 26, 1, 28,168,139,102,151,
- 46, 93, 78,206,158, 61,187,225,195, 15, 63, 92,202,243, 60, 85, 40, 20,148,227, 56, 40, 20, 10, 42,147,201, 40, 33,132,126,251,
-237,183,250,229,203,151,167, 59, 50, 14, 86,104,104,232,230, 33, 67,134, 60,174, 86,171,177,125,251,118,193,199,199, 71,230,238,
-238,142,245,235,215,223,170, 28, 3,165, 84,203,110,141,255,250,107,221,116,224,192, 1,164,164,164, 92, 55,230, 85,117, 99, 85,
-185, 76, 8, 65,143, 30, 61,132, 19, 39, 78,176,113,176, 24,117, 55, 88, 55, 99, 73,159, 96,125, 33,232,247, 29,253,233, 67,161,
- 65, 42,120,187,171,193,201, 85, 40, 50, 19,156, 53,154,113,244,124, 81,170, 40,145,167, 62,216,151,120,214,193,168, 83, 87, 95,
- 95,223,153,146, 36,181,225, 56, 78, 75, 41, 45,225, 56,238,100,122,122,250, 34, 74,233, 57,103,118,194,221,149, 63,229,225, 34,
-115, 83, 40,149, 84, 16, 68, 0, 60,192, 17,128,112, 0,184,138,119, 30, 32, 28,202,202,108, 10, 65, 36,187,178,114,114, 38,221,
-235,204,127,248,225,135,127, 42, 41, 41,249,215,141,228,174, 82,169,230,242, 60, 63,236,126,159, 38,166, 91,183,110, 93,148, 74,
-229, 76, 74,105,136,217,108,246,209,104, 52, 89,132,144,184,210,210,210,101,177,177,177, 39, 88,241,113,239,184,211, 35,185,135,
-132,132,120, 17, 66, 62,166,148,106, 57,142,123, 83,146,164, 51, 1, 1, 1,216,185,115,231, 77, 35, 88,204, 96,221, 95, 6,235,
-133, 23, 94,192, 79, 87,174,224,241,224, 91,119, 92,223,177, 99, 7, 30,124,240, 65,102,176, 24,119,222, 96, 85,152, 34, 50,243,
-145,198, 79,201, 8, 25, 78, 56,218,150, 0, 74,145,226, 18, 71,232, 1,133,202,182,118,222, 79,198,178, 27,214,111, 79, 41, 61,
-125, 71, 19,204, 52,153,230, 61,208, 36,132,112,142, 76, 61,195,242,243,254,208, 12, 9, 9,217, 82, 90, 90, 58, 56, 33, 33,225,
- 86, 26,215, 25, 44,150,159,255, 78,205, 7, 31,124,240,220,242,229,203, 3,155, 55,111,206, 17, 66,192,243, 60, 8, 33,224, 56,
- 14, 60,207, 87,189, 3,192,161, 67,135,132,247,222,123, 47,233,143, 63,254,232,200,242,243,238,104,222,111, 56, 53, 23, 97, 69,
-149,221,182,138, 23,131,241,159,225,118,230,245, 99,252,251,136,141,141, 29,101, 48, 24,142,121,121,121, 53,181, 88, 44,138,178,
-178, 50, 69,245,135, 81,141, 70,147,195,114,233,223,143, 32, 8,143,204,152, 49,227,144,217,108, 14,170,109, 93,141, 70,147, 86,
- 90, 90,218,135,229, 26,227,174, 24, 44, 6,131,193,248,175, 96, 52, 26,123,176, 92,184,191,169,168, 62,110,195,114,130,113, 55,
- 96,221, 34, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24, 12, 6,131, 25, 44, 6,
-131,193, 96, 48, 24, 12, 70,221,249,255, 1, 0, 74,212, 19,245, 82,154, 3,217, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130,
+137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 2, 88, 0, 0, 2, 0, 8,
+ 6, 0, 0, 0, 94,187, 18, 70, 0, 0, 1, 57,105, 67, 67, 80, 80,104,111,116,111,115,104,111,112, 32, 73, 67, 67, 32,112,114,
+111,102,105,108,101, 0, 0,120,218,173,145,177, 74,195, 80, 20,134,191, 27, 69,197,161, 86, 8,226,224,112, 39, 81, 80,108,213,
+193,140, 73, 91,138, 32, 88,171, 67,146,173, 73, 67,149,210, 36,220,220,170,125, 8, 71,183, 14, 46,238, 62,129,147,163,224,160,
+248, 4,190,129,226,212,193, 33, 72,112, 18,193,111,250,206,207,225,112,224, 7,163, 98,215,157,134, 81,134, 65,172, 85,187,233,
+ 72,215,243,229,236, 19, 51, 76, 1, 64, 39,204, 82,187,213, 58, 0,136,147, 56,226, 39, 2, 62, 95, 17, 0,207,155,118,221,105,
+240, 55,230,195, 84,105, 96, 2,108,119,163, 44, 4, 81, 1,250, 23, 58,213, 32,198,128, 25,244, 83, 13,226, 14, 48,213, 73,187,
+ 6,226, 1, 40,245,114,127, 1, 74, 65,238,111, 64, 73,185,158, 15,226, 3, 48,123,174,231,131, 49, 7,152, 65,238, 43,128,169,
+163, 75, 13, 80, 75,210,145, 58,235,157,106, 89,181, 44, 75,218,221, 36,136,228,241, 40,211,209, 32,147,251,113,152,168, 52, 81,
+ 29, 29,117,129,252, 63, 0, 22,243,197,118,211,145,107, 85,203,218, 91,231,159,113, 61, 95,230,246,126,132, 0,196,210, 99,145,
+ 21,132, 67,117,254,221,133,177,243,251, 92,220, 24, 47,195,225, 45, 76, 79,138,108,247, 10,110, 54, 96,225,186,200, 86,171, 80,
+222,130,251,241, 23,194,179, 79,254, 28, 9,179, 39, 0, 0, 0, 6, 98, 75, 71, 68, 0, 0, 0, 0, 0, 0,249, 67,187,127, 0,
+ 0, 0, 9,112, 72, 89,115, 0, 0, 13,215, 0, 0, 13,215, 1, 66, 40,155,120, 0, 0, 0, 7,116, 73, 77, 69, 7,217, 3, 11,
+ 22, 59, 45, 8,130,118, 25, 0, 0, 32, 0, 73, 68, 65, 84,120,218,236, 93,119,120, 84, 85,226, 61,247,181,201,180,132, 20,146,
+ 64, 40, 65,138, 72, 9, 93,138, 32, 29,130, 16, 84, 64, 84,196, 31,224,234,162,171,162,226,170, 65, 69,176,145,192, 42, 32,184,
+148,197, 93, 68, 41, 10, 22, 52, 40, 44, 69,138, 52, 33,184, 2, 34,132, 22, 4, 66, 73, 34,144, 76, 50,153,246,230,254,254,200,
+188,231,100,152,242, 6, 38, 8,120,207,247,205, 55, 51,111,222, 59,115,251, 61,247,220,251,238, 35,148, 82, 84, 23, 8, 33,105,
+148,210,125,140,147,113, 50, 78,198,201, 56, 25, 39,227,100,156,127, 38,112, 87,144,168, 17, 87,100,132, 16,234,121,245,184,222,
+ 57,171, 49,238, 52,130,156, 61, 60,156,147,111,144,112,246,184, 94, 57,149,248, 70,146,215, 59, 13, 35,149,158, 94,225,164,145,
+ 14,103,117,113, 70,186, 94, 70,178,140,250,201,247,201, 55, 72, 56,123, 92,111,156,190,229, 39, 18,188,254,202,228,213,166,167,
+159,112,210, 72,135,179,186, 56, 35,221, 95, 70,170,140, 6,201,251,136,245, 77,215, 51,132, 63, 90, 96, 0, 0,165,148,120,241,
+147,235,149,211, 59, 29, 20,254, 72,134, 53,130,216, 24,105, 78,159,244,140, 20, 38, 83, 74, 9, 33,100, 19,128, 30,145,140,123,
+ 36,242,221, 39,174, 17,225,173, 78,113, 21,201,114, 95,221,156,145,170, 75,190,156,145, 40,247,254,242,189, 26,243, 40, 82,225,
+140, 72, 93,170,142, 50,239,167,252, 92, 53,175, 47,103, 36,234,146, 47,103, 36,202,253,181,224,140, 68, 93,242,199, 25,137,114,
+ 31, 40,239,153,131,117,109,132,128,111,197,238,121, 61, 11,161,106,118,177,122,220, 8,156, 17,206,163,201, 30,206, 72,142,102,
+122, 70, 42,143,124,203, 78, 36, 70, 93,222,156,145, 42,155,126,194,121,213,249,228,143,243,106,195, 27, 32,156, 17,143,251,213,
+150,251,107,197, 25,225, 60,138, 72, 93,242,225,236, 25,225, 65, 64,207, 72,214, 37,111,206, 72,213, 37, 63,225,188,234,124,242,
+199,121,181,225, 13, 16,206,136,199, 61,130,142,104,196,121,111, 58, 7,171, 58,197, 85,117,136, 55,101,148, 20,233,142, 44,146,
+ 34,171,186,156,182, 72,185, 56,126,120, 55, 69,144,110, 99,164,195,233, 9, 31,169, 14, 33, 76, 41,157, 76, 8,153,116, 61, 87,
+104, 86,151, 88, 93,186,222,234,146,191,114,115,181,117,169,186, 6,207,222,156,145, 18, 66,126,226,126, 85,117,201,247,218, 72,
+212,165, 16,156,164, 58,226, 31,233,250,116, 61,130,187, 94, 2, 82, 13,235,123,104,117,184, 98,213, 24,239, 72,134,179,231,141,
+ 16,247,234, 8, 39, 33,100,114, 53,197,253, 70, 73, 83, 86,151, 88, 93,186,238,234,146, 79,153,236, 25, 41,103, 40,210, 3, 41,
+ 95,206, 72,174, 67,138,100, 25,173,238,184, 71,178, 46, 85, 71,222,223, 40, 8,219,193,170,174,209,241,141,192, 89, 29,220,213,
+ 20,247, 77,213, 49, 58,168,134,117, 93, 17, 15, 39,165,116, 50, 34, 56,229,168,196, 57,146, 97,173,206,105,194,234, 40,155,213,
+ 89,222, 35,185,206,163,154,226,126,163,228,123,196,195, 25,169,186,228, 39,207,175, 58,172,254,210, 47,210, 83,216,145, 44,155,
+213,201, 25, 9,238,234, 8,103,117,229,253,141, 4, 82,157,219, 52, 48, 48, 48, 48, 48, 48, 48, 48,252, 25,225,215,193, 74, 75,
+ 75,219,208,177, 99,199,166, 63,254,248,163,131, 82, 10, 66, 8, 8, 33,224, 56, 14,132, 16,184,221,238, 51,187,119,239,190,131,
+ 37, 31, 3, 3,131,166,145, 28, 33, 28,126, 95,146,224,174, 28,204,178,209, 29, 3, 3,195, 77,220,238,249,107,227, 90,183,110,
+157,247,227,143, 63,214,249,239,127,255, 11,131,193, 0,147,201, 4,147,201, 4,179,217, 12,147,201,132, 65,131, 6,157,221,178,
+101, 75,163,112,255,236,150, 91,110, 57,228,114,185,106,133,165, 0, 5,161, 48, 63, 63,191, 41,165, 84,246,247,123,237,218,181,
+ 15, 17, 66,234,134,217,216, 23, 23, 20, 20, 52,164,148,186,174, 21,103,199,142, 29,243,101, 89, 78, 12,135, 83,167,211,157,218,
+182,109, 91, 83, 86, 76,175, 13,238,184,227,142, 67, 78,167, 51,236,242, 89,167, 78,157,166,203,151, 47,247, 91, 62, 59,117,234,
+116,220,237,118, 39,104, 44, 67, 0, 0,142,227,142,239,220,185,179, 77, 32, 1,210,174, 93,187,176,203, 39,128,194,220,220,220,
+ 6,129,126,108,211,166,205, 33,158,231, 35,202,169,160,125,251,246, 98,237,218,181, 23, 0,184, 47,216,121,162, 40, 22, 95,184,
+112,161,225,198,141, 27, 93,172, 52, 50, 48, 48,220,232,240,235, 96,185,221,238,211,143, 63,254,184,105,207,158, 61,129, 28,172,
+243, 87,242,103,118,187,189,110,254,186,117, 16,146,147, 65,237,118,184,226,226, 64, 41,133,219,237, 6,159,151, 7,234,112, 0,
+ 14, 7, 92,109,218, 0, 0,156, 78, 39,218,183,111,159,148,154,154, 42, 2,144, 3,208,214, 26, 55,110, 28,162,163,163, 81, 81,
+ 81,129,138,138, 10,216,108, 54,216,108, 54,216,237,118,216,237,118, 56, 28, 14, 56, 28, 14, 56,157, 78,216,108, 54,236,217,179,
+ 39, 54, 53, 53, 85, 0, 16,168, 33,175,245,244,211, 79,195,108, 54,171,124,202,187,194,225,205,103,179,217,240,211, 79, 63, 5,
+229,148,101, 57,113,211,166, 77, 48,153, 76,112,187,221,144,101, 25,178, 44,195,237,118,195,237,118, 43,233,238,125, 62,210,211,
+211,107,177, 34,122,237, 96,183,219,235,110,121,251,109,240, 53,107,130, 58,157,112, 53,111,174,230,143,248,253,247,128,211, 9,
+234,116,194,217,175,159, 90,110,239,190,251,238,164,162,162,162,128,229,211,229,114, 37,109,122,225, 5,112,209,209,160, 21, 21,
+ 48, 14, 25, 2, 84,218, 55, 40,157, 57, 19,212,233, 4,117, 56, 96,206,204, 4,165, 20, 69, 69, 69,214,180,180,180,253,168, 92,
+167, 64, 3, 8,177, 90,235,215,175, 87,203, 12,165, 20,138, 22, 83,234, 41,207,243,234,235,135, 31,126,192,243,207, 63, 31, 84,
+220,243, 60, 95,107,244,232,209,112, 56, 28,106,221, 81, 62, 59,157, 78,181,188,187, 92, 46, 56,157, 78,216,237,118,156, 58,117,
+ 42,228,128, 65, 17, 87,245,234,213, 27, 48,125,250,116,228,228,228,224,150, 91,110,129, 36, 73,106,248,148,240, 62,251,236,179,
+177,158, 54,137, 9, 44, 6, 6,134,155, 83, 96,237,219,183,175, 55, 0, 12, 29, 58,116, 67, 90, 90, 90,211, 95,126,249,197,161,
+ 52,222,158, 87,237,135, 30,122, 40, 95,105,204, 41,165,103, 62,254,248, 99, 77, 83,134, 66,114, 50,242,227,227, 1, 0,151,114,
+115,149, 17, 59,162,219,182, 85,207,113,252,242, 11, 56,142, 67, 74, 74,138, 58,170, 15, 6,179,217,140,254,253,251, 67,167,211,
+161,125,251,246,144, 36, 9,162, 40, 6,124,105,129,209,104,196,235,175,191,174,184, 20, 48,233,163,240,183, 59, 59, 67, 79,128,
+255,252,244, 11,108,178, 27,130, 32, 64, 16, 4,205,156, 38,147, 9,159,126,250, 41, 36, 73,242,251, 90,191,126, 61,238,185,231,
+ 30, 72,146,132,248,248,120,252,153, 54,100,187, 94,192,215,172,137,211,237,218, 93, 94, 62, 7, 15,190,172,124, 38, 37, 37,105,
+ 42,159, 92,116, 52,206,222,117, 23, 0,160, 96,243,102,232,116, 58, 72,146,132,152, 55,223, 4, 21, 69,112,146, 4,199, 99,143,
+193, 98,177, 88, 71,143, 30,189,221,104, 52,174,253,237,183,223,130,114,202,178,140,157, 59,119, 66,146, 36, 68, 69, 69, 93,246,
+210,233,116,136,138,138,194,178,101,203,112,242,228, 73, 77,113,183, 90,173,120,251,237,183, 65, 8,169, 82,135, 2,125,214,224,
+200,113, 3, 7, 14,156, 91,183,110,221,126,211,167, 79, 55, 73,146,132, 57,115,230, 64, 16, 4, 12, 26, 52, 8,241,241,241, 88,
+187,118, 45, 36, 73,194, 11, 47,188,192, 10, 31, 3, 3,195,205, 47,176,188, 26,200, 58,175,190,250,106,141,197,139, 23, 35, 42,
+ 42, 10, 6,131, 1, 70,163, 17, 70,163,177,202,231, 87, 94,121, 69,214,250,135,212,110,175,218,249,112, 28, 56,142, 11,120, 76,
+ 75, 7,102,183,219, 49,124,248,112, 0, 8, 41,174,180,138, 33,155,205, 6, 65, 16,208,168,126, 34, 94, 29,222, 1, 93,121, 10,
+107, 49,128,162, 50,140,174, 45,224,127,117,111,197,236, 95,139,113,162,196, 2, 65,208,118, 51,166, 44,203, 1,197,149, 36, 73,
+248,248,227,143, 49,124,248,112, 72,146,116, 89,154, 48, 92, 27, 80,167, 51,172,242,169,137,179,162, 66,177,137, 84,113,165,211,
+233, 0,157, 14,156, 40,130, 72, 18, 44, 22,139,117,232,208,161,187, 12, 6,195,146,196,196,196,130, 80,162,136, 82,138,168,168,
+168,203, 4,150, 78,167, 83,197,213,242,229,203,177,120,241, 98,116,234,212, 73,115,153,151, 36, 9, 79, 61,245,212,101,191,173,
+ 92,185, 82, 21, 88,130, 32, 64,146,164, 80,226,138, 0,224, 68, 81,188,255, 31,255,248, 7,167,156,159,144,144, 0, 81, 20,145,
+150,150, 6,179,217,140,173, 91,183,170,245,130,129,129,129, 33, 8, 68, 0,109, 0, 36,162,114,198,160, 20, 64,172,215,239,133,
+158,247, 68,175,239,187,252,240,220,238, 57, 71,249, 93,249,110, 7,160,243,115,188, 24,128,193,243,178, 1,216, 6,160,165,215,
+255, 40,215,193,247,127, 5, 79, 99,216, 3,192, 70, 0, 61,189, 55,191,163,148,158,126,235,173,183, 76,126, 28,172, 42,211,134,
+148, 82,205, 83,134,114,124,188,234, 12,212,104,223,254,247,198,253,231,159,213,142, 75,236,218, 21,196,104, 4,222,121, 71, 19,
+167,221,110,199,249,243,231, 47, 27,121, 95,169,192, 34,132,192,233,116,194, 96,136,194,119,243,187,227,204, 49, 23,222,206, 57,
+137,149, 63, 28,135, 32, 8,200,184,173, 9,134,185,128,236,120, 61,198,186,100, 56,220,218,214,234,186, 92, 46,191, 78,128,242,
+ 34,132, 84,249,204,112,237,225,106,222, 92,115,249, 36, 47,191,172,137,211, 56,100, 8,206,108,217, 2, 73,146,144,208,175, 31,
+224,113,173,132, 93,187, 32, 73, 18,202,202,202,172, 15,116,236,248,253, 5,189,126,241,160, 65,131,142,175, 93,187,214, 24, 82,
+180, 81, 90, 69, 76,121,187, 86,222,226, 74, 20, 69, 56,125, 68, 99, 48,129, 21,168,126, 40,229, 53, 28, 7, 11, 0,220,110, 55,
+253,246,219,111, 49,103,206, 28, 36, 36, 36,160,127,255,254,168, 85,171, 22,150, 47, 95, 14, 74, 41,158,122,234, 41, 24, 12, 6,
+ 24, 12, 6, 86,230, 25, 24,254,164, 8,164, 65,124,208,125,194,132, 9, 29,178,179,179,167,116,233,210,101,217,182,109,219,150,
+ 18, 66,114,188,218,196, 12, 15, 87,142,215,247,219,125, 68,150, 8, 32,145, 16,146,163,156,239,253,221,235,120, 95, 0, 58,229,
+251,132, 9, 19, 90,102,103,103, 79,201,204,204,124, 57, 43, 43, 75,154, 48, 97, 66,171,236,236,236, 41,202,255,248, 11,135,183,
+131,229,119, 23,224,207, 63,255,188,183,111, 12,155, 55,111,190,161,115,231,206, 77,247,236,217,227, 45,186,106,223,126,251,237,
+249,148,210,144,119, 23, 42,107,186, 2,185, 2, 28,199,129,152, 76,128,201,164, 53, 99,224,116, 58, 33, 8, 2, 56,142,195,218,
+181,107, 97, 48, 24, 48,112,224,192,128, 2, 75,171, 43,166,211, 73, 16, 98, 57,252,223,244,221, 40,186, 80,174, 78, 9,174,203,
+ 63,137, 31,244,122,188,218,162, 53,204,150,124,148,216,236, 97, 57, 88, 58,157, 78,237,172, 36, 73,194,147, 79, 62, 9,187,221,
+ 14,142,227,212, 99, 30,225,202,122,156, 63,166,178,107, 42,159, 84,163,139,229,118,187,127,119,173, 36, 9,156, 36,129,120,242,
+185,172,172,204, 58,100,200,144, 93, 23,244,250,197,167, 78,157,250, 1,128, 94,171,192, 82, 68,149,194,237, 79, 92, 9,130, 0,
+135,195,161,121,160, 18,200, 73, 10, 87, 96,209,202, 6,197, 13,128, 54,104,208, 64,189, 38, 57, 57, 25,177,177,177,234,218, 54,
+189, 94, 15,131,193,192, 28, 44, 6,134, 63, 55,180, 60,137, 32, 42, 59, 59,123,138,183,128,241, 21, 52,222,194,201, 71, 68,121,
+139,180,150, 33,218,255, 28, 95,209,164,252, 47, 33, 36, 39, 43, 43, 43, 35, 68, 56, 10,125, 5,150,230,109,246,121,158,175, 51,
+127,254,252, 26, 95,126,249, 37,204,102, 51, 98, 99, 99, 17, 19, 19,131,216,216, 88, 12, 27, 54, 44,228, 84,161,219,237, 14, 56,
+237,194,243,124,165, 96, 51,155, 43, 59, 49,141, 29,152,195,225,128, 40,138,224, 56, 14, 79, 60,241,132,186, 46,234,106,166, 8,
+237,118, 59,120,142, 7,162,110, 1,197, 78, 85, 92,169, 47,157, 14,249,245, 91,131,156, 61, 13, 65,208, 54, 67,234,118,187,213,
+ 78, 79, 20, 69,188,246,218,107,120,247,221,119,171,220, 64, 32,138, 34,218,182,109,139,188,188, 60, 86,229,254, 0,132, 85, 62,
+ 5, 65,147, 88, 87,220, 38, 73,146,192,233,116, 32, 30,129, 85, 86, 86,102, 29, 49, 98,196,247, 37, 37, 37,139,155, 54,109,122,
+ 4,149,219, 24,104, 18,213,132, 16,149, 83,175,215, 7, 20, 87,130, 32,104,118,176,148,122,228,141,191,254,245,175, 85,222, 1,
+224,169,167,158,210, 90,143, 40, 0,136,162,136,190,125,251,162, 85,171, 86, 88,185,114, 37,220,110, 55,158,124,242, 73, 24, 12,
+ 6,204,156, 57, 19, 46,151, 11, 83,167, 78,101,133,143,129,225,207, 61,176, 13,165, 65,172,153,153,153, 47, 19, 66,114, 60, 78,
+210,254, 32, 66,202, 31,110,247, 17,105,133, 1,218,235, 12,127, 34,203,251,179,130, 9, 19, 38,180,244, 19,142, 93,151, 9, 44,
+ 47,245, 24,170, 3, 58, 61,118,236, 88,147,178, 71,150, 34, 12,120,158,215,116,119, 33,119,232, 16,204,158, 5,237,246, 3, 7,
+126, 23, 22,221,187,131,152, 76, 32, 70, 35,184, 85,171, 42, 59,174,216, 88,224,165,151, 66,166,154,211,233, 84, 5, 86,113,113,
+113, 68,214, 96, 57,157, 78,240,146,136, 29,102, 17, 84,228,171,136, 43, 81, 20,193, 9, 34,242, 19,111, 5, 17,254, 11, 65,214,
+118,211,147, 34,176,148, 23,199,113,120,246,217,103,213, 52,224, 56, 14, 93,187,118, 85,132, 44,171,113,127, 0,132, 45, 91, 96,
+206,200,208, 84, 62, 73,116, 52,240,239,127,135,228, 44,155, 51, 7,209,111,191, 13, 34,138, 16,118,236,128, 78,167,131,197, 98,
+177,222,211,182,237, 46, 75,108,236,226, 19, 39, 78,252, 0,128, 27, 62,124,120,141, 14, 29, 58,240, 26, 27, 35,191,211,130, 75,
+151, 46,173, 34,174, 4, 65,128,203,165,173,124, 6,115,176,252,185, 89, 26,132, 37,189,251,238,187,193,243, 60,106,212,168,129,
+232,232,104,245,238, 75,197,185,114,185, 92,112,185, 92,154,215, 49, 50, 48, 48,220,156,208,160, 65,108, 89, 89, 89,251,179,178,
+178, 84, 39,201,215,193, 10,128, 65, 30, 49,149,168,136, 51, 84,174,165,218, 21, 36, 44, 25,129,132,151,247,177,236,236,236, 41,
+126,194,161, 78, 75, 6,220,104,180, 83,167, 78, 77,189,183,105,224,121, 30,178, 44,159,249,249,231,159,175,106,131, 81,234, 53,
+ 93,225, 45,206, 20, 87,128,152, 76, 97, 47, 34, 86,166, 8,121,158, 87,197,203,162, 69,139, 96, 54,155, 49,102,204,152,171, 16,
+ 88, 60,190,146,242, 0, 73,184,204,193,226, 69, 17,191,214,168, 7, 78, 20, 33,200, 78, 77, 78, 70, 73, 73, 9, 36, 73,194,123,
+239,189,135, 87, 94,121, 69, 73, 83,213, 29,241, 22, 90, 12,127, 80, 37,247,114,123, 66,149, 79,158,231,161,105,175, 76,151, 11,
+144, 36,192, 51,149,103,177, 88,172, 35, 70,140,248,222, 18, 27,187,184,113,227,198,138,115,197, 25,141, 70,240, 60,175,201,193,
+226, 56,206,175,184, 82,234,129, 90, 78,121, 62, 44, 7, 75,146, 36,172, 90,181, 74,173, 43,222,206, 85,184, 2,203, 59,172,155,
+ 55,111,198,158, 61,123,240,196, 19, 79,192, 96, 48, 96,214,172, 89,112,185, 92,120,227,141, 55, 96, 48, 24, 42,167, 79, 25, 24,
+ 24, 24, 2, 35, 78, 17, 56, 30,145, 84,197, 89,162,148,102,120,139,160, 64, 83,133, 30,199,105,115,136,255, 90,229, 17,102,126,
+161, 56,105, 62,131,222, 28, 95,113, 38, 40,202,209,251,157,227,184, 58,243,230,205,171,177,121,243,102, 24,141, 70,117,163,209,
+ 17, 35, 70,200, 87,157, 68,138,192,242, 76,183,168,194,194,211,129,113, 94, 29,152,214, 69,175,138,131,229, 45,176, 38, 77,154,
+ 4, 65, 16,176, 96,193, 2, 0,192,223,255,254,247,176, 4,150,195,225, 0,117, 3,219,228,141, 72,153,211, 26,244, 67, 61,206,
+109,254, 5,162, 40,162, 86,199,126,112,119, 24,134, 98, 93, 12, 76,212,173,121,244,125,225,194, 5, 28, 56,112, 0,132, 16,188,
+254,250,235, 85,246, 0,242, 94,227, 3, 0,107,215,174, 5,254, 68,207,108,186,238, 4,150,134,242,169, 56, 73, 90, 56,137, 78,
+ 7,222, 35,174,134, 12, 25,178,171,164,164,100,241,137, 19, 39,118, 1, 32, 35, 71,142,172, 97, 52, 26,177,112,225, 66, 43, 0,
+113,197,138, 21, 6, 45,162,197,159,184,242, 39,176,100, 89, 14,171, 30,133, 26,140, 92,137,192, 34,132, 64,150,101,213,185,114,
+ 58,157,234,247,168,168, 40, 86,240, 24, 24,254,228,238,149,247,123, 0, 20,250,172,115, 34, 62, 78, 83,161, 63, 97,229, 61, 29,
+232,245,217,233,135,215,238, 51,117,232,123, 92,121, 47,206,202,202,250, 78,113,174,188,142, 87, 9, 71, 64, 7,139, 82,170,110,
+ 52,170,116, 34, 28,199, 65,150,229,243, 87,155,144,174, 54,109,224, 60,120, 16, 60,207, 67,234,217,179,114, 45,139,209, 8,110,
+229,202,223, 59,174, 73,147, 64, 77, 38,208, 1, 3,180,113,122,238,206,243, 22, 88, 23, 47, 94,132, 40,138,120,235,173,183,192,
+113, 28,166, 78,157,138, 58,117,234,224,204,153, 51, 88,189,122,181, 38, 78,206,205, 65, 63, 58, 30,250,177,209,224,158,104,140,
+150,131,199,226, 82,105, 3,236,181,155,208,172, 44, 15,113, 27, 38,193, 33,107,159,222,112, 58,157,234,222, 69,148, 82,213,189,
+ 82,166, 77,100, 89, 86, 55,117,156, 54,109, 26,216,147, 68,174, 61, 28,125,250,104, 46,159,238,158,218, 30, 8,111,120,246, 89,
+ 56, 70,143,134,197, 98,177, 62,208,165,203,214, 18,189,254,227,230,205,155,171,107,174,140, 70, 35,244,122, 61, 81,156, 44, 45,
+156,202, 77, 29,161,196,149,242, 89,107,249,244,222,134, 33, 18, 2, 75,105, 59,198,140, 25,131,218,181,107, 99,246,236,217, 85,
+156,171,151, 95,126, 25, 78,167, 19, 51,103,206,100,133,143,129,129, 33, 24,118,133,113,238,237, 94, 98,105,215, 21,242,238,186,
+218, 0,251,109,121,247,238,221,219, 59,208, 5,222,211,135, 74, 3, 74, 41, 61,179,103,207,158, 59,252, 52,174,105,148,210,125,
+222,199,100, 89,254,125, 81,183,201, 84,233, 12, 24,141, 85, 28, 28,106, 54,131, 51,155, 1, 63,119,252,249,227, 84, 4, 22,199,
+113, 85, 70,223,130, 32,224,210,165, 75, 16, 69, 17,179,103,207, 70, 76, 76, 12,108, 54, 27,180,132,211,225,112,128,231,121,148,
+159, 40,199,241,137,123, 17,101, 58,130,166,253,162, 17, 45, 30, 69,147, 45, 95,194,229,178, 3, 94, 83,134, 90, 56, 27, 54,108,
+136,241,227,199,171,139,147,125, 95,222,113,165,148,226,246,219,111, 15,201,121,181, 96,156, 85, 57,189,239,114, 13, 85, 62, 57,
+159, 60, 11, 22, 78,229,110,193, 50,147,233,227, 19,199,142,237, 2,192,141, 28, 57, 50,198,104, 52, 98,254,252,249, 86, 0,220,
+155,111,190,105,104,208,160, 1,175, 37,156, 60,207, 95, 38,174,194, 17, 88,129,234,145,239,246, 33,207, 60,243,204,101, 27,141,
+ 6, 18, 88,129,226,206,243, 60,106,214,172, 9,163,209, 8,151,203,165, 58, 87,122,189, 94,221, 29, 62,208, 96,130,149, 79,198,
+201, 56,255, 60,156,127,144, 24,171, 54,132,189,178, 84,153, 62,220,177, 99, 7,162,163,163, 81,163, 70,141,176,166, 14,157, 78,
+ 39, 18, 19, 19, 65, 41,133,144,157, 13,160,242,201,175,118, 81, 84, 31,249, 33,246,238, 13, 55,199,193, 82, 94, 14,135,195, 17,
+114, 26,198,106,181, 86, 89,128,174,136, 43,239,142,193, 98,177,168,155,135,106,129,194,169,184, 98, 68,166, 56,182,110,197,229,
+119, 19,134,177,147,187, 44,203, 72, 74, 74,170,178,134, 71,233, 4,253,116,212, 0,155, 34,188,230,112, 58,157,136,243, 60,194,
+ 73,204,204, 4, 8, 1, 37, 4, 54,143,211,232,114,185, 32,118,233, 2,202,243, 40,177, 90,225,112, 56,160,215,235,131,114, 22,
+ 23, 23, 91, 31,124,240,193,239, 41,165, 31, 13, 30, 60, 56, 15,149, 11, 44,169,201,100,210,241, 60, 79, 1,252, 6,128,158, 63,
+127,190,198,185,115,231,220, 46,151,171, 94,168,112,238,216,177, 3,199,142, 29, 67,187,118,237,212,199,215, 40, 47,229, 17, 76,
+ 87,226, 96,249,219,163,237, 74,119,114,247,106, 51, 80,163, 70, 13,232,116, 58,188,245,214, 91,144, 36, 9, 6, 67,229, 44,232,
+204,153, 51, 43,211, 58, 12, 62, 6, 6, 6,134, 27, 1, 97, 11, 44,101,250,240,199, 31,127,116, 40,141,167,214,141, 70, 37, 73,
+ 42,108,213,170, 85, 88, 15, 60,150, 36,233,226,137, 19, 39, 92, 65, 84,244,217,141, 27, 55,134,245,144, 90,158,231, 67,114,238,
+216,177, 35, 44, 78,142,227,130,114,138,162, 88,152,158,158, 30, 86,220,163,162,162,206,179, 34,122,237, 32,138, 98,225,160, 65,
+131,252,231,209,172, 89,129,174,185,136, 32,207,206, 19, 69,241, 88,203,150, 45,127, 49,153, 76,223, 38, 36, 36,252,182,101,203,
+150,132,118,237,218, 85,121,248,115,187,118,237,106,249,148, 37, 59, 2, 60,135,208,131,179, 47,190,248, 98,184,229,179, 48,196,
+104,244,236,217,179,103,195,173, 71,133, 33, 27, 24, 65, 56, 59,110,220,184,186, 90,235, 58,216,115, 8, 25, 24, 24,254,172, 2,
+ 43,216,244, 97, 40,228,231,231, 55,136,116, 4, 78,159, 62,221,244, 70,224,220,177, 99, 71, 3, 86,220,174,111, 84, 71, 30,237,
+216,177, 35, 45,210,156,185,185,185, 17, 47,159,187,119,239,110, 90, 29,105,250,217,103,159, 53,101, 37,139,129,129,225,207, 8,
+182, 31, 0, 3, 3, 3, 3, 3, 3, 3, 3, 19, 88, 12, 12, 12, 12, 12, 12, 12, 12,215, 55, 8, 0,191, 83, 24,225,220, 29, 64,
+ 8, 9,123, 26, 36, 20, 63,227,100,156,140,147,113, 50, 78,198,201, 56,111, 62,206, 80,220,215,241,221,137,225, 9,172,234,220,
+107,137,221,194,202, 56, 25, 39,227,100,156,140,147,113, 50,206, 63, 35,216, 20, 33, 3, 3, 3, 3, 3, 3, 3, 3, 19, 88, 55,
+ 7,136,214,231, 0, 49, 48, 48, 48, 48, 48, 48,220,112, 8,184, 77, 67,199,142, 29,243,101, 89, 14,107,223, 38, 81, 20, 11,181,
+222,234, 78, 8, 17, 82, 82, 82,134, 24, 12,134, 30,162, 40,118, 1, 0,167,211,185,221,106,181,110, 42, 40, 40,248,130, 82,122,
+ 69,251,225, 36, 39, 39, 55,224, 56,238, 33, 66,200,112, 0,160,148, 46,119,187,221, 75,206,157, 59,151,127,189, 8, 43, 73,146,
+ 38,222,121,231,157,119, 18, 66, 22, 82, 74,151, 68,144,251,130,191,227,148,210,184, 43,229,172, 95,191,126,172,203,229,234, 0,
+160,173,231,208,143,130, 32,236,254,245,215, 95, 47,178,234,115,115,224, 74,234, 58, 80,185,175,221,246,237,219, 27, 68,146, 83,
+167,211,157,218,182,109,155,223,173, 29, 58,117,234,116,200,229,114,213,141,100, 56, 59,117,234,148,239,114,185,194, 14,103, 84,
+ 84,212,169,173, 91,183, 54,141, 36,231,181, 14,103, 32,116,232,208,225,115, 74,105,186,167, 77, 89,179,123,247,238,161,172,150,
+ 48, 48, 68, 80, 96,201,178,156,184,105,211, 38,152, 76, 38,165,147,134, 44,203,234, 46,209,110,183, 91,125,134,158,178,195,117,
+255,254,253, 53, 53, 0,245,234,213,107,209,180,105,211,197, 79, 61,245, 84,189,193,131, 7,235,146,147,147, 65, 8,193,217,179,
+103, 27,231,228,228, 60, 48,123,246,236,151,235,213,171, 55,242,228,201,147, 63,107,225, 75, 76, 76, 52, 73,146,116, 47,165,116,
+100,235,214,173,239,120,225,133, 23, 72,215,174, 93, 33,203, 50, 54,108,216, 48, 97,250,244,233,153, 41, 41, 41,219, 8, 33,139,
+ 29, 14,199,151,133,133,133,101,127, 96,154,247, 30, 55,110,220, 3,127,251,219,223,106, 62,250,232,163,255, 7, 96, 73, 4,185,
+117, 17, 20,107, 66,237,218,181,199, 3,200,244,229,117,185, 92,246,148,148,148,236, 51,103,206, 76,191, 82, 33,204,112,253,192,
+187,174, 43,207,196,116,185, 92,106,221,150,101, 89,125,202,130, 98,188, 82, 74,209,183,111,223,196,112, 56,149,118, 67,225, 5,
+ 0,183,219,237,125, 13,210,211,211,107, 5,226,116,187,221,181, 20, 78,239,112, 41,124,190,235, 73,149,176,222,121,231,157, 1,
+195,233,114,185, 18,191,255,254,123,232,245,122,149,203, 55,140,222,188,202, 67,171,123,245,234, 85, 43, 92, 78,229,179, 63, 78,
+ 0,232,218,181,235, 53, 13,167,151,120, 75,114,185, 92,179, 8, 33, 58,158,231, 95,160,148,166,175, 94,189, 26,178, 44, 99,208,
+160, 65,233,157, 58,117,106, 44,203,242, 63,140, 70,163,219,102,179, 61,177,115,231, 78,182, 1, 50, 3,195,213, 8, 44, 0, 48,
+153, 76, 88,186,116,169,250,120, 12,223, 71,209,120,127, 78, 77, 77,213,244,135,181,107,215,110,215,160, 65,131, 53, 95,124,241,
+133, 33, 41, 41, 73, 61,238,112, 56, 16, 19, 19,131, 49, 99,198,232,250,246,237,219,120,228,200,145, 27,107,215,174,157,126,230,
+204,153, 61,193,248,234,212,169,243,120, 82, 82,210,155,227,199,143, 55,220,125,247,221,136,139,171,106,214,100,100,100, 96,224,
+192,129,228,216,177, 99, 93,151, 47, 95,222,245,163,143, 62,122,183, 78,157, 58,175,157, 62,125,122, 94,168,176,214,173, 91, 55,
+ 78,175,215,191,159,156,156,156,118,252,248,241,109, 58,157,238,197,138,138,138,167,106,215,174, 61,194, 98,177,156,180,217,108,
+ 79,254,250,235,175,199,195, 17, 45,241,241,241,127, 31, 59,118,108,124,105,105,169,156,155,155,123, 88, 57,174,215,235,159,239,
+220,185,115,199,239,190,251,110, 9,165,244,243, 43,113,174, 92, 46,215,238, 96,191,107,117,178, 90,180,104, 33,213,174, 93,123,
+ 13,128,142,131, 7, 15, 62, 49,121,242,100, 26, 27, 27, 27,205,113, 28, 41, 46, 46,190, 48,109,218, 52,233,211, 79, 63,157, 84,
+187,118,237,244, 22, 45, 90,164,255,252,243,207, 14, 86,149,110,108,152, 76, 38,124,242,201, 39, 85, 30,135,227,253,220, 65,223,
+199,229,196,199,199, 87, 11, 39,165, 52,232,212,185,193, 96,192,134, 13, 27, 46,123, 52, 86,160,151,217,108, 6, 33, 4,132, 16,
+ 66, 3,220,209,163,215,235,177,110,221, 58,245, 65,215,161, 56,141, 70, 35, 16, 98,121, 69,184,156,102,179, 57,100,122, 94, 97,
+ 56, 67, 46, 69,112,185, 92,179,166, 77,155, 54, 40, 58, 58, 26, 47,189,244,210,255, 82, 83, 83, 17, 19, 19,131,249,243,231, 35,
+ 46, 46, 14,178, 44,255,239,157,119,222, 33, 39, 79,158,196,204,153, 51,231, 2, 24,194,106, 12, 3,195, 85, 10, 44, 0, 85, 26,
+193, 96, 2,203, 31,124,239, 48,104,208,160, 65,148,217,108, 94,242,213, 87, 95, 25, 18, 18,126,127, 90,136,221,110, 71,105,105,
+ 41, 44, 22, 11, 74, 75, 75, 97, 50,153, 48,103,206, 28,195, 67, 15, 61,180,164, 65,131, 6,173,243,243,243,109,129, 56, 41,165,
+217, 63,253,244,147,232,114,185,160,211,249, 55,112, 56,142, 67,227,198,141,241,204, 51,207,160, 91,183,110,198, 7, 31,124, 48,
+ 27,192,188, 64,156, 94,194,228,195, 45, 91,182,116, 73, 74, 74,210,127,249,229,151,250, 57,115,230,228, 13, 28, 56,208, 50,106,
+212,168,218, 23, 47, 94,172,157,145,145,241, 53,128, 22, 90,226,238,193, 3,227,199,143,111, 17, 23, 23,199, 77,155, 54,237, 98,
+105,105,233, 7,158,227, 79,205,156, 57,115, 84,143, 30, 61,106, 62,250,232,163,110, 66,200, 23,254, 58,131, 32,119,108,232, 60,
+241, 20,194,117,182,252,113, 94,188,120,241,101, 0, 29, 23, 45, 90,180,175, 79,159, 62,245, 41,165,197, 0,206, 2, 64, 82, 82,
+146,126,250,244,233,198, 30, 61,122,252,248,196, 19, 79,116,244,156, 59, 89, 99, 56,175, 24,140,179,122, 57,221,110, 55, 68, 81,
+196,176, 97,195, 64, 8,169,242, 28, 67,165,158,111,217,178, 5,253,251,247,135, 40,138,120,244,209, 71, 53,115, 62,248,224,131,
+112,185, 92,151,113,174, 95,191,190,138,208,226, 56, 78, 51,167,242,140,208, 80, 47,173,156, 90, 69,203,245,194,217,171, 87, 47,
+236,220,185,243,170, 57,149,102,254,167,159,126, 66,235,214,173,177,120,241, 98,194,243, 60,118,238,220, 9,131,193,128,209,163,
+ 71, 35, 45, 45,141, 24, 12, 6, 28, 59,118, 12, 22,139,133,176,122,196, 56,171,139, 51, 4, 68, 0,109, 0, 36, 2,144, 1,148,
+ 2,136, 5, 96,247,244,113,197, 0, 12,158,151, 13,128, 5, 64, 77,207,181, 69,158,193,134,247, 99,202, 10, 81,245,161,208,183,
+123,184,149, 71,128,121, 59,202,118,159,126, 84,249,238,251, 94,133, 91,240, 8, 9,165, 51,239, 73, 41,221,228,149,128,154,196,
+149, 40,138,208,178,102,219,237,118,143,205,204,204, 76,242, 22, 87, 54,155,173,138,184,178, 88, 44, 40, 40, 40, 64,253,250,245,
+ 49,124,248,240,164, 69,139, 22,141, 5,240, 94,176, 68,231,121, 30, 63,252,240, 3,206,159, 63,143, 86,173, 90,225,150, 91,110,
+169,114,194,209,163, 71,241,205, 55,223,224,194,133, 11,104,223,190,189,146, 81,126,145,146,146,146, 16, 27, 27, 59,142,227,184,
+251, 59,117,234,148, 82, 88, 88, 72,206,158, 61,139,212,212,212,228, 47,190,248, 2,123,247,238, 53,231,230,230,194,225,112, 72,
+ 93,186,116,169,223,188,121,243, 19,162, 40,174, 58,119,238,220,187,193,214,121, 17, 66,248,186,117,235,190,252,248,227,143,235,
+ 10, 10, 10,220, 31,125,244,209,119,148,210,189,132,144,251, 95,121,229,149,199,210,211,211,107,238,217,179,167,116,215,174, 93,
+ 59,168,198,189, 51,252, 56, 87,130,111,131,108,177, 88,112,226,196,137,221, 37, 37, 37,156,231,124, 59,165,180, 86, 16,215,174,
+ 17,128,241,247,223,127,255, 97,143,184,250,213, 83,152, 1, 0,178, 44, 59, 75, 75, 75,203,122,244,232, 81,187,111,223,190, 7,
+215,173, 91, 55,190,110,221,186,139, 79,157, 58,117,148,141, 87,110, 92,184, 92, 46,136,162,136,111,191,253, 54,168,219,180,117,
+235, 86,213,113, 89,177, 98,133, 38,206,175,190,250, 42,164,131, 21, 70, 27,162,138, 7,223,135,174,207,157, 59, 23,227,198,141,
+171,114,204,227, 94, 81, 79,227, 74, 3,113, 6, 18, 66,183, 52,108,136,179,103,206, 84,225,228, 56,174,202,212,102, 48,206,143,
+ 62,250, 8, 25, 25, 25,200,201,201, 9,250,126,215, 93,119,105,138,187, 34,174, 28, 14,135, 26,198, 35, 71,142,248,229,253,231,
+ 63,255, 9, 45, 77, 9,207,243,227,151, 45, 91,246,211,133, 11, 23,132,220,220, 92,232,245,122, 24, 12, 6,245,253,236,217,179,
+176,219,237,248,244,211, 79, 93, 28,199, 61,207,106, 11, 67,164, 17, 72,131,248,160,251,132, 9, 19, 58,100,103,103, 79,233,210,
+165,203,178,109,219,182, 45, 37,132,228, 80, 74, 51,148,247, 9, 19, 38,180,204,206,206,158,146,153,153,249,114, 86, 86,214,126,
+ 66, 72, 14, 0,248,126,247,232,155, 12, 31,241,150,168,240,120,194, 84,229, 92,127,223,125,223,125,185, 5,175, 3,196,171, 33,
+ 82, 58, 83,205, 2,203,223,104,201, 23,209,209,209, 3, 6, 12, 24, 32, 5, 19, 87,165,165,165, 40, 45, 45,197,161, 67,135,144,
+150,150, 38, 69, 71, 71, 15, 8, 33,176, 42,149,133, 32, 32, 37, 37, 5, 69, 69, 69,216,183,111, 31, 82, 83, 83,225,116, 58,177,
+102,205, 26, 92,188,120, 81,109,216,237,118,123, 80,158,164,164,164,217, 15, 61,244,208,192,177, 99,199,242,255,253,239,127,209,
+172, 89, 51,220,114,203, 45,216,182,109, 27, 28, 14, 7,234,213,171,135, 46, 93,186, 96,197,138, 21,104,211,166, 13,247,215,191,
+254,181,230,254,253,251, 71,207,154, 53,171, 51,128,118, 65,168,219, 12, 29, 58,180,102,116,116, 52,198,141, 27, 71,237,118,251,
+ 12, 66, 72,218,176, 97,195, 38, 63,253,244,211, 9,249,249,249,142,199, 30,123,108,187,221,110,159, 31, 70,185, 12,232, 92,185,
+ 92, 46, 88, 44, 22,148,148,148,160,180,180, 84, 40, 41, 41,225,160, 97,141,150,219,237,190, 19, 0, 63,113,226, 68, 80, 74,127,
+243, 22, 87,118,187, 29, 22,139, 5, 22,139,197, 45,203,242,165,177, 99,199, 90,215,173, 91,199,123,174, 97, 2,235, 6,134, 82,
+215,135, 14, 29, 90,197, 29, 90,191,126, 61, 50, 50, 50, 46,155,230,211, 34, 8, 20,206, 7, 30,120, 64, 21, 70, 74,155,177,122,
+245,106, 77,142, 75, 32,145,225,207,193,226, 56,206,239,177, 80, 34, 67,225,244,247, 2,112, 25,167, 86, 33, 40, 8, 2,198,142,
+ 29, 11, 81, 20,241,220,115,207, 65, 20, 69,164,165,165, 65, 20, 69,116,234,212, 9,162, 40,162, 87,175, 94, 97,115,110,222,188,
+ 25,157, 59,119, 86,195,152,150,150,134,118,237,218, 65, 20, 69,116,235,214, 13,162, 40,162,127,255,254,154, 56,149, 5,237,105,
+105,105,120,226,137, 39,240,197, 23, 95, 96,209,162, 69,234,239,195,134, 13,195,208,161, 67, 97,177, 88,144,156,156, 44, 20, 20,
+ 20,236,239,208,161, 3, 91,248,206, 16,113,248,211, 32, 62,136,202,206,206,158,226, 35,140,170, 64,249,157, 16,146,147,149,149,
+149,225, 45,134,188,191,123,185, 76,222,226,173,165,183, 3,229, 45,158, 2,136, 50,223,240,123,159, 95, 88, 69, 96,121, 34,214,
+211, 95, 3, 41, 73,146,218,160, 5, 18, 90, 90, 80, 81, 81,209, 74,113,175, 42, 42, 42,170, 8, 42, 79,199,173,126,182,219,237,
+104,216,176, 33, 42, 42, 42, 90,133,169,132, 81,187,118,109, 56, 28, 14, 44, 88,176, 64, 21, 86, 10, 28, 14, 71,168, 76,174,221,
+187,119,111, 62, 63, 63, 31,167, 79,159,134,219,237,198,246,237,219, 33,138, 34,172, 86, 43,108, 54, 27, 86,172, 88, 1,158,231,
+113,244,232, 81,232,245,122,180,110,221,154,200,178, 28, 27, 34,104, 61,122,247,238, 13, 66, 8, 86,175, 94,125,156, 82,154,103,
+ 52, 26, 23, 78,153, 50, 37,206,102,179,185, 71,141, 26,117,252,183,223,126,123, 25,128, 75,175,215, 79,236,209,163, 71,215,117,
+235,214,125,236,114,185, 22,135, 91, 80,109, 54, 91,149,180, 44, 41, 41,193,165, 75,151,180, 94,222, 22, 0, 98, 98, 98,106, 2,
+ 56,163, 28, 44, 47, 47, 71,121,121, 57, 74, 74, 74, 80, 94, 94, 14,171,213,234, 48, 26,141, 58,175,107,254,195,154,136, 27, 95,
+ 96,173, 94,189,186,138,203, 36,138, 34, 54,108,216,112,153, 3,165,211,233,176,106,213, 42, 77,110,211,215, 95,127, 29,212,185,
+242,110, 99, 66,173,193,242, 22, 67, 31,124, 80, 57,195,254,204, 51,207,248,157, 54,244, 94,186,112,223,125,247,145, 80,225, 20,
+ 69, 17,105,111,114, 0,100,252,250,142, 65,109,215,124, 57,181,184, 66, 10,231,252,249,243, 53, 57, 88, 3, 7, 14,212,204,233,
+ 27,174,125,251,246,249,229,157, 59,119,110,200,244, 84, 22,180,199,196,196,168,211,130, 0,144,145,145,241,188,217,108,238, 86,
+ 81, 81,113, 79, 78, 78, 14, 46, 94,188,136,134, 13, 27, 34, 41, 41, 9, 59,119,238, 76,103, 53,134,161,154, 92,172,158, 65, 78,
+177,102,102,102,190, 76, 8,201, 81, 28, 41, 95,167,201,223,119, 63,255,163,136, 32,101,122,240,118, 31,241,166, 76, 29, 14, 10,
+114,173,221, 71, 80,249, 78, 17,238, 10,233, 96, 41,115,254,222, 13, 87, 32,129,165,101,244, 73, 41,229, 9, 33, 85, 4, 64, 32,
+ 7,203,233,116,162,184,184, 24,148, 82, 62,146,153, 24, 74, 96, 21, 23, 23,191,240,212, 83, 79,173,156, 49, 99, 70,204, 3, 15,
+ 60,128,239,191,255, 30,205,155, 55,135,205,102, 67, 66, 66, 2,142, 31, 63, 14,158,231,145,151,151,135,212,212, 84,152, 76, 38,
+188,246,218,107, 22,171,213,250, 90, 48, 94, 73,146,122,118,239,222, 29,185,185,185,184,112,225,194,122, 66, 72,227,199, 30,123,
+236,174,186,117,235,114,111,191,253,182,237,240,225,195,211, 0, 92, 52,155,205,239,125,244,209, 71,253,218,181,107,103, 26, 53,
+106, 20, 37,132, 44,163,148,202, 90,227, 87, 86, 86,118,153,184, 82,190,107, 28, 69,136,132, 16, 74, 8, 81,231, 64, 20,241,171,
+188, 74, 74, 74, 96,179,217,168,211,233,228, 42, 47,161, 34,107, 30,110,108, 40,157,247,240,225,195, 47,155, 46,147, 36, 9,107,
+214,172,193,208,161, 67,161,211,233, 32, 73,146, 50,213, 30,170, 44, 65, 20, 69,140, 24, 49, 66, 21, 4, 95,125,245,149, 95,113,
+165,184, 82, 90, 57,121,158,199,211, 79, 63, 13, 81, 20, 49,103,206, 28, 60,251,236,179,224, 56, 14,211,167, 79, 7,207,243,152,
+ 56,113,162,191,233,135,160,156,162, 40,226,104, 86,229,123,253,191, 91, 80, 52,167,242, 38,156,152, 26, 53, 42,207, 11, 49, 45,
+232,143,211,159,115, 37, 8, 2,122,246,236, 9, 81, 20, 53, 9, 43,127,225, 60,112,224,128,250,185, 83,167, 78,232,218,181, 43,
+ 68, 81, 68,191,126,253, 84, 94,173, 79,233,144,101, 25,243,231,207, 87,167, 5, 61,121,213,121,252,248,241,247,248, 59,191, 69,
+139, 22,172,194, 48,252, 17, 14,150, 45, 43, 43,107,127, 86, 86,150, 95,135,202,215, 73, 10,230, 52,121, 9,171, 93,240, 76, 13,
+102,102,102,190,140,202,181, 91,187, 52, 92,171,243,157, 34,244,119,190,175,131,245,122,160,209, 98, 48,129,165,172, 75, 8, 5,
+163,209,184,191,168,168,168, 83, 84, 84,148,218,241,251, 19, 39, 80,170,230, 0, 0, 32, 0, 73, 68, 65, 84, 87, 22,139, 5, 60,
+207,227,252,249,243, 48, 26,141,251, 35,153,137,161,166, 8, 79,157, 58,181,171,110,221,186,143,252,245,175,127, 29,111,183,219,
+ 91, 10,130, 32,217,108, 54,221,215, 95,127, 77,214,172, 89,131, 90,181,106,225,153,103,158,161, 22,139,197, 65, 8,177,139,162,
+120,188,172,172,108,222,241,227,199,131, 58, 77,141, 27, 55,190,213,100, 50, 97,235,214,173, 0,176, 3,192,195, 79, 60,241, 4,
+231,116, 58, 49,119,238,220,115, 0,182,198,198,198,126,188,124,249,242, 14,173, 91,183,214,173, 93,187,214,178,115,231,206,117,
+ 90,197,149,178,222,202, 59, 13,189,211,184,164,164, 68, 83,250,112, 28,247, 63, 74,233,200,242,242,242, 18,131,193,160, 47, 41,
+ 41,113,120, 59,140, 22,139, 5,101,101,101,144,101, 89, 56,119,238,220, 41, 0,205, 56,142,251, 31,107, 30,110, 14,129,181,106,
+213,170,128,110,147,226,110, 41, 3,170, 53,107,214,104,114,197, 86,174, 92,121,153, 43,230,235, 10,105,157, 38,163,148, 86, 89,
+115, 5, 64, 29, 0,114, 28,135,204,204, 76,232,245,122,188,245,214, 91,200,204,204, 84, 93,172,162,162, 34,162,133,179,209, 4,
+155,167,141,133,122,173,195,110,175, 12, 31,199,105, 22, 89,222,156,190, 47,239,184,135,217, 1, 85,225,136, 4, 39,128, 85,131,
+ 6, 13, 26, 20, 23, 23,135,209,163, 71,195,104, 52, 98,200,144, 33,168,168,168, 24, 6, 0,217,217,217,152, 48, 97, 2, 0, 96,
+210,164, 73,152, 60,121, 50,202,203,203,109,172,198, 48, 84,147,131,245,122,144, 83,226,188,215, 84,133,193,155,227,125,190,194,
+225, 43,138, 60,142,216,230, 80, 92,254,174, 13, 4, 65, 81,142,193, 42,116, 40,247, 74, 25, 81,106,112, 87, 54,110,220,184,177,
+253,189,247,222, 43,120,119,252,190, 66,203, 51,223,143,163, 71,143,186,202,202,202, 54,106, 25,129, 69,202,193,242,136,172, 53,
+ 0,212,222, 35, 33, 33, 97,137,197, 98, 25,152,148,148, 36,218,237,118, 92,186,116,233,232,145, 35, 71, 90,135, 83,120, 76, 38,
+147, 30, 0, 46, 94,188, 8, 0, 23, 1, 52,185,245,214, 91,145,155,155,139,223,126,251, 45, 7, 64,191,201,147, 39,119,236,220,
+185,179,184,108,217, 50,235,147, 79, 62,249,169,195,225,152,165, 53, 78,254, 28,193,178,178, 50, 92,186,116, 9,229,229,229,154,
+167, 8, 9, 33,219, 40,165,152, 50,101, 74,201,228,201,147, 27,148,148,148,148, 93,186,116, 73,246,118,198,202,203,203,137,209,
+104, 20,150, 46, 93, 26,173, 92,195,154,135,155, 67, 96, 93,233, 29,111,161, 28, 44,111,183, 74, 17, 90, 58,157, 14,203,151, 47,
+247, 93, 43, 21, 82,101, 41,174,213, 51,207, 60, 3,189, 94,143,247,222,123, 79,109,131,252,221,209, 76, 8,241,123,247,155,111,
+ 56, 27,191,108, 71,193,204, 88,136,162,136,196, 39, 11,171, 76,197,249,171, 42, 90,194,249,143,127,252, 35, 98, 83,132,106, 56,
+ 27, 55, 6, 0,204,159, 63, 31,195,135, 15,199,214,173, 91, 3, 78, 17,134, 10,103,110,110,238,253,237,218,181,107,228,114,185,
+246,180,106,213, 74, 56,123,246, 44,134, 14, 29,138,229,203,151,195,211,145, 33, 51, 51,179,202, 53, 22,139,133, 9, 44,134,136,
+187, 87, 26, 78, 43,244, 89, 63, 69,188,167,235,130,188,251,158, 15,175, 99,222,188,133, 0,156,126,254,175,208,143,168,242,253,
+ 15,239,115, 10, 47,115,176,180, 52,186,193,196,150, 22,129, 69, 8,153, 61,105,210,164,177,221,186,117,139,139,137,137, 65, 65,
+ 65,129, 95, 7, 43, 38, 38, 6, 14,135, 3, 27, 55,110, 44, 37,132,204, 14, 65,235,114, 58,157, 66, 82, 82, 18,138,138,138, 2,
+222,221,195,113, 28, 12, 6, 3, 44, 22, 11, 0,132,187, 57,166,189,180,180,212, 57, 98,196, 8,113,246,236,217,176, 90,173, 97,
+ 53, 48,132, 16,174,103,207,158, 18, 80,185,150, 9, 64, 89,157, 58,117, 26,233,245,122,228,231,231, 3,192,113, 0,189, 6, 12,
+ 24, 32, 20, 23, 23,211,177, 99,199,174,119,187,221,175, 80, 74, 67, 13,151,227, 1, 32, 58, 58,250, 12, 0,108,223,190,253, 23,
+127,235,218, 94,126,249,229,102,158,206, 43, 30, 1,238,164,242, 18,151,251, 83, 82, 82, 62, 92,180,104,209,232, 30, 61,122,108,
+111,211,166, 77,195, 11, 23, 46, 92,178, 88, 44,246,242,242,114, 74, 41, 21,140, 70,163,184,101,203,150,188,188,188,188, 12, 0,
+ 31,158, 58,117,106, 63,107, 34,110,124, 68, 82, 92,121, 11, 2, 95, 7,203,247, 61, 28, 78, 37,156,227,199,143,199,251,239,191,
+ 15, 74,169, 42,172, 56,142,195,148, 41, 83, 0, 0,175,188,242, 74,192,237, 99, 2,113, 22,204, 52, 32,229,217,139, 85,142, 1,
+ 0,241,132,239, 74,166, 8, 39, 77,154, 4, 81, 20,171, 76,225, 9,130,160, 10,170,112,166, 8,213,112, 22, 20, 84,138,192,196,
+ 68, 60,244,208, 67,232,215,175, 31,238,186,235, 46, 16, 66,170,240,106,157, 34,228, 56,238,157,169, 83,167, 10,122,189, 30,118,
+187, 29,229,229,229, 40, 46, 46, 70, 32, 7,203,106,181, 70,177,218,194,240, 7, 96,215, 53,230,189,234,255, 19,180, 52, 18, 87,
+186, 77,131,239,211,182,143, 29, 59, 86,146,146,146, 50,102,196,136, 17,203,230,204,153, 99,104,212,168, 17, 14, 30, 60,136, 11,
+ 23, 46,192,225,112, 64,146, 36,164,164,164,192, 98,177,224,179,207, 62, 43,183, 90,173, 99, 10, 10, 10, 74,130,113, 18, 66,222,
+ 24, 48, 96,192,164,137, 19, 39,242, 45, 90,180,192,133, 11, 23, 96,177, 88,212,198,133, 16,130,152,152, 24, 24,141, 70,236,219,
+183, 15, 59,118,236,144, 9, 33,111, 4,227,244,211,168,157, 60,126,252,184,123,214,172, 89,168,168,168,176,185, 92,174, 83, 26,
+ 68,149, 55,167,193,179,233, 31,202,202,202, 0,192, 86,191,126,253, 20, 79,154, 0,192,175,141, 27, 55,126,181, 81,163, 70,228,
+227,143, 63,166,110,183,123,157, 63,113,229, 27, 78, 74,169,205,115, 92,167,184, 99,190,107,218, 74, 74, 74, 32,203,178,206,251,
+252, 80,113,119, 58,157, 47,137,162,216,109,204,152, 49, 93, 6, 13, 26,244,211,200,145, 35, 43, 98, 99, 99, 19,120,158,183, 30,
+ 61,122,244,183,229,203,151, 71, 29, 57,114, 36, 3,192, 49,167,211,249,146, 22,206, 8,216,199,140,179, 26, 57,149,186, 30,108,
+223,166, 80,131,168, 64,156,163, 70,141, 82, 5,150,242, 82,156, 43, 95, 78, 63,187,177, 95, 22,119,101, 90,236,197, 23, 95,172,
+ 18,190, 87, 95,125, 53, 96,216,108, 54, 27,209,194,121, 97,126,237,170, 11,218, 3,136, 42,173,225,124,253,245,215,175,216,193,
+ 10, 22,206,222,189,123,195, 98,177, 64, 16, 4,172, 93,187, 54,216, 34,119, 45,101,169, 98,245,234,213,208,235,245,248,236,179,
+207, 92,201,201,201, 66,108,108,108, 64, 7,171,162,162, 34,138,213, 35,198, 89, 29,156, 55, 27,130, 10, 44,151,203,133,122,245,
+234,169,226,137,227, 56,101, 95, 25,240, 60, 15,142,227,192,243, 60,194,121,110,113, 65, 65,193,250,148,148,148, 17, 67,134, 12,
+249,207,232,209,163,205,205,154, 53, 19, 83, 83, 83, 97,181, 90,145,159,159,143,252,252,124,215,134, 13, 27, 74,173, 86,235, 35,
+ 5, 5, 5,235, 67,241,157, 62,125,250,221,148,148,148, 85, 15, 63,252,240,155,109,218,180, 25, 56,126,252,120, 52,108,216, 16,
+151, 46, 93, 66, 92, 92, 28,146,146,146,112,252,248,113,172, 88,177, 2,151, 46, 93,250, 6,192,196,130,130,130,188,112, 18,201,
+ 96, 48,204,152, 58,117,106,247,228,228,228,102,197,197,197,167, 36, 73,122, 57,220,132,118, 56, 28, 50, 0,190,168,168, 8, 0,
+172, 6,131,129, 0,192,145, 35, 71, 0,224,215,250,245,235,199, 0,192,250,245,235, 9,128,157, 97,210,199, 3,192,128, 1, 3,
+126,243,109,252,189,156, 43,205, 40, 44, 44, 44,107,220,184,113, 87,171,213,154,181,106,213,170,209, 1,238, 22,251,208, 96, 48,
+ 76, 56,114,228, 72, 25,171, 70, 55, 73, 99, 32, 8,208,233,116, 87, 36,174,130,113,126,246,217,103,126,157, 43, 95, 78,173,237,
+136,175, 8, 84,246,187, 10, 54, 80, 12,209, 81,248,141,115, 32, 78, 45,225, 84, 56,179,179,179, 33,138, 34,250,246,237, 91,101,
+ 81,251,149, 56, 88, 10,167,242, 4, 12,179,217, 12, 89,150, 49,112,224,192,171,226,165,148, 62,157,147,147,227,162,148, 26, 57,
+142,251,123, 65, 65,193,126,197, 85,244,231, 96, 49, 48, 48, 92,165,192, 18, 69,177, 80,235,179, 5, 21,232,116,186, 66,141, 34,
+107, 93,227,198,141,155, 47, 88,176,224, 73,179,217,220,203,106,181,166,121,132,204, 62,139,197,242,157, 32, 8,255, 44, 40, 40,
+ 40,213,250,191, 30,193, 52, 60, 37, 37,165,203,195, 15, 63,252,230, 29,119,220,209,233,177,199, 30,131, 32, 8,248,244,211, 79,
+113,250,244,233,157, 30, 97,181,253, 74, 18,233,216,177, 99, 37, 8,126,251,104,168, 6,172, 76, 20,197,121,221,186,117,123,108,
+219,182,109, 31, 80, 74,207,232,245,250,127,247,236,217,115,212,247,223,127,255, 31, 74,233, 73, 81, 20, 63,232,218,181,235,152,
+157, 59,119,126, 76, 41, 61, 17, 38,191, 45, 88,195,239,207,185, 10,133, 35, 71,142,148, 2,120,178,118,237,218,239,243, 60,223,
+ 85,150,229,182, 0,192,243,252,143,178, 44,111, 61,115,230,204, 65, 86,125,110, 30,184,221,110, 36, 38, 38, 86, 25, 52, 41, 83,
+111, 87, 42,174,220,110, 55,146,146,146,192,113,156,202,171,108, 16, 26,100, 90,144, 4, 19, 24,110,183, 27,209,209,209, 42,167,
+ 50,232, 11, 81, 63,168,221,110, 15,186, 6, 43, 92, 78,132, 88,219,116,133,156,208,194,105,183,219, 35, 22, 78, 0,200,205,205,
+ 45, 6,240,176,242,189,125,251,246,171, 14, 30, 60, 56, 40,144,131,197,192,192,112,149, 2,107,199,142, 29, 13,170,243,143, 61,
+ 29,120,150,231, 21, 17,120, 4, 84,239,148,148,148,140,109,219,182, 41, 83, 87, 83, 11, 10, 10,114,254,232,132,118, 58,157,147,
+ 9, 33,111, 83, 74,157, 0, 80, 81, 81,241, 10, 33,100,146,242,176,100,167,211, 57,145, 16,242,250,213, 60, 60,153, 82,106,140,
+116,184, 61, 66,138,137,169,155, 24,162, 40, 22, 14, 24, 48, 32, 49,220,235,130, 13,168, 68, 81, 44, 76, 79, 79, 15,155, 51, 42,
+ 42,234,124, 16,206,179,189,122,245,170,123, 5,225,188, 88,167, 78, 29,191,119,194, 72,146, 84,216,189,123,247,136,134,243, 74,
+ 57,131,165,103,117,132, 51,136,224,186, 63, 37, 37,101, 91, 66, 66, 66, 35,155,205, 38, 89,173, 86,201,219, 5, 52, 24, 12, 69,
+172,214, 48, 48, 92,133,192,186,145,225, 17, 84, 57,215, 91,184, 20,113,229,245,221, 21,236, 59, 3,195,181, 64,117, 12,166,170,
+131,115,235,214,173, 77, 35,205,185,125,251,246, 6,127, 86,206, 16,109,232, 29,172,102, 48, 48, 92, 29, 56,150, 4, 12, 12, 12,
+ 12, 12, 12, 12, 12,145, 5, 1,144,230,239,135,112,238, 14, 32,132,164,133,251,199,161,248, 25, 39,227,100,156,140,147,113, 50,
+ 78,198,121,243,113,134,226,190, 89,238, 78, 36, 90,247, 74,185, 34,114,118, 11, 43,227,100,156,140,147,113, 50, 78,198,201, 56,
+255,132, 96, 83,132, 12, 12, 12, 12, 12, 12, 12, 12, 76, 96, 49, 48, 48, 48, 48, 48, 48, 48, 48,129,197,192,192,192,192,192,192,
+192,192, 4, 22, 3, 3, 3, 3, 3, 3, 3, 3, 3, 19, 88, 12, 12, 12, 12, 12, 12, 12, 12,215, 13,170,245, 46, 66, 6, 6, 6,
+ 6, 6, 6, 6,134, 63, 35, 84, 7,139, 16,178,137, 16,178,137, 37, 9, 3, 3, 3, 3, 3, 3,195,181,196,205,168, 65, 4, 79,
+196, 40,174,226, 97,198, 12, 12, 12, 12, 12, 12, 12, 12, 87, 40,174,110, 74, 13, 66, 40,165, 32,132, 80, 74, 41, 97,217,204,192,
+192,192,192,192,192,112,173, 5,214,205,168, 65,216, 34,119, 6, 6, 6, 6, 6, 6, 6,134,106, 18, 88,175,179, 53, 88, 12, 12,
+ 12, 12, 12, 12, 12,127, 0,110, 74, 13,162,222, 69, 72, 8,233, 1, 0,148, 82, 38,178, 24, 24, 24, 24, 24, 24, 24,174,157, 24,
+185, 9, 53, 8,219,166,129,129,129,129,129,129,129,129, 33,194,168,214, 53, 88,132,144, 52,198,201, 56, 25, 39,227,100,156,140,
+147,113, 50, 78, 38,176, 24, 24, 24, 24, 24, 24, 24, 24, 24,152,192, 98, 96, 96, 96, 96, 96, 96, 96, 96, 2,139,129,129,129,129,
+129,129,129,129, 9, 44, 6, 6, 6, 6, 6, 6, 6, 6, 6, 38,176, 24, 24, 24, 24, 24, 24, 24, 24,254, 32, 16, 0,126,239, 4,
+160,148,238,211, 76,114, 5,119, 19,132,226,103,156,140,147,113, 50, 78,198,201, 56, 25,231,205,199, 25,138, 59, 28,253,113, 93,
+ 11, 44, 45,251, 96, 17,207,131,130,194, 38, 39, 36, 45,210, 9,197, 56, 25, 39,227,100,156,140,179,122, 56,175,164,173,247,199,
+ 73, 8, 33, 94,131,120, 0,160,158,142,147, 94, 79,225,188, 81,242,168, 58,210,179,186,243,136, 1, 16, 66, 36, 32,135,202,105,
+ 68, 66, 8,113, 3,112,211, 8,236, 76,234,201, 88, 46, 82,124, 12,213,160,188, 43,243,136,252, 62,160, 96,249,196,192,112, 19,
+215,247,136,181,245, 94,109, 7,175,112, 2,144, 1,200,132, 16, 92, 77, 91, 82, 29,125,146, 55, 39,128,106,139,251,149,182,163,
+213,145,158,213,153, 71, 12, 33, 4, 22, 33,132, 52,111,222, 92,236,218,181,235, 15,177,177,177, 77,188,127, 27, 60,120, 48, 0,
+ 64,150,101,249,155,111,190,137, 14,231,207,122,246,236, 41, 8,130,240, 85, 70, 70, 70, 15, 95, 62, 79, 47, 46,231,228,228, 68,
+ 95,207, 9, 54,108,216,176, 82,135,195,193,251, 30,151, 36, 73,254,236,179,207,162,111,134, 66, 65, 8, 17,154, 52,105, 50,204,
+104, 52, 26,148, 99,109,219,182,245,254,157,238,217,179,103,161, 22,174,215, 95,127,157, 91,180,104,209, 86,163,209,104,228, 56,
+ 14,130, 32, 64, 16, 4,148,149,149, 21, 13, 31, 62,188, 31, 0, 44, 89,159,191, 54,202,104, 72,128, 27,112,187, 41,168,155,162,
+188,162,172,120, 76,122,227,126,147, 38, 77,114,179,106,122,121, 61, 10, 53, 56,242, 3,215,198,141, 27, 93, 44,245, 52,215, 1,
+165, 77,186,242,139,171, 54,180, 3,100,224, 65,207,215, 10, 14, 40, 38, 64, 94, 2,240,217, 57,192, 90,229,228,107,216,185, 41,
+ 29,109,221,186,117,223, 75, 78, 78, 30, 83, 90, 90, 90,206,243, 60, 8, 33,180,101,203,150,151, 69,135, 16, 2,183,219,125,106,
+255,254,253, 29, 66,116,220, 98,253,250,245,167, 39, 38, 38,142, 42, 47, 47, 47, 39,132,128, 16, 66, 9, 33, 72, 75, 75, 83, 57,
+149,119,183,219,125,106,223,190,125, 29,174, 85, 56,255,200,184, 43, 92, 90,226,238,205, 89,183,110,221,233,201,201,201,163, 44,
+ 22, 75, 57,199,113, 42,103,203,150, 45,175, 56,156,145,226,100, 8, 67, 96, 53,106,212, 72, 74, 76, 76,220,156,154,154,218,120,
+193,130, 5,200,203,203, 67,179,102,205, 32,203, 50,220,110, 55, 40,165, 24, 54,108, 24, 31,110,167, 32,138,226,170, 58,117,234,
+220,177, 96,193, 2,228,228,228,224,246,219,111, 7, 33, 4,178, 44, 67,150,101, 60,253,244,211,252, 85, 54, 22, 38, 65, 16,158,
+214,233,116,119,186, 92,174,219, 60,194,231, 96, 69, 69,197, 22,151,203, 53,155, 82, 90,118,181, 9,230,112, 56,248,175,191,254,
+218,159,240, 10, 26,246, 78,157, 58, 29,114,185, 92,117,195,249, 47,157, 78,119,106,219,182,109, 77, 3,253,222,165, 75,151, 67,
+ 14,135, 35, 44,206,168,168,168, 83, 91,183,110,109, 26, 76, 92, 53,110,220,248,190,150, 45, 91,234, 63,253,244, 83,156, 62,125,
+ 26, 6,131, 1,110,183, 27,178, 44,195,233,116,226,222,123,239, 37,225,252,167,209,104, 52,110,219,182,173, 81,116,116, 52,202,
+202,202,112,225,194, 5, 60,240,192, 3,106,103, 31,165, 55, 36,204,204,154,216,216,233,116,225,183, 18, 43,206, 95,176, 98,222,
+220,185, 55,124,229,234,210,165,203, 6,187,221, 30,175,124, 23, 69,241,183,157, 59,119,246,190, 90, 94,171,213,122,140, 82, 26,
+171,177,111, 7, 0,240, 60,127, 17, 64,253, 16,245, 39, 21,192, 64, 65, 16, 26, 9,130,208,148, 82, 90,223,229,114, 37,121,202,
+226,121,158,231,127,117, 56, 28,135,236,118,251, 81, 0,223, 80, 74, 79,220,164,226,170, 62, 0, 87, 74, 74, 74,129,103, 52,127,
+213,156, 50,240, 32,165,180, 6, 0, 92,186,116,169,198,201,147, 39,107,125,253,245,215, 45,167, 76,153,210, 91, 87, 81, 49,205,
+ 14, 28, 8,118,125,211,166, 77,119,139,162,152,234,213, 14,157,200,203,203,139, 68,103,199,213,169, 83,231,189,187,238,186,235,
+225,121,243,230, 25,119,238,220,105,108,213,170, 21, 42, 59, 91,168,237, 61,165, 84, 45, 91,157, 59,119, 1,249,221,221,190, 44,
+249, 0, 8, 41, 41, 41, 51, 7, 12, 24, 48, 98,238,220,185,198,125,251,246, 25,155, 52,105,162,114,122,167,167,167, 83, 71,251,
+246, 29, 64, 0, 66, 61,211, 84,145, 10,103,117,196,189, 69,139, 22,248,249,231,159,131,198, 61, 61, 61,125,196,188,121,243,140,
+123,247,238, 53,222,122,235,173,126,227,174,196,191, 67,135,219,131, 22, 71,239,244,156, 63,127,190, 49, 55, 55,215,216,188,121,
+115,143, 72,131, 26,198, 48,226, 94, 29,156, 12, 90, 4, 22, 33,132,235,217,179,231, 55,245,235,215,111,177, 96,193, 2,194,243,
+ 60,114,115,115, 81, 92, 92,140, 58,117,234,192,108, 54, 67,175,215,135,255, 71,130,240,149, 71, 92,113, 60,207, 99,195,189,247,
+194, 10, 96,152,221, 14, 73,146,112,228,200,145,171,109, 20,187, 69, 71, 71, 47, 88,178,100, 73,108,151, 46, 93,184,147, 39, 79,
+ 34, 45, 45, 13, 69, 69, 69,237, 55,110,220,216,118,236,216,177,163, 8, 33,143, 81, 74,191,143,196,200,246,155,111,190,129,201,
+100,130,209,104,132,201,100,130,195,225, 8,122,157,219,237,174,181, 97,195, 6, 68, 71, 71, 67,150,101, 80, 74,171, 84, 96,223,
+138,231,114,185,208,183,111,223, 90, 65, 45, 9,151,171,214,230,205,155, 85, 1,228,205, 37,203, 50,116, 58, 29, 56,142, 83, 28,
+ 71, 56, 28, 14,244,232,209,163, 86,176, 17, 93,147, 38, 77,134, 41,226,138,231,121, 44, 91,182, 12,201,201,201, 72, 74, 74,130,
+217,108,134,209,104,188,146,188, 71,116,116, 52,190,250,234, 43,196,197,197,161, 65,131, 6, 16,132,223,139,158,236,114,163,220,
+106, 71,198, 45,139, 48,122,109, 39,196,155, 37,184, 92,242, 13, 95,185,236,118,123,252,158, 61,123,212,239,189,123,247, 54,183,
+107,215,238,167, 64,231,107, 21, 96,178, 44, 39,108,217,178, 5, 6,131, 65, 91,231, 46,203,232,216,177, 99, 66,136,114,157,158,
+144,144,176,164, 75,151, 46, 98, 98, 98, 34,111, 48, 24, 96, 50,153, 16, 27, 27, 11,189, 94, 15,183,219, 93,223,229,114,213,183,
+217,108,119,158, 63,127, 94,254,226,139, 47,222, 32,132, 60, 68, 41, 93,115,147,137,171, 91, 82, 82, 82,254, 1, 0, 5, 5, 5,
+ 47, 24, 12,134,227,145, 18, 89, 10,106,212,168,129, 26, 53,106, 32, 45, 45, 13, 67,135, 14,141,109,219,182,237,223, 27,216,108,
+143,231, 3,246,128, 74,128,227,234,238,223,191, 63,193,107,192,198,223,122,235,173,231,252, 25, 94,158, 54,224,212,209,163, 71,
+ 59,132,136, 43, 87,171, 86,173,119, 6, 12, 24,112,255,188,121,243,162, 1,224,223,255,254, 55, 6, 14, 28,136, 90,181,106,193,
+ 96, 48, 64,146, 36, 72,146, 4, 81, 20,213,119,175, 78,218,175,150,175, 85,171,214,180,129, 3, 7,222, 55,119,238,220,104, 0,
+248,232,163,143,144,158,158,142,132,132, 4, 68, 71, 71, 35, 42, 42, 10, 58,157,174, 10,183, 23, 39,213, 18,206,233,157, 59,163,
+ 55, 0,241,223,255, 70,108,108, 44, 82, 71,142,132, 94,146,192,239,218,133,152,152, 24,111, 78,205,113,207,205,205,197,185,115,
+231,252,198,157,231,121, 68, 69, 69, 85,218,143, 21, 21,129, 92, 33, 53,238, 10,231,162, 69,139,212,184,155,205,102, 63,113,231,
+ 66,185,139,124,173, 90,181,166,165,167,167,223, 55,127,254,124,149,179, 79,159, 62,136,143,143, 71,116,116, 52, 36, 73,130, 78,
+167,243,151, 71,215,132,147, 65,163,192, 82,214, 70,153, 76,166,206, 31,124,240, 1,120,158, 87, 59,200,168,168, 40,181,112,232,
+116,186,176,109,232,140,140,140, 30, 11, 22, 44, 80, 57,109, 62,231, 92,137,104,243,226,239,117,231,157,119, 46, 90,181,106, 85,
+148, 32, 8,184,116,233, 18, 54,111,222,140,216,216, 88, 24, 12, 6, 12, 27, 54,140,235,213,171, 87,124,175, 94,189,150, 16, 66,
+ 70, 83, 74,191,187,154, 68,163,148,170, 98,195,100, 50,193,100, 50,105,117,114,176,114,229, 74, 8,130, 80,165,224,122, 87,100,
+229,123, 98, 98,162, 86, 71, 10,219,182,109, 3,199,113,234,245,162, 40, 98,213,170, 85,120,254,249,231,113,238,220, 57,245, 55,
+ 13,225, 36, 70,163,209,160,136, 43,143, 3,168, 52, 54, 68, 16, 4,226, 57, 78,195, 89,100, 42, 8, 2, 46, 94,188,136,154, 53,
+107, 34, 46, 46, 14, 81, 81, 81, 85, 42,172,211,229, 70, 65, 81, 41,134,127,219, 6,101,214, 18,148,148, 18, 56,156,206,155,174,
+178,125,240,193, 7,146, 44,203,138,224, 86, 93, 65,143, 43,133,199, 31,127, 60, 94, 43,151,193, 96,192,154, 53,107,212,178,164,
+116, 2, 74,163,232,125,188,110,221,186, 90,202,209,171,203,151, 47,143, 90,186,116,169, 58,216,209,233,116, 48,153, 76,136,137,
+137, 65,108,108, 44,226,227,227,145,144,144,128,182,109,219,242,143, 62,250, 40,223,173, 91,183, 87, 1,220, 52, 2,139, 16, 18,
+ 99, 48, 24, 38, 46, 95,190, 92, 2,128,190,125,251, 78,180, 90,173,207, 2, 40,185, 90,145,197, 3,203, 8, 33, 15,122,242, 78,
+223,175, 95, 63,221, 63,255,249, 79,220,118,219,109, 24, 55,110, 92,252,187,211,166, 13, 6,176, 34, 88,155,227,141, 89,179,102,
+197, 42,101, 72, 25,172, 41,175,178,178, 50, 60,247,220,115, 33,219,100, 0, 92, 74, 74,202, 95,254,245,175,127,153,149,227,241,
+241,241,151,181, 69,190,239,129, 92, 82, 47, 87,232,145,249,243,231,171,156, 9, 9, 9,106, 27,167,188,126, 61,248, 19, 54, 44,
+158, 1, 83,124, 45,140,124, 97,106,216,225,236, 8,160, 35,199,193,221,186, 53, 12, 6, 3, 18,140, 70, 64,146,224,246,136, 43,
+ 45,225,244,229,228,121, 94,141, 39,165, 20, 21, 21, 21, 40, 45, 45,133, 44,203,176,219,237,104,223,190, 61, 8, 33,184,229,150,
+ 91, 2,185, 66,151,197,189,102,205,154,151,197,221,187,157,246, 30,104, 6,226, 76, 73, 73,121,228,131, 15, 62,240,155,158,130,
+ 32, 64,146, 36, 44, 90,180, 72,147,147, 29, 14,103,152,249,206,160,197,193, 82, 70, 38,121,121,121,216,189,123, 55, 68, 81, 68,
+ 82, 82, 18, 58,118,236,168, 88,211, 16, 4, 1, 28,199, 97,240,224,193,229,190, 23, 75,146, 84,248,217,103,159, 53,240, 52, 10,
+202, 29, 6, 28, 0,172, 95,191, 30,171,210,211, 97, 3,208, 48, 43, 11,173, 50, 50,112, 72,167, 3, 15, 32,169,168, 8, 60,207,
+251,229,244, 94,155,229,231, 78, 8,179,201,100,154,151,147,147, 19, 37,203, 50,138,138,138, 0, 0, 25, 25, 25,224,121, 30,191,
+252,242, 11, 38, 79,158,140, 47,190,248, 2,171, 87,175,214, 55,107,214,108, 30, 33,164, 29,165,212,226,197, 95,133,243,158,123,
+238,201,115,187,221,117,252, 37,152, 36, 73, 0,128,232,232,104,232,245,122,152,205,102,191,194,197,223,221, 21,178, 44, 99,200,
+144, 33, 32,132,128,231,121,117, 61,146,119,101, 83, 62,239,221,187, 87, 19,167,219,237, 70,183,110,221, 0, 0, 38,147, 9,102,
+179, 25,223,125,247,187,126,108,215,174, 29,236,118, 59, 18, 19, 19,177,111,223, 62, 77,156,103,206,156,193,146, 37, 75, 32, 73,
+ 18,226,226,226, 32,138,162,180,126,253,250,215,140, 70, 99, 12,207,243,136,139,139, 67, 70, 70,198, 44,101,253,156,219,237,150,
+ 87,173, 90, 21, 29,136, 83, 16, 4, 88,173, 86, 85, 96,197,197,197, 85,117,226,220, 46,156, 58,119, 17,105,173,108,232,221, 67,
+ 66,206,234, 50,236,216,224, 14, 25,206,171,197,181,224, 60,113,226, 4,142, 28, 57,162, 78,175, 42,211,225,223,175, 95, 18,119,
+ 52,111,151, 73,233, 56, 41,165,208,185, 46,161, 75, 43,178, 19,110,124,182,125, 63,125, 39, 84, 56, 5, 65,128, 44,203, 88,189,
+122, 53,142, 31, 63,142,245,235,215,163,162,162, 2, 53,107,214, 68,108,108, 44, 58,119,238,140, 71, 30,121,196,175,192,242,229,
+148,101,121, 9, 33,164,245,200,145, 35,201, 55,223,124,131,162,162, 34,148,150,150,194,225,112,192,225,112, 64, 20, 69,117, 64,
+145,146,146, 2,142,227,104, 69, 69,197,146,155, 33,143, 60,237,136, 0, 96,194,251,239,191,159,208,190,125,123, 0,192,251,239,
+191,159,240,200, 35,143, 76, 0,240, 42, 0,215,149,132,211, 0,212, 65,229,197,171, 81,249,194,235, 86, 43,121,115,229,202, 33,
+ 0, 70,125,249,229,151, 24, 49, 98, 4,222,153, 54,173,149,175,192,242,230,116,187,221,216,181,107, 23,118,238,220, 9,151,203,
+ 5, 89,150,213,119,239,207,202,123, 32, 49,232, 19, 78, 98,177, 88, 42,118,238,220,105, 94,184,112, 33,226,227,227,209,160, 65,
+ 3,213,101,242, 21, 3,202, 43, 84,220, 45, 22, 75,197,190,125,251,204, 75,150, 44, 65,124,124, 60,234,215,175, 15,163,209,168,
+114, 74,146,132, 61,223,173,194, 19,163,238, 65,225,209,159, 48,235,217, 7, 52,135,115,122,231,206,232, 12,192, 52,111, 30,202,
+154, 55, 71,195, 62,125, 32, 72, 18,108, 63,254, 88, 25,190,222,189, 65,117, 58,136,219,183,107,230,220,181,107, 23, 40,165, 72,
+ 77, 77,133,213,106, 69, 76, 76,140, 26,214,117,235,214,225,238,187,239,198,226,197,139,209,185,115,103, 77,113,223,187,119,175,
+ 26,247,122,245,234, 93, 22,119, 69,196, 52,108,216, 16, 23, 47, 94, 68,163, 70,141,130,114,150,149,149, 85,228,230,230,154, 23,
+ 47, 94,140,248,248,120,212,173, 91, 23, 70,163,177,138, 19,246,250,235,175, 87,225,104,221,186,245, 85,115,134,155,239,215, 0,
+183, 3,240,118, 30,236, 0,116, 94,239,133, 0,118,249, 57, 79, 57, 46, 2,104,227,249, 77, 6, 80, 10, 32,214, 15, 95, 32,158,
+ 34,143,195,154,232,115,190,239,255, 84, 21, 88,132, 16,165, 54,246, 4,240, 61, 0, 52,107,214, 12,197,197,197,136,138,138, 66,
+199,142, 29, 81, 88, 88,168, 90,135,110,183, 27,183,221,118, 27,222,126,251,109,112, 28, 7,167,211, 9, 74, 41,120,158,199,189,
+247,222,235,207,122,113, 3,192, 29,119,220,129,223, 60, 7, 90,101,100,160,110,221,186, 56,233,229,196,164,165,165, 97,210,164,
+ 73,234,180, 22,165, 20, 86,171, 21, 15, 62,248, 32, 31,196, 29,121,234,163,143, 62,138,145, 36, 9,103,206,156,129, 50,210,148,
+ 36, 9,199,142, 29,195,204,153, 51,241,200, 35,143,224,248,241,227,168, 95,191, 62, 38, 78,156,104,158, 56,113,226, 83, 0,178,
+130, 52,150,201,159,127,254,185, 90,168,236,118, 59, 74, 75, 75, 81, 90, 90,138,197,139, 23, 3, 64, 21, 7, 75,235,180,153,219,
+237,198,234,213,171,253,142, 14,125, 71, 12, 90, 71, 11,110,183, 27, 59,119,238, 84,197,153, 32, 8,170,251, 68, 8,193,254,253,
+251,193,113,156, 42, 12, 67,245, 61, 74,220,146,147,147, 97, 48, 24, 32,138,162,244,195, 15, 63, 76,174, 85,171,150,105,212,168,
+ 81, 40, 45, 45, 69, 74, 74, 10,250,247,239, 15,183,219, 13,135,195, 17,114,237,156, 32, 8, 32,132,160,102,205,154,136,137,137,
+241, 51,213, 41, 99,208,144,139, 0, 42,195,152, 49,192,132,255,204,186, 57, 70, 48, 78,167, 19, 21, 21, 21, 85,196,213,246, 77,
+159,198,237,248,254,155,184,220, 93,155, 42, 51,249,208,221,191,119,199, 48,180,108,251,240,111,169,173,110, 37, 63,236,205, 11,
+ 62,157,205,243, 60,198,143, 31,143,204,204, 76, 12, 31, 62, 28,235,215,175,199, 75, 47,189,132, 71, 30,121, 68,235, 8,217, 59,
+156,255,121,248,225,135,255,178,124,249,242, 91,199,143, 31,207, 41,117,210,104, 52,130, 16, 2,155,205, 6,171,213,138,138,138,
+ 10, 28, 60,120,208,253,232,163,143, 30,182,219,237,255,185,137, 6,155,143, 63,247,220,115,205, 31,122,232, 33,245,192, 67, 15,
+ 61,132,253,251,247, 55,159, 49, 99,198,227,253,250,245,123, 63, 92, 23,203, 0,212,173, 81,171,214, 12, 0, 48,156, 61,251,156,
+ 21, 56, 5, 0,111, 2,233, 50,112,247,218,181,107, 1, 0,245,235,215,135, 27,104, 78,128,143,120, 96,153, 11,248,214,159,131,
+229,114,185, 80, 81, 81,113,153,152,242,247, 30, 42,156,148, 82, 74, 8,113,243, 60,143,180,180, 52,164,167,167, 67,167,211,193,
+108, 54,171,237,188,111,155, 20,168,163,245,109,146,120,158, 71,147, 38, 77,208,167, 79, 31, 72,146, 4,147,201,164, 14, 72, 21,
+135,181,117,183,190, 88,182,248, 29, 60,156,222, 18,255,215, 61, 25,159,237, 45,210, 20,206, 59, 57, 14, 93, 37, 9,150,102,205,
+ 16, 29, 29, 13,206, 96, 0,241,154,202,162, 70, 35, 56, 31,135, 60, 88, 56,211,210,210,112,246,236, 89,228,231,231, 35, 63, 63,
+ 31, 28,199,161,107,215,174,208,233,116, 16, 4, 1,121,121,121,120,227,141, 55, 96,183,219, 67,113, 82, 0,110,142,227,208,164,
+ 73, 19,244,238,221, 27, 58,157, 14, 70,163,241,178,169, 65, 81, 20, 81, 90, 90,138,198,141, 27, 99,229,202,149,184,243,206, 59,
+ 67,114, 54,111,222, 28, 61,123,246, 84,103, 20,148,165, 58, 74,122,122,196,157,154, 14,222, 55, 37,105,225, 92,254,131, 13,175,
+255,247, 44,202,237,133,248,173,220, 93,101, 6,184, 94, 77, 61, 78, 44, 25, 88,221,238,177,170, 65, 40,165,155, 2,156,150, 72,
+ 8,201,241, 42, 27, 25,132,144, 28,239,247, 64,231,121, 62,118,159, 48, 97, 66,135,236,236,236, 41, 93,186,116, 89,182,109,219,
+182,165,129,248, 2,241, 76,152, 48,161,101,118,118,246, 20,239,243,253,252,207,229, 14, 86,101, 57, 38, 20, 94,187,187,215,169,
+ 83, 71,157,119, 54,155,205, 85, 58,105,151,203,133,255,252,231, 63, 72, 74, 74, 82,215,232, 36, 39, 39, 7,172, 36,138,219,113,
+159,103,173,210, 65, 73,194, 73, 0, 45, 60, 13,129,203,229,130,195,225,192,138, 21, 43, 16, 29, 29,173, 86,116,179,217, 28, 52,
+ 99,116, 58, 93,247, 59,238,184,131, 43, 45, 45, 85, 69,137, 40,138, 56,118,236, 24,222,125,247, 93, 60,244,208, 67,104,220,184,
+ 49,100, 89, 70, 73, 73, 9,122,246,236, 41, 24,141,198,238,193, 4,150,226, 76,127,254,249,231,234,212,165,210,120, 41, 80, 4,
+150,214,117, 48,138, 24, 26, 50,100, 8,120,158,247,235, 90,121, 55,104, 91,182,108,209,204,217,185,115,103, 24,141, 70, 53,189,
+190,253,246,247,246,185, 99,199,142,160,148, 34, 49, 49, 17,223,127,255,125,200, 70,183,109,219,182,112,187,221, 72, 74, 74,130,
+ 36, 73,100,253,250,245,175,121,196, 21, 17, 69, 17, 63,254,248, 35,246,239,223,143,196,196, 68,152, 76, 38, 77, 83,187,165,165,
+165, 69, 35, 70,140,112, 41,194, 15, 0, 74, 74, 74,206,252,222,185,219,139,239, 29,240,153, 79, 88, 28,197, 55, 67,175,237,112,
+ 56, 80, 94, 94,142,195,135, 15,195,106,181, 66,150,101, 28, 61,178, 79, 55,229,141,113,228,245,231,187, 2, 0, 94,155,125, 6,
+214,173,181,213,107,118,124,249, 87,115,175, 7, 22,125, 12, 32, 53, 24,183,213,106,133,195,225, 64,106,106, 42,114,115,115, 81,
+ 86, 86,134, 62,125,250, 92,230,144,106,116,117,236,132,144,222,131, 7, 15,222, 50,125,250,244,134, 45, 90,180, 32,101,101,101,
+ 40, 43, 43, 67,121,121, 57,148,207,251,246,237,163, 75,151, 46, 61, 94, 94, 94,222,139, 82,106,191, 73,166, 6, 7,246,235,215,
+175,255,219,111,191,125,217,111,111,191,253, 54, 14, 28, 56,208,127,237,218,181,249,183,222,122,235, 55, 90, 69, 86, 3, 64,231,
+ 18,197,151, 62,253,244, 83, 9, 0,122,247,238,253, 82, 3,167,243,249,124,192,222,162, 85,171,251,182,109,219, 86, 67, 25,152,
+213,168, 81, 3,148, 82,190,188,188,188,198, 29,119,220,113, 31, 2, 8, 44,167,211, 9,171,213,170,254,191,247, 20,161,247, 98,
+100,142,227, 96, 54,155,227,110,189,245, 86,155,103,224, 91,118,240,224, 65,127,107,240,220,149,119,141, 1,181,106,213,130, 40,
+138,208,235,245, 85,214,223,132,114, 49,252, 64,174,236, 71,168, 58,237,244,243,247,171,113,241,200, 15,144, 8,133, 91,118,194,
+237,114, 64,118, 58,192,195,141, 3, 71, 79,163, 69, 74,200, 54, 68, 13, 39, 55,123, 54,228,142, 29,209,104,208, 32,112,162, 8,
+199,142, 29,149,142,208,192,129,128, 78, 7,227,230,205, 90,195, 89, 37,238,185,185,185, 24, 55,110, 28,166, 78,157, 10,131,193,
+160, 14, 84, 15, 30, 60,136, 79, 62,249, 4,253,250,245,211, 28,119, 66, 42,167, 90,149, 52,156, 48, 97, 2, 10, 10, 10, 48, 99,
+198, 12,116,232,208, 1,162, 40,226,226,197,139,184,227,142, 59,112,238,220, 57, 77,156,148,186, 17, 31, 31, 15, 81, 20, 17, 21,
+ 21,117,217, 26, 49,165,223, 11, 39,143,188, 57,159,189, 55, 10, 31,110, 61, 8,192,141,115, 75,186, 87,233,143,166,124,114,228,
+154,212, 67, 47, 13, 66, 66,156,151,161,145, 79, 57, 79, 73,228,168,236,236,236, 41,190,215,135,226,243,254,221,231,122,187,143,
+ 40, 59, 23,114,138, 80, 17, 67,110,183, 27,102,179, 89, 93,111,229,219,145, 42,191,121,143,110, 66, 53,230,110,183, 91, 45, 0,
+188,159,209,248,129, 3, 7,112,224, 64,213,155,105, 62,248,224,131,160,156, 46,151,235,182,184,184, 56,156, 61,123,214,187,113,
+193,107, 19, 39,226,255, 70,141, 82,197,149, 78,167, 67,102,102, 38,238,186,235, 46,216,108,182,219, 52, 52,186,234,186, 51,183,
+219,173, 58,117, 58,157, 14,111,188,241, 6,246,239,223, 95,101, 97,187, 78,167,147, 53,100, 56,214,172, 89, 19,210,193,146, 36,
+ 73,117,241,180,112,238,217,179,231,178,181, 56, 74, 99,251,191,255,253, 79,237,108,181,186, 98,178, 44,195,104, 52, 18, 73,146,
+136,209,104,140, 25, 53,106, 84,149, 53, 62,146, 36, 65,175,215,171,233, 19, 10, 67,134, 12, 9,218, 58, 61, 62,248,182,126,184,
+ 73,225,114,185, 96,179,217,112,233,210, 37, 76,158, 60,217,115,116,226, 89, 0,232,216,247, 53, 60,254,112,167,122, 62, 54,179,
+ 82, 2, 67,182,148,241,241,241, 88,188,120, 49, 68, 81, 68, 78, 78, 14, 98, 98, 98, 48,116,232, 80,196,196,196,224,197, 23, 95,
+196, 3, 15, 60, 16,214,226, 84, 74,105, 9, 33,164,207,115,207, 61,183,101,218,180,105,245,234,215,175, 15,135,195, 1,187,221,
+ 14,135,195,129,163, 71,143, 98,217,178,101,167,202,203,203,251, 80, 74, 75,110, 18,113, 85,247,214, 91,111,253,235,226,197,139,
+225, 61, 0,240,110,151, 22, 47, 94,140,110,221,186,253, 53, 47, 47,239, 23, 0,249, 90,120, 79, 2,143,191, 51,117,106, 61,101,
+250,126,234,212,169,245,254, 62,126,252,227, 0,222, 59,176,119,239,199, 99,198,140,121,110,249,242,229, 85,174, 25, 51,102, 12,
+ 14,236,221,251,113,160,122,174,184,161, 60,207,227,217,103,159, 13, 21, 4, 17, 0,108, 54, 27,250,244,233, 19,112, 64,213,162,
+ 69, 11,200,178,172,184,213,151, 45,108,246,110,223, 53,182, 31,202,102,149,234,160,252,196,174, 53, 24,255,196,112, 64,118, 1,
+142, 50,192, 81, 14,234, 40, 7,181,151,129,232, 12,160,206,138,144, 3, 63, 37,156, 49, 49, 49,149, 2, 72,175, 7,188,250, 31,
+ 98, 52,130,120,156, 43, 45,225,244,141,251,137, 19, 39,240,228,147, 79,194,110,183, 99,232,208,161,168,168,168,128,205,102, 67,
+ 69, 69, 5, 26, 54,108, 8,171,213,170,197, 17, 84,182, 51, 80, 93,192,231,158,123, 14, 29, 58,116,192, 27,111,188,129, 23, 95,
+124, 17, 13, 27, 54,196,227,143, 63,142,101,203,150,161,101,203,150, 40, 47, 47, 15,201,169,244,157,102,179, 25,130, 32,168,109,
+176,119, 94, 41, 2, 43, 84,220,131,113,130, 84,110,135,229,155,239,147,255,175,249,245, 86,103,115,180,136, 44,175,243,114,149,
+ 49,105,102,102,230,203,132,144,156,204,204,204,151,179,178,178,246,107,225, 11,240,251, 42,207,251, 32,175, 99,185, 33, 5,150,
+119,133, 86, 70, 51, 74,102, 40, 2, 70, 17, 88, 57, 57, 57, 88,177, 98, 69, 21, 1, 21, 74, 96, 29,240,100,110,115,207, 40, 76,
+249,222,204,237, 70,143, 30, 61,208,186,117,235, 42,238, 85, 40,135,136, 82,138, 3, 7, 14, 96,203,150, 45,184,235,174,187, 80,
+ 94, 94, 14,167,221,142,103,127,250, 9, 45, 70,142,132,221, 51,165, 25, 21, 21,133,119,223,125, 87,115,135,163,196, 63, 42, 42,
+ 74,181,231, 69, 81, 68,219,182,109, 33, 8, 2,126,252,241, 71,124,253,245,215, 97,221, 82,231,118,187,113,223,125,247, 85, 17,
+ 67,190, 2, 75,169, 60,171, 86,173,210, 28,206, 30, 61,122,192,108, 54,171,233,246,197, 23, 95,168,191,119,239,222, 29,132, 16,
+ 36, 37, 37, 33, 39, 39, 71,115, 56, 21,241,196,243, 60,202,202,202,144,155,155, 11,157, 78,167,174,207,208,235,245,106,250, 48,
+ 4, 23, 88,229,229,229,176,219, 43,205,158, 99,199,142, 85,249,221,238,184,114, 19, 72, 41, 71, 22,139, 5, 27, 55,110,196, 39,
+159,124,162,142,144,189,197,118,152,163,200, 34, 66, 72,223, 23, 95,124,113,227,155,111,190, 89, 59, 33, 33, 1, 74,181, 76, 0,
+ 0, 32, 0, 73, 68, 65, 84, 1, 14,135, 3, 39, 78,156,192,194,133, 11,207,148,149,149,245,165,148, 22,221, 68, 89, 68,243,242,
+242,138, 19, 19, 19, 21,123, 62,198,110,183, 19,207,160,137, 2, 80,132,100, 25, 0,135, 22,247, 74, 4,122, 14,189,239,190,222,
+222, 11,205,159,123,238, 57,236,216,177,163,183,184, 98,197, 62, 39,176,145, 95,177, 34,109,198,140, 25,234, 57, 51,102,204,192,
+231, 43, 86,108,144,129,141,193,202,146,213,106, 85,219,176,221,187,119,107,110, 35,130, 13, 36,149, 37, 21,129,214, 92,133,179,
+100,129, 82, 74,211,210,210, 42,215, 20,122,218,178,219,238,188, 7,211,223,251, 0, 81, 28,197,189, 61,154, 32,201, 44,128, 24,
+227, 33,245,200, 4,137,245,152,180,147,219,132, 28,240, 82, 74, 81,231,133, 23, 16,111, 52,194,230,113,170,164, 33, 67, 0,157,
+ 14,134,181,107, 33,138, 34,172, 35, 71, 2,146, 4,227,194,208,219,244,121,199,253,200,145, 35,216,186,117, 43,154, 53,107,134,
+195,135, 15,171,251, 84,113, 28,167, 14,176,181,198,221, 83,118, 32, 73, 18,206,158, 61,139,140,140, 12, 72,146,132, 15, 63,252,
+ 16,155, 54,109,194,139, 47,190,136, 49, 99,198,160, 87,175, 94,151, 25, 10,254, 56, 91,182,108, 89, 37,143, 2,173,143, 10, 39,
+143,252,113, 42,198,209,149,228,251, 53,173,176,191,187, 69,254,166,204, 6,249,113,158,110, 71,229,218, 40, 91, 86, 86,214,254,
+172,172,172, 12, 66, 72, 78, 86, 86, 86, 70, 16, 7,107, 80, 8,135,107, 16, 42,215, 92, 5,111,163,189, 10, 27, 69,229, 26, 44,
+ 21,193,110,207, 52,155,205,248,203, 95,254,130,151, 94,122, 9, 9, 9, 9, 72, 77, 77,213, 84,160,131, 97,211,166, 77,216,180,
+105, 83,149, 99, 43, 87,174, 12,122,141, 36, 73, 7,147,147,147,219, 61,240,192, 3,184,120,241, 34, 10, 10, 10, 16, 19, 19,131,
+ 22,239,188,131,189,127,251, 27,218,204,155, 7,174,119,229,157,239, 81, 81, 81,200,203,203, 67, 84, 84,212,193, 80, 65, 85, 92,
+ 59,101,171, 3,197,142, 87,210,133, 42,126,102, 24,139, 50, 40,165, 88,181,106, 85,208,181, 87,222,119,177,104,229,220,190,125,
+251,101, 14,150,146,222,202,111,202,130,104,173, 48, 24, 12, 84, 17, 88, 70,163, 17,241,241,241, 85,132, 85, 56, 14,214,207,217,
+217,107,121,131, 33, 65, 20, 69, 72,162, 8, 65, 20,225,176, 88,138, 83,159,122,170, 31, 0, 44, 92,184,112,171,201,100, 82, 55,
+ 34, 21, 69, 17,229,229,229, 69,247,221,119,223, 13,239,108,217,237,118,117,237, 82,152,141, 72,200,115, 28, 14, 7, 36, 73,194,
+ 87, 95,125,133,219,111,191, 29,237,219,183, 87,243, 90,153,226,208, 58, 69,232,243,223,167, 9, 33, 3,102,205,154,181,105,250,
+244,233,177, 22,139, 5, 11, 23, 46, 44, 41, 45, 45, 29, 64, 41, 61,125, 51, 9, 96, 79,124,254,226,213, 70,125, 12,160,134,231,
+107, 9,128,135,195,189,123,176,121,171, 86, 15, 47,244,211,193, 47, 92,184, 16,135, 15, 31,126, 24,123,247,110,172, 7,204,123,
+233,165,151, 26,183,111,223,190, 30, 0,188,244,210, 75, 39,235, 1,243,130,149, 7,197,193, 10, 53,144,245, 55, 96,210, 50,179,
+ 16,232,206,193, 43,237,100, 21,145,209,123,216,104,156,255,245, 8, 90,152,127, 67,114,156, 25,238,178,243,144,250, 76,198,222,
+223,140,152, 57,111, 77, 88,241,208, 69, 69,129,120,220, 54, 73,146, 0,131, 1,188, 94,255,123, 56, 61,107,178,194,225, 20, 69,
+ 17, 7, 15, 30,132,209,104,132, 44,203,151,137, 41,173,179, 9,222,121,165,184, 75,211,167, 79,199, 11, 47,188,128, 15, 63,252,
+ 16,123,247,238, 69,155, 54,109,208,183,111, 95,156, 63,127, 30, 63,253,244, 19,108, 54,155,230,112,122,247, 23, 7, 14, 28,192,
+186,117,235,112,232,208, 33,156, 60,121,242,138,242,199,151,211,183,223, 95,180,238, 87,140,238,151,122,205,234,162, 63, 13, 18,
+ 4,185, 62,238, 17,148,245, 80,138, 32,242,253, 14, 32, 78, 57,150,153,153,249,178,214,235,188,191, 43, 14, 88, 16,225,117,185,
+192,162,148, 18,127, 98, 72, 73,116,239, 10,170,124, 86,220, 18,147,201,132,212,212, 84, 77,149,158,231,121,212,183, 88, 20,129,
+162, 58, 87, 10,134, 15, 31,142,180,180,180, 42,107,176, 66, 85,110,155,205,182,229,187,239,190,107, 51,100,200, 16, 46, 47, 47,
+ 15,146, 36, 85,222, 86,219,165, 11,218,204,155,135,125,227,199,163,199,177, 99,168,112, 58,149, 91,219,157,229,229,229, 91, 52,
+100,182,186, 48, 81, 17, 17,202, 66,126,165, 50, 79,158, 60,217,239,190, 45,193, 42, 94,160, 17,162,247,139,227, 56,205, 98,200,
+237,118,171, 29, 41,207,243,234,139, 16,162,142,118,195,117, 49, 20,219, 92,225,229, 56, 14, 53,106,212, 80, 43,163,178, 6, 64,
+171,192, 18, 12,134,132, 89,195,135, 55,118, 78,156,136,232,185,115,225,122,254,121,188,222,181,171,250,187,201,100, 50,110,219,
+182,173,145,193, 96, 0,165, 20,133,133,133,184,255,254,251,111,138, 93,199,101, 89, 86, 23,136, 71, 26,159,126,250, 41,142, 29,
+ 59, 6,135,195,129,183,222,122,171,138,184,242,126, 93,161,240, 56,218,174, 93, 59,247,128, 1, 3,176,125,251,118,232,245,122,
+ 39,165,244, 40,243, 36, 67,227,231,189,123, 87,152, 76,166, 7, 1,152, 47, 94,188,200,215,168, 81, 3, 70,163, 17, 86,171,245,
+ 18,239,185, 83, 48, 31,176, 27,156,206,169,247,223,127,255, 12, 0, 16,156,206,169,193,246,193,186, 26,129, 21,202,193,242,238,
+ 84,175,212,185,242,199, 41,138, 34, 4,158,199,178,233,175,162,133,185, 24,237,110, 49,161,162, 40, 31, 81, 49, 53, 65, 98, 27,
+ 96,230,188, 53, 56,144,255, 91, 88,156,220, 39,159, 64,174, 87, 15,226,131, 15,130, 68, 69, 65,159,147, 3, 73,146, 96,253,203,
+ 95, 64,116, 58, 24, 23, 44,184,162,112,150,151,151, 7,116,170,180, 58, 88,190,156,146, 36,161, 93,187,118,104,210,164, 9, 54,
+110,220,136,118,237,218,225,240,225,195, 56,124,248, 48,242,243,243,177,119,239, 94, 92,184,112, 65, 51,167,146, 71,159,124,242,
+ 9, 10, 11, 11, 33, 73, 18, 74, 74, 74,112,252,248,241,128,235,159,195,201,119, 5, 81,131, 42, 55,210,174,159,104,184,102, 2,
+203,159, 6,241,131, 34,159,181, 78,202,119,187,143,216,241,253,238,123, 62, 0,156, 7,192,135,184,206,247,123, 81, 86, 86,214,
+ 70,197,249,242,240,242,129,214, 95, 85,113,176,124,251,133,123,238,185,231,178, 94, 57, 42, 42, 10,247,220,115, 15,120,158, 71,
+108,108, 44,106,212,168,129,166, 77,155,134,220,100,211, 35,174,228, 17, 35, 70, 92,198,169,215,235,113,239,189,247, 98,233,210,
+165, 0, 0,223,117, 9, 95,125,245, 85,168, 41,152,217,127,249,203, 95, 70,247,233,211, 39, 54, 37, 37, 5,103,206,156, 81,239,
+116, 36,189,122,161,251,209,163,176,203, 50, 76, 38, 19,142, 30, 61,138,217,179,103,151, 57, 28,142,217,161, 50,219, 91, 96, 41,
+110, 13, 33, 68,237,176, 8, 33,244,192,129, 3, 97,183, 62, 90,196, 85,184, 80, 68,149,183,200,122,226,137, 39,212,239,225, 52,
+146,146, 36,209, 65,131, 6,169,207, 32,140,139,139, 67, 66, 66, 2,206,157, 59,167, 54, 26, 38,147, 73, 21, 87, 90, 4,150,168,
+211,193,245,218,107, 16, 26, 52,192,175,123,246,160, 97,124, 60,248,230,205,171,140, 16, 45, 22, 11,210,211,211, 33, 8, 2,230,
+206,157,123,197,194,224,122,131,114,247, 96,106,106,106, 68, 55,171,116, 56, 28,120,236,177,199,252,174,127, 84, 22, 61,187,221,
+110, 56,157, 78,173,119,144, 94,145,139,118,179, 35, 53, 53, 53, 96,253, 9,148, 62,202,150, 12, 60,240,230,175,191,254,218,170,
+ 70,141, 26,232,223,191, 63,190,254,242,203,175, 38,122,237, 27,102, 5, 78, 25,206,158,125,214,243,249,116,168,188, 80,238, 34,
+140,124, 62,146,203,220,171,171,157, 30, 34,164,242,206,229,111, 23,189,135, 22,166, 66,180,169, 31,133,173, 59,126, 66,167,122,
+ 20,212, 38, 93, 41, 43,204,102,115,101, 59,105, 50,169,119, 15, 18, 66, 64, 12, 6, 32,204,253, 25, 21, 78,165,126, 40,109,239,
+213, 58, 88, 74,220,149,116,124,244,209, 71,241,210, 75, 47,161,127,255,254, 56,124,248, 48, 54,111,222,140,188,188, 60,140, 27,
+ 55, 14, 45, 91,182, 68,122,122,186,166,112, 42,124, 95,124,241, 5, 46, 93,186,164, 14, 70, 43, 42, 42,240,218,107,175, 93, 81,
+220,189,243, 93, 21,148,107,135, 1, 0, 62, 92,123,226,122,171,142, 63,132,248, 30,238,245,213, 14,191,189,216,215, 95,127,237,
+247,153,122,131, 7, 15, 46,191,251,238,187,113,232,208, 33,152, 76, 38, 52,109,218, 20, 54,155, 45, 96,103,232,253,180,237, 47,
+191,252, 50, 32,231, 61,247,220,131,134, 13, 27, 86,113,174, 2,109,125,224,251, 4,111, 74,169,133, 16,242, 84,247,238,221, 63,
+ 88,191,126,189,190,101,203,150, 40, 46, 46,134,219,237,198,132, 9, 19,240,254,251,239,195,100, 50,225,248,241,227, 24, 52,104,
+144,213, 98,177, 60,229,189, 7,150, 63, 78,143,112,171, 34, 34,148,233,194, 42,114,186,168,136, 4, 25, 33,248,125,210,248,172,
+ 89,179, 48,127,235, 86,140,245,114,112,252,225,253,247,223,215,196, 73, 41,197, 59,239,188, 19, 49,206,157, 59,119, 46,244,201,
+159,217,233,233,233, 56,121,242,100,149,105,193, 96, 2,203,151, 83, 18, 4, 68,207,153,131, 83, 63,253,132, 70,183,221, 6,201,
+237, 6, 90,181,250,189, 16, 10, 2,234,212,169,131,183,222,122, 11, 53,107,214, 68, 82, 82,210,101,101,234, 90, 61,181, 62,146,
+156,162, 40,110,126,231,157,119,186,253,235, 95,255,226, 12, 6, 3,118,239,222,141,226,226,226,203,132,146, 42,148, 19, 6, 65,
+ 46, 94,229,201, 87,185, 44, 88, 56, 43, 42, 42, 48,123,246,108, 77,249, 62,127,254,252, 43,138,187,183, 83,162, 69,108,221,136,
+121, 20, 66, 92,197,156, 56,113,194,223,162,243,101,240,185,211,207, 31, 39, 1,246, 45, 93,186,180, 85,171, 86,173,148,186, 55,
+106,218,127,255,251,192,100,171,181, 2,168,220,124,212, 35,198, 66,134,147, 82, 74, 12, 6, 3,210,210,210,224,116, 58,195,114,
+177,188,207,245, 13,167,178,214,232,106, 6,122,254, 56, 57,142, 3,207,243, 56,186,237,107,100, 12,168,141,109, 59,243,176,254,
+148, 9,245,162, 10, 80,187,188, 16,238,194, 95,240,236,125,237, 48,115, 69,229,147, 14,246,238, 14,205, 73, 8,129,249,233,167,
+ 65,140, 70,232, 87,172,128, 40,138,176, 61,249,100,229, 26, 44, 79,219, 86,241,230,155,128, 78, 7,253,139, 47,106, 10,167,239,
+ 76,141,178, 28,196, 91, 92, 5,115,176, 2,197, 29,168,220, 54,225,194,133, 11,248,232,163,143,240,200, 35,143,224,252,249,243,
+ 56,126,252, 56, 14, 29, 58,132,101,203,150,105,238,227,124,243, 40, 51, 51, 19,207, 63,255, 60, 56,142, 67, 90, 90, 26, 38, 79,
+158,140, 46, 93,186,132,157, 71,190,249,238,139, 80,238, 85,117,212,205,155, 13, 97,219, 4, 28,199,161,102,205,154,234,230,154,
+222, 29,108,184,214,181,183,152, 49, 24, 12, 48, 24, 12, 85,182, 62,184,251,238,187, 67, 58, 88,158,198,103, 45, 33,100, 76,227,
+198,141,231,101,103,103,155,251,244,233,195, 39, 39, 39, 99,224,192,129, 56,113,226, 4, 86,173, 90,229,156, 49, 99, 70,185,197,
+ 98,121,156, 82,186, 65,107,163,228, 45, 34,252,236, 94, 79,155, 52,105,162,121,136, 39,138,226,175, 71,143, 30,109,240,238,187,
+239,114,101, 0,102,112,156,218, 8,113,158,207,222,248,238,187,239, 92, 58,157, 46,232, 29, 75, 58,157, 78,229, 44, 39, 4, 51,
+ 60,149,155,243,226, 14,151, 51, 16,188,167, 75,255,159,189,243, 14,143,162,248,255,248,123,118,175, 39,164, 64, 72,128, 36, 23,
+ 66, 2,132, 14, 73,104,130, 20, 21, 68, 65,138, 72, 81, 81, 17,148,162, 8, 95, 84,186, 72, 19, 65, 17, 84, 4, 5, 69,137,128,
+ 52, 11, 8, 34,189, 23, 41, 73, 40, 2, 9, 2, 9,164, 65, 10,169, 87,183,205,239,143,148, 95, 8, 41,119, 73, 20,196,121, 61,
+207, 61,151,219,221,188,119,118,103,118,246,189,159, 41, 91,252,156, 56, 82, 17,171,213,106,144,105,211,208,192,221, 29,106, 69,
+ 1,225, 56,160,224,101,170,133,235,207,159, 63,143,247,223,127, 31,106,181, 26, 63,255,252,243, 67,113,113, 25,141,198,183,111,
+222,188,185,190, 95,191,126,141,203,204, 67, 41,179,200, 92,133, 15,248, 13,145, 91,250, 20, 84, 94, 82, 86, 57,121, 17,127,232,
+208, 33,227,220,185,115,249,116,142,195,130, 98, 77,195,133,159,226,249,114,224,192, 1,217, 96, 48, 36, 84,229, 88,254, 67,209,
+ 44,115, 66, 66,130,135,209,104,196,149, 43, 87, 8,254,191, 63, 86,241,235,238,121,148, 50,149, 66, 73,252,129,109, 75,151, 46,
+125,122,248,240,225,181,154, 52,105, 82, 56,248, 68, 91,240, 65,193,204,238, 59, 29, 60,255, 91, 63,250,232,163, 87,126,248,225,
+ 7,109,225,245, 18, 23, 23, 87, 81, 52, 26,171, 87,175,182, 87,116, 19, 44,124,211, 67, 97,212,165, 50, 81,244,178,162,234,225,
+253, 70,225,203, 29,223,192,167,213,211, 24,220,247, 81, 28, 93,246, 10,134, 52,179, 64,216,244, 2, 90, 14, 94,139,136,105,249,
+209,155, 54,155,167, 57,116,239,209,187,187,131, 47, 24, 45,200,113, 28,224,226, 2, 82, 44,250, 66, 10,102,116,119,230,126, 86,
+104, 46,202, 58,110,103,207, 7,207,243, 8, 10, 10, 66,112,112, 48, 58,119,238,140,208,208, 80, 60,246,216, 99, 56,119,238, 28,
+206,157, 59,135,241,227,199, 59,253,202,177,226,121,244,228,147, 79,226,169,167,158,170,114, 30,149,204,119,198, 3, 98,176,188,
+189,189,161,213,106, 43,109,168, 74, 98,183,219,139,140,149,193, 96, 40, 10, 77, 59, 98,174,138, 85, 64,251, 9, 33,109,223,125,
+247,221, 55, 13, 6, 67,215,194,169, 24,116, 58, 93,140,197, 98, 57, 44, 8,194,114, 74,105,182,227, 15,101,228, 46, 67, 81,202,
+ 6,200,202,202,114,216, 96,201,178,220,227,127,255,251,223,126,155,205, 22,232,200,246, 6,131, 33,201,100, 50,245, 40,111, 27,
+ 81, 20,123, 76,152, 48,161, 90, 53,203, 72,251, 93,166,170,240,219,209,190, 93,106,141, 6,218,201,147,193, 9, 2, 8,199,129,
+150,136, 96,169,213,106,120,122,122, 98,235,214,173,240,242,242,122,104, 46,174,205,155, 55,203, 0,134,148,183,205, 35,173,200,
+ 73, 0, 45, 30, 25,252, 91,218,197,235, 52, 48, 52,132,196,255,177,117,148,119, 5, 15, 36,143,127,242,201, 39,123, 5, 65, 8,
+112, 36, 29, 90,173,246,166, 32, 8, 78,231,187,162, 40, 36, 37, 37, 5,139, 22, 45, 50,101,100,100, 28,255,143,212,137, 43,123,
+244,232,241,254,222,189,123, 85, 70,163,177, 74, 66,241,128, 93,107,179,125, 18, 22, 22, 54,121,250,244,233,158,125,251,246,133,
+209,104,132,135,135,135,211, 90, 9, 9, 9,163, 1,212,233,218,181,107,239,194, 73, 25, 11,235,223,226,111, 3, 40,252, 46, 24,
+127,163,200,178,124,225,214,173, 91,237,202,169,232,138, 30,198,170,203, 92, 21,206,195, 6, 0, 79, 12,122, 21, 79, 12,122,181,
+ 40, 93,251,126,236,142,200,164,221, 8,231,146, 96,251,250, 81, 16,247,194, 34,204, 85,168,201,113, 28, 12,235,214,221, 53,141,
+141,225,147, 79,238,126,248,120,251,109,167,210, 89,252, 65,180,186,250, 96,241, 60,143,244,244,116,196,198,198,226,246,237,219,
+ 48,155,205,184,116,233, 18,236,118, 59, 50, 51, 51, 81, 56,210,176, 50,233,172,206, 60,170,110, 77, 70, 21, 13,150, 70,163, 73,
+ 27, 52,104,144,119, 69,219, 56,233,246,229, 87, 95,125,181,220, 59,181,171,171,171, 67, 61,190, 11, 12,212,124, 0,243, 11,222,
+ 97, 5,171,213,234,244,163,183, 90,173, 78, 29, 52,104,144, 79, 5,199,153,133,252,233,246, 29,226,228,201,147,169, 0,154, 87,
+103,230,253, 29,154,165, 92,136,242,232,209,163,203,205,159, 26, 53,106,148,123, 30,236,217,217, 25, 83,142, 28,201, 55, 85, 45,
+ 90, 0,173, 90, 33,239,206,157,140,194, 41,100,115,115,115,211, 95,122,233, 37,169,120,179, 96,241,137, 72, 31,106, 40,174,135,
+181,172,231, 19, 29, 75, 3, 1, 32, 58, 54,223,100,233, 52,184, 94, 65,190,183,252,187,147,150,156,156,124,190, 69,139, 22,127,
+101,102,102,126, 74, 41, 77,252, 79,100, 7,165,103, 9, 33,115, 27, 54,108, 56, 26, 64, 89, 97,134, 13,142, 70,244,236,192,165,
+ 58, 86,235,216,217, 51,103, 62, 55,107,230,204,198, 10,224, 5, 64, 15,228, 55, 17, 58, 25, 65,236, 87,221,199, 43,203,114, 98,
+167, 78,157,156,254,159,138,214,151, 51,147, 56,126,128, 17, 56,227,188,230,223,145,206, 66,205, 86,173, 90,161, 77,155, 54, 69,
+223,133, 20, 95, 30, 26, 26, 10, 89,150, 19, 37, 73, 42, 87, 51, 44, 44, 12,205,154, 53, 43,115,134,246,146,125,174,238,247,177,
+ 23, 82,248,114,157,208,208, 15, 43,165,201, 40,229,254,249,119,134,254, 31,182, 62, 25, 76,147,105, 50, 77,166,249, 32,104,146,
+138, 66, 62,247,248,248,252,215,149, 85,167,102,177,132, 54,103,121,196, 52, 25, 85,140, 96, 49, 24, 12, 6,227,254, 83,104,152,
+ 30, 4, 77,194,178,131,193, 40,243,218, 40,181,169,193, 25,103, 74, 8,113,186,185,162, 34,125,166,201, 52,153, 38,211,100,154,
+ 76,147,105, 62,124,154, 21,105, 63, 44,145, 49,214, 68,200, 52,153, 38,211,100,154, 76,147,105, 50,205,251,174,249,176,193,134,
+ 14, 48, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12, 6, 51, 88, 12, 6,131,
+193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48, 30, 24,200,127,232, 29, 99, 12, 6,131,193, 96, 48, 24,255, 8, 44,130,
+197, 96, 48, 24, 12, 6,131, 81,205,168, 0,160,240,229,161, 0, 64, 41,101, 19,243, 50, 24, 12, 6,131,193,248, 71,120, 88, 61,
+136,138, 25, 43, 6,131,193, 96, 48, 24,247,147,135,209,131,112,165, 57, 72, 6,131,193, 96, 48, 24,140,127,138,135,209,131,112,
+ 15,179,123,100, 48, 24, 12, 6,131,241,224,243,208, 71,176, 88, 20,139,193, 96, 48, 24, 12,198, 63,205,195,232, 65,216, 52, 13,
+ 12, 6,131,193, 96, 48, 24,213,204,223, 58, 77, 3, 33,164, 37,211,100,154, 76,147,105, 50, 77,166,201, 52,153, 38, 51, 88, 12,
+ 6,131,193, 96, 48, 24, 12,102,176, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193, 96, 6,139,193, 96, 48, 24,
+ 12, 6,131,193, 12, 22,131,193, 96, 48, 24, 12,198,125,130, 0, 40,117, 36, 0,165,244,130,195, 34,149, 24, 77, 80,145, 62,211,
+100,154, 76,147,105, 50, 77,166,201, 52, 31, 62,205,138,180,157,241, 31, 15,180,193,250, 59,231,193, 34,132,180,172,238, 19,197,
+ 52,153, 38,211,100,154, 76,147,105, 50,205,135, 79,243, 97,131, 53, 17, 50, 24, 12, 6,131,193, 96, 84, 51, 42,118, 10, 24, 12,
+199, 8, 15, 15, 55,232,116,186, 39, 14, 28, 56,160,185,116,233, 18, 78,157, 58, 69,215,173, 91, 39,218,108,182,125,145,145,145,
+ 22,118,134, 30, 14,218,180,105,211,131,231,249,119, 0, 64,150,229,197,103,207,158,221, 91,133,167,124, 18, 28, 28,252,134, 78,
+167,235,165, 86,171,235,201,178, 76,108, 54, 91,138,217,108,222,151,156,156,188,148, 82,170, 84, 66, 51,220,203,203,235,181,150,
+ 45, 91, 54,188,118,237, 90, 98, 66, 66,194, 6, 0,123, 1,244, 48, 26,141,207, 7, 7, 7,251, 95,184,112,225,106, 70, 70,198,
+ 42, 74,105,228,253, 74, 39,131,193, 12,150, 99, 23, 31,231,238,238,254,152, 90,173, 30,101,177, 88,218,232,245,250, 63, 57,142,
+ 91,149,158,158,190,139, 93,120, 15, 47,132, 16,190, 94,189,122,143,251,248,248, 76,200,201,201,233,224,233,233,121,230,206,157,
+ 59,159,221,184,113, 99, 47,165, 84,174,164, 38,231,226,226,210, 93,165, 82,141,180,219,237,225, 58,157,238,188,162, 40,223,230,
+230,230,238,185,159,101,169,115,231,206,231,101, 89,246, 43,111, 27,157, 78,167,222,191,127, 63,255,203, 47,191,208, 31,126,248,
+225,206,243,207, 63,239, 58, 98,196, 8, 85, 68, 68,196, 74, 0,147, 75,110,223,177, 99,199,120, 81, 20,189, 29,217,191, 90,173,
+ 78,251,227,143, 63, 2, 89,169,187,255,240, 60,255,206,136,133, 7, 59, 43, 20,136,152,214, 29, 5,230,165, 82,132,133,133,125,
+211,191,127,255, 65, 33, 33, 33, 42, 69, 81, 32,138, 34,108, 54, 91,227,168,168,168, 46,187,118,237, 10, 3,240,146,147,215,207,
+211, 83,167, 78, 93, 62,119,238,220,218,106,181,154,136,162,216,126,227,198,141, 79,142, 29, 59,246,252, 87, 95,125,213,106,232,
+208,161, 53, 10,151,207,154, 53,235, 73, 66,200, 20, 74,233,230,127, 58,157, 12, 6,163, 2,131,229,238,238,222,208, 96, 48,140,
+118,115,115,235,213,168, 81,163,164, 17, 35, 70,156, 22, 4,225, 47,158,231,233,154, 53,107,198,219,237,246, 79,252,252,252,246,
+216,108,182, 21, 25, 25, 25,177, 78, 86, 20, 13, 1,140, 0,240, 36, 0, 95, 0,183, 0,236, 2,176,154, 82,122,165, 50, 7,227,
+239,239,223,194, 96, 48,188,205,243,124, 59,147,201,228,231,226,226,146, 2,224,116,110,110,238,103,201,201,201,103, 43,163,105,
+ 52, 26,131, 0,140,209,104, 52,157, 37, 73, 10, 84,171,213, 55, 69, 81, 60, 38,203,242,138,196,196,196,171,149,209,236, 84,223,
+189, 55,117,117, 91, 32, 16,189,191,201, 38,107, 92,181,188,168,161,182, 68,217,156,253,254,169, 27,185, 91,238,119,161,240,245,
+245, 13,169, 91,183,238, 91,141, 26, 53,122,174,126,253,250,154, 97,195,134,105,186,117,235,134, 67,135, 14, 61,186,110,221,186,
+246, 26,141, 70,104,223,190,253,207, 73, 73, 73, 75,147,147,147, 29,202,119,157, 78, 23, 92,163, 70,141,215, 93, 92, 92,122, 53,
+105,210, 36,101,220,184,113,177, 81, 81, 81, 49,173, 90,181, 74, 88,177, 98,197, 91,177,177,177,139,124,124,124,118, 91,173,214,
+111,114,115,115,175,252,211,199,108,179,217,130,143, 30, 61, 10,141, 70, 83,234,122, 69, 81, 48,120,240, 96,104,181, 90,172, 88,
+177,130,156, 58,117,106,174,197, 98,153,185,124,249,114,175,136,136,136,103, 75, 51, 88,162, 40,122,255,241,199, 31, 80,171,213,
+247,232,201,178, 12, 81, 20, 33, 73, 18,108, 54, 27,122,245,234,229,205,170,163, 7, 3, 74,105, 93, 10, 96,231, 57, 43, 0,120,
+ 86, 69, 75,175,215,135, 60,251,236,179,170,244,244,116,168, 84, 42, 8,130,128, 91,183,110, 33, 56, 56,152,183,217,108,141,157,
+213,107,210,164,201,107, 11, 22, 44,240,222,177, 99,135,176,110,221, 58,123,143, 30, 61,212, 35, 70,140,112,235,214,173, 91, 39,
+127,127,127,238,187,239,190,179,237,221,187, 87, 28, 54,108,152,246,195, 15, 63,244,222,185,115,231, 32, 0,155,255,233,116, 50,
+ 24,140,114, 12,150,139,139,203, 14,173, 86, 27, 48,120,240,224,195, 51,103,206,252,194,203,203, 75, 4,128,245,235,215,251, 14,
+ 25, 50, 36,229,205, 55,223,140,207,202,202, 82,205,157, 59,183,229,218,181,107,127, 50, 24, 12,183, 45, 22,203, 19, 14, 24, 43,
+ 2,224, 77,142,227,198,180,107,215,110,135, 44,203, 87, 15, 28, 56,176,240,137, 39,158,232, 15,128,158, 57,115,230, 39, 66,200,
+119, 0, 62,119, 52,162, 65, 8,225, 27, 52,104, 48,195,207,207,111,194, 87, 95,125,165,107,208,160, 1, 92, 92, 92,144,155,155,
+107,188,114,229,138,255,132, 9, 19,250, 4, 7, 7,127,229,225,225, 49, 39, 50, 50, 82,116, 80,147,248,249,249,141,115,119,119,
+127,127,241,226,197,250,144,144, 16,226,234,234,138,164,164,164,230,167, 79,159,110,246,217,103,159,189,108, 52, 26, 63, 76, 76,
+ 76,116, 56,157,221, 9, 81, 89, 27,214,254,181,102,227,118, 93,191,250,122, 21,169,235,226, 2, 53,199, 65, 20, 4,117,162,201,
+212, 96,220, 27, 99,214,118,108, 92,231, 68,158, 58,181,207,197,139, 84,184, 31, 5, 34, 56, 56,248,188,155,155, 91,192,179,207,
+ 62,171, 30, 60,120, 48,130,131,131,139,214,189,244,210, 75,120,233,165,151, 52,215,174, 93,211,108,222,188,249,149,181,107,215,
+190,208,160, 65,131,132,184,184,184,150, 21,152,171,237, 6,131,161,254,232,209,163,207, 78,158, 60,249,176,155,155,155, 0, 32,
+249,252,249,243,242,176, 97,195,254, 26, 57,114,100, 98,110,110, 46,102,204,152, 81,127,221,186,117,155,116, 58, 93,170,205,102,
+123,242,159, 62,118,189, 94,143,171, 87,175,222, 99,132, 82, 83, 83,145,145,145, 1,139,197,130,172,172, 44, 20, 60,225, 91, 21,
+ 69, 1,199,113, 64,254,104,220,178, 34, 83,136,141,189,215,131,138,162, 8,139,197, 2, 65, 16, 96, 23, 4,168,180, 58,116,237,
+209,243, 47, 66,177, 61,215,106, 94, 26,125,252,248, 77, 86, 61,221, 31, 56,142,187,182,237,240,213, 32, 0, 2,128,152, 42,202,
+ 41, 0,112,248,240, 97,220,190,125, 27,105,105,105, 72, 75, 75,131,209,104, 68,101, 34,182, 49, 49, 49,203,195,194,194, 72,116,
+116,244, 14, 0,171, 55,110,220,216,239,206,157, 59,159, 79,154, 52,169,230,162, 69,139, 50, 39, 79,158, 60, 1,192,175, 27, 55,
+110,124,169,117,235,214,189,207,157, 59,183,236,126,164,147,193, 96,148,211,201,157, 82, 90, 47, 32, 32,224,230,154, 53,107,186,
+142, 25, 51,166,105, 70, 70,134, 26, 0,188,189,189,109, 0,144,149,149,165,122,253,245,215, 91,124,251,237,183, 93,245,122,125,
+162, 44,203,181, 75,209, 40,109,132,193, 88, 23, 23,151,167, 46, 94,188,248,113,195,134, 13,245,243,231,207, 63,232,234,234,138,
+101,203,150,237,247,247,247,247,136,141,141,253,208,213,213,181, 11,128, 9,101,164,235, 30,205,192,192,192,233,131, 6, 13,154,
+112,236,216, 49, 93,235,214,173,225,230,230, 6,158,231,225,233,233,137, 14, 29, 58,144,195,135, 15,235,250,244,233, 51, 54, 59,
+ 59,123,190,163,154, 70,163,113,194, 51,207, 60, 51, 43, 50, 50,210,208,169, 83, 39,162, 86,171,145,157,157, 13,141, 70,131, 71,
+ 30,121,132,108, 88,183,206,208, 54, 52,116,186,209,104,156,233,168,166,173, 81,237,237, 67,198, 76,238,182,253,247, 93,196,199,
+199, 7,182,185,115,145,221,162, 5,108, 83,166,160, 78,221,186,216,182, 99, 39,121,230,165, 55, 58,185,137, 62, 59, 28,213,172,
+134,167,245,187, 52,173, 86,107,112,104,104, 40,127,252,248,113,219,213,171, 87, 45, 37, 71,153, 82, 74,113,241,226, 69,243,239,
+191,255,110,242,242,242,130,221,110, 15,170, 72,147, 82, 90,183, 75,151, 46, 98, 68, 68, 68,167,209,163, 71,171,111,221,186,117,
+ 2, 64,108,205,154, 53, 19, 1, 36,165,166,166,198,189,240,194, 11,126,107,215,174,125,188,118,237,218,201,148, 82,239,251,113,
+236,133,134,170,228,167,112,185,175,175, 47,182,111,223,142, 62,125,250,160, 99,199,142, 31,245,235,215, 79,119,234,212, 41, 74,
+ 8,249,221,153,116, 42,138, 2,139,197, 2,139,197,130,196,196, 68, 44, 89,186, 12, 39,143, 31,195,198, 53,223,251,142,123, 99,
+236,235, 30, 46,110,199, 67, 59,117, 10,248,167,143,157,105, 22,173, 79,202, 55, 87,196, 76, 41,189, 81, 89,205,103,159,125,182,
+121, 96, 96,160,207,166, 63,107, 34, 83,211, 4,178,218, 3,138,214, 19,178, 87, 91,252,165,121, 10,190,190,190, 62,129,129,129,
+ 29,156,209,164,148,238,143,138,138, 26, 64, 41, 93, 69, 41,149, 41,165,191, 76,158, 60,249, 13, 66,200,150,201,147, 39,191, 69,
+ 41,253,165, 96,121,196,217,179,103, 7, 81, 74, 15,223,143,116,178,178,196, 52,255, 6,218, 1,232, 83,240,105, 15,160, 67,137,
+223,218, 18,219,245, 40,227,187, 79,137,223,237, 74,252, 95,187,106, 53, 88,132, 16, 90,248, 41, 22,193, 17, 87,172, 88,241,243,
+215, 95,127,189, 34, 45, 45,205, 39, 40, 40,104,226,163,143, 62,218,249,218,181,107, 46, 93,187,118,237,236,235,235,251,118, 84,
+ 84,148,207,192,129, 3,191,126,249,229,151,127, 36,132, 72, 14, 68,133,130, 56,142,123,243,248,241,227, 27,154, 52,105, 98, 75,
+ 73, 73,241,236,209,163, 71, 38, 0,132,135,135,231,101,101,101,213,240,246,246,150,183,110,221,250, 19, 33,228, 85, 66, 72,133,
+161,105, 63, 63,191,214,181,107,215,158, 48,127,254,124, 29,207,243,101, 69, 80,240,193, 7, 31,232,220,221,221, 95,245,247,247,
+111, 95,145,166,175,175,111,136,155,155,219,140, 79, 63,253, 84,111,181, 90, 33, 73, 18,188,189,189,225,226,226,130,140,244,116,
+164,222,188,137,172,228, 68, 76,159, 56,193,224,106, 48,140,243,243,243,107, 85,145,230,163, 13,220,158,113,245,109,218,101,252,
+132,137,176,142, 28, 9,179, 94, 15,243,219,111,195, 22, 25, 9,243,194,133,176,213,172, 9,235,147, 79, 98,226,196,119,160,245,
+ 9,238,248, 72, 64,141, 65,247,203,117,191,255,254,251,220,196,137, 19,117,219,183,111,215,119,235,214,205,190,122,245,234, 92,
+147,201,132,229,203,151,231,134,135,135, 91, 87,172, 88,161,239,216,177,163,235,227,143, 63,174,118, 48, 34, 32,174, 93,187,246,
+252,202,149, 43,231, 95,185,114, 69,221,168, 81,163,185,109,218,180,233,157,155,155,171,238,208,161, 67,159,128,128,128, 5, 81,
+ 81, 81, 53,159,126,250,233,121, 51,102,204, 88, 15, 64,196, 3, 2,207,243,224,121, 30, 26,141, 6,173, 90,181,194,198,141, 27,
+225,231,231,135,111,190,249,198,179, 78,157, 58, 46, 17, 17, 17,217, 89, 89, 89,159, 58,163,105,183,219, 97,179,217, 96, 54,155,
+241,199,233, 51,248,253,215, 45, 88,179,238, 7,188,242,218,235,153,146, 36,217,198,142,126,221,205, 77,239, 50,158, 61,255,221,
+ 31,242,251, 23, 18, 51, 64,243, 8, 33,118, 0,104,216,176,161,214,223,223,191,125,195,134, 13,181,142,234, 88, 44,150, 47,150,
+ 44, 89,226,199,233, 60,113,212,222, 27, 27,233, 92,236,241, 88,142,180,192,201,168, 99,108,132,167,159,126,218, 27,192,146,106,
+ 72,239,118, 74,233, 48, 74,233,214,202,252,255,223,157,206,240,240,240,206,225,225,225, 71,195,195,195,175, 23,124,119,174,234,
+ 49,175,152, 73, 30,251,238,125,237, 95, 95, 77, 35,230,239,222,215,254,181, 98, 38,121,140,149,220,127, 47,165,121,144, 82,240,
+ 38,132,108, 39,132,108,159, 54,109,218, 99, 0,188, 74,252,238, 84,124, 59, 0,218,210,190, 11, 63,197,150,123, 23, 24, 43,239,
+ 98,191,171, 5, 85,177,139,180,212,102, 14,163,209,104, 89,180,104,209, 30,147,201,116,224,243,207, 63,111, 55,113,226,196,151,
+252,252,252, 14, 15, 26, 52,232, 83,119,119,119,177,180,254, 37,229,240, 74,199,142, 29,127, 54, 26,141, 74, 82, 82,146, 70, 20,
+ 69,205,245,235,215,117,162, 40, 18,181, 90, 77, 45, 22,139,250,194,133, 11, 26, 81, 20,229, 22, 45, 90,108,186,112,225,194, 8,
+ 0, 83,202, 19, 52, 24, 12,163,191,254,250,107,125, 89,230, 74,150,101,228,229,229, 65,146, 36,204,153, 51, 71, 63,105,210,164,
+ 55, 0,156, 42, 79, 83,173, 86,191,177,124,249,114,189, 40,138, 69,253,103, 98, 99, 99,145,157,153, 9, 49, 47, 15, 66, 94, 14,
+164,188,108,168,204,238,152,240,210,139,250, 5,223,124, 59, 30,192,200,242, 52, 5,109,141,121,223,127,243, 45, 68, 81,132,125,
+195,134, 82,183, 17, 15, 30, 4,236,118,124,240,225, 66,242,206,232, 23,230, 0,248,241, 62,221, 96,192,243, 60, 94,125,245, 85,
+ 98,183,219,181,219,182,109,211,182,106,213, 74, 14, 13, 13,117,235,223,191, 63, 36, 73, 66,118,118, 54,244,122,189, 51,178,114,
+131, 6, 13,204, 95,127,253,245,207, 25, 25, 25,219, 62,250,232,163, 46, 75,151, 46, 29,229,237,237,189, 99,200,144, 33,211,221,
+220,220, 4,173, 86, 11, 73,146,220, 31,180,139, 95,163,209,192, 96, 48,192,223,223, 31, 3, 7, 14,196,210,165, 75,193,243,124,
+ 6,207,243,123,242,242,242, 22, 93,184,112, 33,206, 89,131,101,181, 90, 97,177, 88,112, 61,254, 6, 68, 81, 68,196,218,181, 56,
+118,240,192,123,148,210,185,235,215,124,239,178,124,229,202,254, 0,222, 97, 85,239, 63,203,224,193,131,121, 66,136,103,195,186,
+122, 19,225,168,249, 4,165, 53, 3, 2, 2, 94,146, 36,233,113,163,209, 88, 59, 33, 33, 33,221,223,223,127,175,221,110,255, 53,
+ 45, 45,205, 84, 65,164,146, 72,146,132,209,237,179, 48,182, 35, 7, 73,146,144,149,149,133,155, 55,111,226,207, 63,255,196,201,
+147,127, 86, 42,141,129,129,129,175, 24, 12,134, 39, 52, 26, 77,125, 74, 41,103, 50,153,110,218,237,246, 3, 73, 73, 73,223,210,
+ 74, 76,108,248,119,165,179, 24, 11, 6, 14, 28, 88,207,195,195, 3, 81, 81, 81,245,206,157, 59,183, 0,192,163, 85,186, 38,137,
+102,197,144, 55, 14,248,186,184,213, 65,106,236, 70,223, 29, 91,231,174, 0,208,136,149,224,127,245,131, 13,169, 96,147, 52, 74,
+233, 51, 5,134,108,251,130, 5, 11,158, 41,248,191,103,138,255,118, 96, 63,207,148, 98,240,182,151,182,188,218, 12, 22, 33,132,
+150,119,128,174,174,174,210,140, 25, 51, 78, 28, 58,116, 40,188,115,231,206,199,156, 52, 86,133,116,108,220,184,113,228,238,221,
+187,189,234,213,171,103, 83, 20,133,184,187,187, 75,110,110,110,114, 65,223, 22, 26, 23, 23,167,142,139,139,171,225,229,229, 37,
+ 3,232, 88,145,160, 90,173,238, 16, 20, 20, 84,230,141, 44, 47, 47, 15,185,185,185,176,217,108,168, 83,167, 14,225, 56,174,194,
+240,159, 74,165,234,212,168, 81, 35,146,155,155,139, 58,117,234,224,220,185,115,176,230,229, 65, 52,229, 66,202,201,133,156,151,
+ 13,154,147, 5, 83,118, 22,130,124,106, 19,158,231, 43,140,138, 73,188,193,232,235,234, 10,251,212,169, 16,254,250, 11,208,104,
+160,169, 95, 31, 16,242,187, 90, 9,241,241,128, 86, 11,110,228, 72, 52,122,237, 53, 72,208,249,222,199,130, 14,187,221, 14,179,
+217, 12,141, 70,131,231,158,123, 14,135, 14, 29, 18,218,181,107,167, 79, 76, 76,132,221,110, 7,199,113, 69,205,103, 14, 86,226,
+ 50,199,113, 20, 0,188,188,188,196, 69,139, 22,237,239,218,181,107,247, 30, 61,122,236,209,106,255, 63, 40, 96,179,217, 20, 0,
+244, 65,186,240,117, 58, 29,212,106, 53, 8, 33,168, 81,163, 6,114,115,115,113,249,242,229,250,149,209,146,101, 57,191,223, 85,
+ 65, 20, 75,150,101,252,113,250, 4,244, 6, 3, 58,116,233, 58, 93, 81, 20,131, 90,165, 2, 95,208,185,139,241,207,209,161, 67,
+135, 48, 13,149,230,191,225, 43, 4, 60, 53,208,223,164,119, 81,153, 6,238,176,119, 15,110,216, 97,192,252, 15,230,215, 8, 10,
+ 10,114,141,142,142,206,155, 63,127,190,223,153, 51,103, 0,224,135,242,244,146,146,146,182, 44, 92,184,176,102,247,238,221, 27,
+168,213,106,146,149,149,133,180,180, 52,164,166,166, 34, 33, 33,129,198,197,197, 93, 23, 69,241,103,103,210,216,166, 77,155, 47,
+135, 13, 27,246, 66,243,230,205,213,148, 82,136,162, 8,179,217,220,250,228,201,147,125,142, 30, 61,218, 9,192,171,206, 30,119,
+114,114,242, 47, 11, 23, 46,116,237,222,189,123, 99,181, 90,205, 85, 71, 58, 75, 80,207,205,205, 13,123,247,238,133,135,135, 7,
+ 0,212,171,106, 94,217, 69,193,215,197,221, 23,136,255, 20, 62,158, 1,176,139,130, 47, 43,193,255,254, 40, 86, 5, 38,235, 52,
+128, 62, 85, 53, 67,127,151,153,170, 84, 4,171,144,219,183,111,235,114,115,115, 85,148, 82, 78,150,101,149,162, 40, 68,167,211,
+ 57,219,148,211,108,208,160, 65, 63,245,234,213, 43,171, 32, 50, 32,122,121,121, 73,153,153,153,200,206,206,134, 36, 73,178,187,
+187,187,185,110,221,186,230,166, 77,155,230, 28, 56,112,160,194, 38, 66,139,197,226, 95, 90, 36,197,108, 54, 35, 47, 47,175,200,
+ 96,153,205,102,184,187,187,195,100, 50, 85,120,113, 11,130, 16, 96, 48, 24,144,150,150,134,244,244,116, 88,243,114, 32,228,230,
+ 65,202,203,129,148,147, 13, 37, 55, 27, 52, 47, 23,138, 34,163,166,183, 55,236,118,187,127, 69,154,102,155,172, 85, 3,176,252,
+252, 51,240,191,255,149,109,110, 14, 28,128, 75, 72, 8, 44, 22,225,190,205, 81, 86,252, 33, 88, 16, 4, 72,146, 4, 74, 41,181,
+219,237,176,219,237,197, 77,147,147,222, 34,223,144,157, 61,123,214, 61, 53, 53, 85, 79, 41,229,243,242,242,116, 38,147,137,171,
+ 93,187,182, 21, 0,149, 36, 73,126,208, 46,124, 73,146, 32, 8, 2, 4, 65,128,205,102,115,234,184, 75,110, 91, 56,114,176, 96,
+ 24, 60,236,162, 29,159, 45,253, 18, 91, 54,109,196,165, 75, 23,253,102,206,253, 0,162, 36, 65, 86, 88,191,226,127,138,214,173,
+ 91,247,228,121,254,179,142, 30,138,219, 4,127, 49,175,182, 86, 49,197, 46,127,203,116,206,104,176, 88, 45,130,239,130,165, 31,
+122, 81, 10,204,152, 49,227,246,144, 33, 67,106, 76,156, 56,177,197,208,161, 67,123, 52,111,222,252,199,139, 23, 47, 10,101, 84,
+226,154, 17, 35, 70,156,174, 89,179,102,208,218,181,107, 83, 83, 82, 82,106,137,162,104,176,219,237,130,221,110,191,110,183,219,
+143,139,162,120, 32, 57, 57, 57,218,153,180,186,186,186,182, 28, 58,116,168, 58, 51, 51,179,104,180, 95, 90, 90, 26,194,194,194,
+248,125,251,246, 53,171,204, 93,185,173,144, 0, 0, 32, 0, 73, 68, 65, 84,241, 95,186,116,105,169,159,159,223,225,109,219,182,
+ 61, 81,163, 70,141, 80,173, 86, 91, 71, 81, 20,217, 98,177,164, 90, 44,150,243,149, 73,103, 9, 82,162,162,162,234,185,187,187,
+ 35, 49, 49, 17, 0, 82,170,154,103, 90,181, 38, 49,245,202, 70,127, 31,143, 32, 92,187,244, 27,180,106, 77, 34, 43,201, 15,125,
+ 4,171, 93,241,136, 85, 57, 38,201, 50,117,234,212,233,132,144,237, 83,167, 78,157, 94, 78, 4, 75, 46,190, 93,177,237,109,213,
+110,176, 74,195,100, 50,169, 78,159, 62,237,117,251,246,237, 26, 62, 62, 62,166,102,205,154,101, 17, 66, 64, 41, 37, 57, 57, 57,
+ 46,169,169,169, 46,174,174,174,182,250,245,235,231, 56,184,191,191,254,247,191,255,245,155, 50,101,202,222, 23, 95,124, 49, 5,
+ 0, 50, 51, 51,113,251,246,109,100,100,100, 64, 16, 4, 36, 37, 37,145, 35, 71,142,212,217,183,111,223,227, 0,226, 43, 18, 52,
+ 24, 12,137,185,185,185,141, 60, 61, 61,139,204, 65,161,169, 42,254, 45, 8, 2,114,115,115,225,234,234, 90,225,197,173, 86,171,
+147,211,210,210,130,237, 54, 27,210, 18, 19,243,141, 85, 94, 46,228,156, 44,200, 57,217, 32,166, 92,104, 68, 17, 58,181, 26,185,
+119, 50,160,209,104,110, 87,164,233,162,227,237,118, 73,210,242,125,251, 2,164,236,114, 68, 59,117,194,157, 22, 45,160,223,254,
+179,120, 31, 11,122,169,191, 75,154, 5,103,140,198,157, 59,119,184,165, 75,151, 54,139,141,141,173,225,227,227,147,222,163, 71,
+143, 56, 66, 8,229, 56, 78, 73, 77, 77,173, 21, 27, 27,219,200,211,211,211,164, 86,171,211,238,167,145, 42,109,153,201,100,130,
+205,102,131,213,106, 69, 86, 86, 22, 84, 42, 21,186,118,237,122,192,102,179,253, 66, 8, 89,115,242,228,201,220,178, 52, 69, 81,
+188,231, 92,202,178, 92,100,178, 84,132,199, 47,155, 54, 97,217,202,101,248,249,231,109,116,200,160,129,228,208,225, 35, 80, 20,
+154,196,170,220,127, 6,158,231, 63, 60, 54,229, 57, 55, 34, 75,121, 89,251, 55,153,151, 37,104, 77,191,157,189,112,204,108,181,
+243, 13,130,131,154, 6,214,111,160,158, 57,107, 74,234,185,203,127,196,103,126,149, 89,247,221,119,223,173,223,168, 81,163, 58,
+113,113,113,193, 0, 46,151,166,233,230,230, 22, 48,124,248,240,151,179,178,178,212,223,126,251,237,186,132,132,132, 99,148,210,
+235, 37, 76, 88, 27, 66,200,135, 5,245,176, 15, 0, 25,192, 62, 74,233,250,242, 60, 59, 33, 4, 7, 15, 30,188,103,180,159, 44,
+203,149,118,229,201,201,201, 89, 29, 59,118,108, 25, 27, 27,187, 61, 51, 51,115,227, 61,245,151,139, 75,159, 22, 45, 90, 12, 58,
+117,234,212, 60, 74,233, 53,103,180, 57,142,155,242,231,159,127,126, 64, 41, 13, 32,132,220,228, 56,238,189,170,230,153, 64,133,
+ 55,118,108,153,189,220, 46,216,141, 90,141, 54, 65,160,194,155,172, 36, 63,244, 20,246,145, 66,113,227, 84,138, 49, 58,190, 96,
+193, 2,195,194,133, 11,177, 96,193,130, 63, 75,139, 96, 21, 26,173, 5, 11, 22,252, 89,184, 93,177,237, 15, 87,171,193, 42,205,
+ 57,202,178,172, 95,184,112, 97,167,230,205,155, 39,119,238,220, 57,217,104, 52, 90, 10,111, 16, 42,149, 74,244,241,241,201,150,
+ 36,201,122,251,246,237,218,135, 15, 31,110, 64, 41,117,164,243,231, 33, 55, 55, 55,205,153, 51,103,234,109,220,184,177,117, 76,
+ 76, 76, 72,159, 62,125,138,162, 3,137,137,137, 33,159,125,246,153,172,211,233,210,121,158,143, 4, 80, 97, 39, 31, 81, 20, 79,
+ 94,185,114,165, 97,135, 14, 29,136, 40,138,119,153,170,226,127,107,181, 90, 36, 38, 38, 82, 69, 81, 78, 59, 96, 48, 78,159,139,
+142, 14,110,209,164, 73,190,185,202,205,134,156,147, 13, 57, 59, 11,196,156, 7,141, 40,192,213, 69,129, 78,235,130, 63,243,159,
+200, 42,156, 45, 89, 37, 89,110,198,231,228, 52,170,191,104, 17, 52,158,158,128, 32, 20, 53, 11, 2, 40,106, 46,164, 41, 41, 56,
+115,226, 4, 84,138, 45,249,126, 26,141, 90,181,106, 33, 39, 39, 7, 54,155, 13,148, 82, 80, 74,139, 12,149, 86,171, 69, 65,127,
+ 41, 71, 67, 87, 30,253,251,247,127,180, 67,135, 14, 49,175,190,250,234,254,102,205,154,221, 40, 44,235, 46, 46, 46, 66,147, 38,
+ 77,146,109, 54, 91,222,245,235,215, 67,214,174, 93,219, 73, 81,148, 26,247,227,184, 75,154,161,194, 8, 94,161,185, 74, 75, 75,
+195,174, 93,187,112,252,248,113, 92,188,120,177,221,201,147, 39, 91,109,217,178,229,221,230,205,155,119,184,120,241,226,109, 71,
+ 13, 86,225,185,164,148,130,230,143,142,199,214, 95,127, 71,239, 62,221, 72,174, 41, 7,219,119,236, 6,165,180, 30,171, 79,255,
+ 49, 76,144,100,147,237,208, 6,243,171,151,116, 89,105,118,204,139,142,142, 60,210,167, 79,159,189,193, 13, 26,187, 3,128,221,
+ 70,107,186,104,188, 12, 42,149, 74, 11, 0, 1, 1, 1,225,148,210,207,145, 63, 18,233, 30, 6, 12, 24,208,177, 78,157, 58,173,
+119,238,220,121, 62, 33, 33,225,120, 73,115, 5, 0, 33, 33, 33,239, 93,184,112,225, 73,181, 90, 77,138, 85,254, 20, 64,169, 6,
+235,217,103,159,109,100, 52, 26,107,237,184,226,129, 28, 77, 48, 20, 46, 11,148,215, 65,246,108,141, 27,154,230,168, 91,247,114,
+173,198,141, 27,183,186,114,229,202,121,103, 14,158, 16, 98, 28, 50,100,200,207,171, 86,173, 10,233,213,171,151, 22,192, 61, 6,
+171,105,211,166,253,247,237,219,247,236,216,177, 99, 91, 17, 66, 6, 81, 74, 29,158, 3,240,244,233,211, 39, 0, 84,107, 39,244,
+ 49,243,232, 1, 0, 77, 88,209,253,207, 68,175,128, 98,125,176, 0,164, 33,255, 93,202,197,127, 23,206,117,105, 47,182,109, 90,
+177,168,149,189, 68,212,171,180,117,105,168,198, 65, 86,170,114,110,178, 7, 79,157, 58,213, 38, 60, 60,252, 90,161,185, 42,188,
+ 30, 11,255,112,117,117,181, 3,160, 49, 49, 49,205,100, 89, 62,238,192,254, 86, 71, 70, 70,238,248,242,203, 47, 63, 14, 8, 8,
+176,245,239,223,159,251,224,131, 15,182, 23, 70,177,150, 44, 89, 66,123,247,238,253, 91,108,108, 44,185,116,233,210,123, 0,158,
+173, 72,208, 98,177,172,124,243,205, 55, 7, 29, 57,114, 68,111,183,219,145,149,149,117, 87,244, 42, 55, 55, 23,146, 36,129,231,
+121,124,249,229,151, 54,147,201,244,101,133, 79, 71,130,240,237, 71, 31,125, 52, 96,253,234,239,244,188,104,135, 53, 43, 19, 74,
+ 78, 22, 56,179, 9, 42,193, 14,157, 90, 70,189, 70,174,200, 77,213, 96,217,174,131, 22, 81, 20, 87, 86, 24, 21,179,153,166,191,
+ 49,122,212, 79,123,246, 31,128,250,241,199, 33,238,220,121,239,147, 94,157, 58,176, 10, 2, 22,204,159, 71,137, 37,107,230,253,
+ 40,232,106,181,250,242,168, 81,163,234,140, 30, 61,186,102,203,150, 45, 33, 8, 2, 68, 81, 44,138,188,120,121,121, 1, 0, 18,
+ 18, 18, 16, 21, 21,149,205,243,124,133,209, 59, 89,150, 15,221,184,113,163,249,200,145, 35,175, 62,245,212, 83, 62,130, 32,168,
+ 50, 51, 51, 83, 10,158,140, 85,254,254,254, 6,173, 86, 75, 82, 83, 83,179,238,220,185,227,163, 40,202,241,251,113,236,162, 40,
+226,253,247,223, 71, 68,108, 44,134,135,132, 20,153, 77,155,205,150,223,156,103,183, 99,247,238,221, 56,124,248, 48,214,173, 91,
+151,241,220,115,207,121,188,248,226,139, 30,235,214,173, 27, 7,224,189,178,204,234,228,201,147,177,237,250,117,244, 45,165,175,
+ 32,165, 4, 73,201, 73, 16, 69, 17, 63,255,188, 39, 89,173, 82,123, 46,249,120,161, 97,210,244,233,132, 85,187,255, 12,138,162,
+204,238,188,120,203, 56,142,115, 17, 0, 44,143,142, 62,115, 28, 0, 12, 6,131,247,226,197,139,181, 0,176,232,227, 69,106, 74,
+169, 90,146, 36,216,237,118,204,155, 55, 79, 63,122,244,232, 50, 71, 27,253,248,227,143, 89,115,231,206,173,245,218,107,175,245,
+ 60,120,240,160,142, 16,178,167,224, 65, 44,163, 32, 82, 85, 27,192,137,218,181,107,215,221,180,105, 83,208,147, 79, 62,233, 90,
+ 81, 58,173, 86,235, 87, 43, 87,174,172,191,248,176, 27,118,152, 6, 34,129, 14, 1,173, 69, 81, 75,147,139,102, 53,110,162, 91,
+189,132,122,235,214,173, 91, 14,192,225, 81,122,132,144,166,207, 61,247,220,198, 85,171, 86, 5,142, 26, 53, 42,233,248,241,227,
+137,132,144,210,202,114,198,240,225,195,111, 70, 68, 68, 4, 41,138,178,149, 16,210,223, 25,147,197, 96, 84, 3,167,255,166,109,
+255, 54,202, 51, 88,227, 9, 33,205, 22, 45, 90,244,193,183,223,126,219, 97,250,244,233, 7, 59,118,236,152, 89,104,176,110,221,
+186, 85,235,200,145, 35,221,205,102,179, 36,203,242,184,210,230,196, 40,249,182,109, 74,233, 77, 66,200,103,157, 59,119,126, 97,
+205,154, 53,235, 92, 93, 93, 51,247,238,221, 91,203,215,215,247, 78,100,100,164, 59,199,113,185, 87,174, 92, 81,237,221,187,119,
+ 40,128,149,165, 93,192, 37, 53,147,146,146,206, 53,104,208,224,243,119,223,125,119,194,204,153, 51,245,133,115, 12,229,230,230,
+194,106,181, 66,173, 86,131,231,121,108,216,176,193,102,183,219,191, 75, 76, 76, 60,229,128,230,201,192,192,192, 85,159, 44,250,
+100,212, 91, 35, 94,209,114, 57, 89,176,220, 73, 7, 4, 27,116, 42, 14,198,240,154,176,100,242, 88,190,235,168, 61,205, 98,249,
+ 41, 33, 33,225, 72, 69,154,199,110,228,236,236,216,200,251,192,188, 57,179, 30,155,250,227,143,128, 44,131,188,242, 10,176,111,
+ 31,208,178, 37,148,228,100, 88, 5, 1, 51,166, 77, 1,111, 73, 61,118,242, 70,222, 47, 21,105, 86, 7, 37, 53,111,222,188,217,
+ 65,146,164, 97,115,231,206,157, 29, 28, 28,172, 30, 49, 98,132,103, 96, 96, 32, 20, 69,129, 70,163, 65, 82, 82, 18, 78,157, 58,
+149,115,231,206, 29,129, 82,250,126,114,114,242, 15, 21,105,202,178, 60,150, 16,210,236,157,119,222,153,247,193, 7, 31,168, 63,
+249,228,147, 19, 61,123,246,244, 83,171,213,154,214,173, 91,123, 31, 62,124,216,176,101,203,150, 39, 76, 38, 19, 40,165, 19, 28,
+ 41, 75,213,125,236, 26,141, 38,237,242,229,203,181, 23, 45, 90, 68,110,101,101, 97,182, 70, 3,161, 96, 0, 66, 97,228,110,214,
+172, 89,112,117,117,197,146, 37, 75,112,250,244,233, 37, 25, 25, 25,111, 47, 93,186,212,107,195,134, 13,131, 11, 13, 86,113, 77,
+189, 94,127,227,220,185,115,198, 21, 43, 86,112, 9,146,132, 79, 69,241,158,136,214,228, 25,239, 65,176, 11, 32,132, 71,212, 31,
+135,231, 63,218,253,137,185, 53, 61, 61, 13,138, 66,233, 63,153,239,255,101,205,179,103,207, 30, 2,112,168,156,167,235,194,135,
+ 57,164,167,167, 35, 61, 61, 29, 30, 30, 30,133,147, 38,151,170,105,177, 88,206, 79,153, 50, 37,122,197,138, 21, 61,143, 29, 59,
+246,220,161, 67,135,158,218,191,127,191, 53, 62, 62, 94, 18, 69,145,214,171, 87, 79,245,232,163,143,234,123,247,238,237,162,211,
+233,184, 25, 51,102,100,204,159, 63,223,171,192,128,149,170,169, 40, 10,175, 40, 10,222,238,146,131,201,143,169, 96,179,229, 63,
+ 80, 38, 39, 39,225,226,197,139, 56,126, 60, 6,132, 16,206,201,243,249,201,186,117,235, 26,104,181, 90,178,126,253,122,227,250,
+245,235,223,168,232,252,173, 89,179,166,254,250,245,235, 63, 39,132,244,161,148, 42,172, 44, 49, 77,134,147, 6,171,160, 98,185,
+ 4, 96, 0, 33,164,211,164, 73,147,230,248,251,251,103,200,178,172,217,182,109,219, 83, 57, 57, 57,181,100, 89,158, 69, 41, 61,
+234,100, 40,112, 21, 33, 4, 67,135, 14,157,230,239,239,255,219,159,127,254,249,216,115,207, 61,183,105,219,182,109,143,203,178,
+124,227,218,181,107,211, 1,124, 9,224, 43, 71, 53,227,227,227, 63,220,179,103, 15, 57,113,226,196,248,169, 83,167,234,124,124,
+124,136,167,167, 39, 44, 22, 11, 18, 18, 18,232,234,213,171,109,118,187,125,133,135,135,199, 28, 71, 53,107,213,170, 53,115,207,
+177, 99,218,243, 23, 47,188,244,191,231, 7,235,235,251, 25,225,198, 25,145,123, 39, 3, 71,143, 37,225,243,221, 71,172,233,118,
+251, 38,142,227, 28, 30, 74,239,127, 53,189,255,158,205,223,110, 57,124,240,224, 99,243, 22,124, 68,154,188,246, 26, 92, 26, 52,
+ 64,118,163, 70, 56,117,248, 48, 22,204,159, 71,121, 83,234, 49,233,234,237,103,238, 87,129, 40,120,199,224,247,129,129,129,155,
+174, 92,185, 50,122,250,244,233, 83,195,194,194,168,205,102,211,236,216,177,195,148,146,146,162, 40,138,242,177, 90,173, 94, 17,
+ 31, 31,111,115, 66,247, 18,128,103, 9, 33,157, 70,142, 28, 57,219,207,207, 47, 85,146, 36,213,228,201,147, 31,203,204,204,172,
+ 67, 41,157,237,108, 89,170, 78, 4, 65,120, 98,210,164, 73, 7, 0,212, 40,222, 28,122,215,197,162, 82,105,114,114,114,136,162,
+ 40,162,213,106, 77, 43,140,140,150,117, 29,137,162,248,216,204,153, 51, 15, 88,173,214,250,101,237, 87,163, 55,224,232,241, 19,
+ 24, 54,116,136,172,226,249, 15, 94, 28, 58, 68,123,252,143,147, 50,165,202, 86, 86, 61, 61,152, 80, 74, 81,240, 48, 64,203,217,
+ 38,129, 16,242,222,153, 51,103,244, 99,198,140, 9, 29, 54,108,152,219,227,143, 63,238, 90, 34,250,174,108,219,182,205,188,114,
+229,202,140, 67,135, 14, 69,142, 28, 57,178, 31,242,103,143, 47,149,228,228,228,157,203,150, 45,243,232,214,173, 91, 67, 89,150,
+145,158,158, 94,212, 7, 43, 49, 49, 17, 55,110,220,184, 41,203,242,111, 78, 30,206,255, 94,124,241,197, 95, 34, 34, 34, 2, 70,
+141, 26,149,180, 97,195,134,223, 0,148,214,167,214,117,224,192,129,125, 34, 34, 34, 2, 70,143, 30,157, 0,224, 29, 54,195, 59,
+131, 81, 5,131, 85,172,178, 56, 14,224, 9, 66,200, 51,132, 16, 47,171,213,186,134, 82,186,189, 10, 21,212, 42, 66,200,222,132,
+132,132,225, 0,252,190,248,226,139, 47, 0, 36, 2,184, 2,160, 95,105,253, 21, 28, 48, 5,115,253,253,253,183,204,158, 61,187,
+ 90,222, 69, 88,240, 74,157,137,190,190,190, 63,190,247,245,234, 41,138,162,180, 81, 68,161, 22,120, 85, 22,207,243,231, 68, 81,
+252, 40, 33, 33,193, 41, 67,176, 57, 63,157,125, 59,212,119,127,122,202,216, 97,243, 37,222, 16, 96,178, 73, 90, 23,173,202,174,
+161,214, 4,206,146, 61,251,100,124,238, 3,113, 99, 45, 48, 79,159, 55,108,216,112,245,169, 83,167,222, 5, 48, 38, 47, 47,111,
+165, 94,175,255,228,234,213,171,185, 85,200,251,227, 0,122, 20,148, 37, 31,179,217,188,177, 42,101,169,186,136,140,140,188, 30,
+ 30, 30, 30, 12,192, 80,214, 54, 60,207, 47,221,185,115,231,179, 61,123,246,180,218,108,182, 69, 61,123,246, 84, 69, 71, 71, 83,
+ 74,233,129,210,182, 63,121,242,100, 42,128,114, 71,118,133,118,234, 20, 16,177,102,205,241, 17,195,135,187, 45,255,108, 73,205,
+211,145, 81,242,119, 17, 17,185, 38,171,117, 41,171,158, 30, 12, 10, 3, 85,106,181, 26, 46, 46, 46,112,119,119, 71, 90, 90, 90,
+133,131, 60, 40,165,215, 8, 33, 3, 39, 77,154,212,105,210,164, 73, 79,249,249,249, 53,171, 95,191,190, 63,199,113, 92, 74, 74,
+ 74,122, 66, 66,194, 77, 65, 16, 14, 0,216, 9, 64, 19, 20, 20,116, 14,192,134,178,244, 46, 94,188,248,145,159,159,223,225, 95,
+126,249,229, 41,189, 94,223, 68,163,209,212, 20, 4,129, 51,155,205,153,118,187, 61, 70, 16,132,223,147,146,146,254,112,242,122,
+252,139, 16,242,180, 74,165,250,121,213,170, 85, 33, 41, 41, 41,245, 15, 29, 58,116,207, 36,199,225,225,225, 95, 71, 68, 68, 4,
+140, 29, 59,246,250,250,245,235, 7,177,230, 65, 6,195,129,186,163, 18,243,210, 57, 83, 49, 61, 84,161,206,192,192, 64,157,163,
+ 81, 27, 22, 58,126,248, 52, 91,182,108,233, 89,167, 78,157,193,227,199,143,215, 54,105,210, 4, 49, 49, 49, 88,190,124,185, 61,
+ 57, 57,121,243,133, 11, 23,178, 42,155,206,208, 78,157, 2, 92,245,250,241, 0,121, 6,160,219, 77, 86,235, 93,239, 34,100,121,
+116,127, 52,251,247,239,191, 69,167,211, 53,224, 56,142, 80, 74,105,225,171,147, 10, 71,128,218,237,246,184,253,251,247, 15,120,
+ 24,142,157, 16, 98,108,223,190,253,156,152,152,152,221, 57, 57, 57,247,116,114,215,233,116,125,194,194,194,134,158, 56,113, 98,
+118,201, 81,132,172, 44, 49, 77, 70, 21, 34, 88,140,187,162, 58,140,255, 40, 5, 38,170,104, 64, 67, 80, 80, 16,250,244,233, 83,
+101,221, 2, 51,245, 14,216,204,237, 15, 20, 91,183,110, 29,240, 95, 57, 86, 74,105, 2,202,153,164,212,102,179,253, 6,224, 55,
+ 86, 42, 24, 12,199, 97,179, 69, 51, 24, 12, 6,131,193, 96, 84, 51, 4, 64,203, 50,158,104, 28, 14,253, 17, 66, 90, 86,226,137,
+233, 2,211,100,154, 76,147,105, 50, 77,166,201, 52,255, 91,154,197,180,231,150,177, 42,169, 64,231,235,127,181,193, 98,125,176,
+152, 38,211,100,154, 76,147,105, 50, 77,166,121,191, 53, 75,232,143,250,183, 27, 44,214, 68,200, 96, 48, 24, 12, 6,131,193, 12,
+ 22,131,193, 96, 48, 24, 12,198,131,141, 67,163, 8,181, 90,109, 51, 0, 47, 3,168, 67, 8,185, 77, 41, 93, 99,183,219, 47,253,
+215, 78,150, 86,171,109, 70, 8,121,153, 82, 90, 7,192,109, 0,247,247, 60, 16, 66,230,204,206,159, 89,127,214,108, 80,252,157,
+237,189, 12, 6,131,193, 96, 48,170,110,176, 26, 4, 4, 60, 71, 56,124, 34, 74,138,167,167,167, 39,183,108,217, 50,174,111,223,
+190,216,182,109, 27,198,191,245,214, 27,254,254,190,138,154, 87,101,129,202,239,198,221, 76,250,201,145,157, 13, 28, 56, 48, 94,
+ 20,197, 50,223,223,197,243,124,218,150, 45, 91, 2,171,122, 80,126, 97, 67,226, 69, 81, 40,115, 63, 42,149, 58, 45, 57,122,179,
+ 67,251, 9, 8,240,123,142, 3,249, 68, 82, 20,207,154, 53,107,114, 95,124,241, 69,209,121, 24, 55,110,220, 27, 70,127,127, 69,
+173,226,178,168,130,119,227,110,222,252,233, 31,203,185, 98,230, 10, 0,230,204, 6,153, 69, 8, 30, 72,147, 85,144,214, 89,179,
+ 64, 1,102, 2, 25, 12, 6,131,241, 31, 54, 88,132,208,207,214,175,252,196, 51, 35, 35, 19, 27,182,238, 66,211,166, 77,113,241,
+226, 69, 52,109,218, 20,143,182,111,205,245,122,164, 13,199,115,168,253,254, 23,107, 63, 3,224,144,177, 16, 69,209,251,151, 95,
+126, 1, 33,164,104,194,190,194, 73,251,114,115,115, 49, 97,194, 4,239,234, 56, 40, 81, 20,188,175,159,254, 25, 42,158, 64,146,
+ 41, 4,137, 66,148, 20, 8, 50, 69,142, 89,194,227,125, 94,116,120, 63,132,146,207,190,251, 98,145,103, 86,118, 54,126,222,177,
+231,174,243,240,120,231,118,220,224,222,221, 57, 23,131,166,246,232, 41, 31, 57,124, 30,170,131,226,230,234, 46,147, 5, 60,112,
+ 6,166, 48,173,115,230,128, 0,249,211, 98,207,158, 13, 74, 89,196,141,193, 96, 48, 24,255, 53,131,101, 19,101,207, 58,181, 60,
+176,250,187,239, 48,121,234, 60, 52,105,210, 4,148, 82, 16, 66, 48,125,230, 92,124, 58,111, 42,134, 62,221, 21,162,164,120,150,
+165, 81,198,140,193,136,139,139,131,197, 98,185,235,211,162, 69, 11,135, 18,236,232,168, 5, 21, 79,240, 91, 84, 46, 4, 81,129,
+ 32, 21,124, 68, 5,143,181,116,115, 74, 83,148, 21, 79, 79,143, 26, 88,181,242, 43, 76,154,187,232,174,243, 48,101,250, 76, 44,
+ 95,248, 30, 38,142,125, 5, 54, 81,246,172, 76, 58,157,225, 97,210,156, 61, 27,100,206, 28, 66, 28,109,218,100,231,147,105, 50,
+ 77,166,201, 52, 31,110,205,135,210, 96, 17, 66,186, 1, 56, 88,112,210,138, 34, 35,162,221,138,230, 70, 47,124,181,248, 3, 80,
+112, 80, 64, 1, 5,160,138,136, 6,181, 93, 96, 49,155,157,222,161,162, 40, 16, 4, 1,162, 40,226,235,175,191, 70, 94, 94, 30,
+ 20, 69, 65,211,166, 77, 1, 0,225,225,225,197, 69, 19, 34, 35, 35,155, 84,164,233,221,178,127, 12, 1, 49, 22, 95, 54,107,209,
+183, 56, 22,117, 13,148, 2, 58,131, 11, 6, 13, 27, 13, 89,161, 16, 68,231,223, 79,106, 53,153, 81,167,134, 26,159,206,159, 9,
+ 78,173, 1, 7, 2,142, 35,224,136,130, 38,254, 53, 97,179, 88,254,241,140,155, 53, 27,180,100, 20,107,214,108, 80,204,250,119,
+ 21,192, 7,186,105,147,193, 96, 48, 24,127, 59,101,121,144,135,194, 96, 1, 56, 88,218, 65,217,173,102,248,215,212,160,110, 13,
+ 15, 72,146,140, 63,133,122,200, 53, 91, 33, 8, 34,110, 8, 2,174, 70,167,160, 83,167, 78, 24, 48, 96, 64,158,221,110,135, 70,
+163,201,217,186,117,171, 95, 69, 6, 75, 20, 69, 8,130, 0,147,201,132,117,235,214, 65,165, 82, 21,189, 56,181,240, 62, 75, 41,
+ 69,231,206,157,141, 14,101, 14,136,241,234,169,159,224,166,231, 33, 41, 20,146, 68, 33,201,128,164, 80,152,237, 10, 6,142,124,
+ 15,146,162, 64, 86, 20,216,133,138,239,227,119, 25,182, 90,237,208,127,218, 6, 0, 53,138,214,187,235, 40, 38,119,230,160,209,
+234,160,213,240,176, 89,204,255,124,206, 81, 74,103, 17,130,127, 91, 39,247, 89,179,168, 2, 16,146,223, 92, 88,204,100, 61,128,
+ 77,155, 12, 6,131,193,248, 71, 56,248, 48, 25,171,146, 6,171,200, 69, 82, 74, 15,253,191,193,178, 64, 18,101,136,146, 12, 73,
+148,144,157,103,193,199, 31,127, 12,157, 78, 7, 66, 72,145, 89, 82, 20,133, 19, 69, 17,189,123,247,246,172,104,135,178, 44, 23,
+ 69,176, 40,165,224,121, 30, 29, 58,116,184,103,187, 63,254,112,234,165,240,112,211,243,104,208, 99,218, 61,203, 79,254,244, 1,
+ 40,165,144,101, 10, 73,166,176, 75,114,149, 13, 91,104,183,193,176,217,197,252,238,218, 20,176,154,205,247, 39,247, 40,165, 69,
+198,228, 95, 21,185,162,116,214, 44,208, 57,115, 8,155, 38,132,193, 96, 48, 24,165,122,144,135,202, 96, 33, 63, 68, 87,228, 34,
+109, 22, 11, 68, 81,130, 36,201, 16,197,124, 99,100, 48, 24,208,181,107,215,194,251,123,209,247,174, 93,187, 32, 8, 66,133, 59,
+ 44,236,212, 46, 8, 2, 20, 69, 1,165, 20, 27, 54,108,128, 90,173, 46,250,104, 52, 26,167, 15, 68,146, 41,166, 77,121, 27, 26,
+ 53, 7, 53,207, 65,163,226,160, 86,241,144, 41, 5,165,128,162, 80,200, 10,133, 77,116, 44, 80, 82,158, 97, 3, 0,193, 38, 0,
+148,130,130,194, 98, 50,177, 43,131,193, 96, 48, 24,140,170,113,151, 7,121, 88, 12, 86,119, 66,200, 61,206,195,110, 49, 21, 68,
+175,100,136,146, 84,100,160, 22, 47, 94, 12,149, 74, 5,173, 86, 11,149, 74, 85,100,136, 28, 49, 88, 86,171, 21, 65, 65, 65,176,
+219,237,104,218,180, 41, 40,165,120,254,249,231,239,217,238,212,169, 83, 78, 29,136, 40, 83, 44,248,104,201, 61,203,143,110,158,
+135, 86,205, 26,160, 93, 35, 87, 88, 5, 5, 57,102,169,202,134, 13, 0,172,118, 17, 10,242, 39, 29,176,152,204,236,178, 96, 48,
+ 24, 12, 6,163,114,148,234, 65, 30, 10,131, 85, 16,146,187,199, 53, 90,205,102, 72,162, 84,100,178,236,118, 59, 20, 69,193, 91,
+111,189,117,143,208,190,125,251, 96,183,219,203,223,153, 74,149,246,250,235,175,223, 53, 69, 2,165, 20, 63,253,244, 19,116, 58,
+221, 93, 81, 44, 66,156, 51,177,162, 76, 49,251,189,119,161, 85,241, 80,171, 10, 13, 17, 7, 69, 1,182,253,182, 27,219,126,219,
+ 93,180, 45,207,171,211,170, 98,216, 0,192,110, 23, 0,154, 31,129, 51,229,229,178,203,195, 65, 8, 33,132, 77,207,192, 96, 48,
+ 24,140, 98, 62,160, 84, 15,242, 80, 24,172,178,176, 90, 76, 16,139,245,193, 18, 4, 1,146, 36,225,235,175,191,190,171, 57, 79,
+173, 86,131,227,184, 10, 35, 88,191,252,242,203, 93,147,123,134,135,135,155, 41,165, 24, 52,104, 80, 81,115,227,171,175,190,138,
+ 81,163, 70, 57,109,176, 36,153, 98,206,252,197, 69, 58,189,123,116, 65,255,167,187, 65, 41,184,149,167, 94,216,226, 82, 93,134,
+ 13, 0,236,182,252, 62, 88, 20,128, 57,151, 53, 17, 58, 74,209,244, 12,179,168,194,206, 6,131,193, 96, 48, 30, 86,202, 52, 88,
+106, 21,151,115,245,198, 45,247,218,174, 6, 72,138, 21,178,146,223,111, 74,150,101,140, 26, 53,170,104,187, 23, 94,120, 1, 47,
+191,252,114,169, 6,203,145,183,109, 43,138,130,163, 71,143,130, 16, 2,142,227,138, 62,229, 68, 64, 74,213, 52,217, 20, 28,219,
+ 52, 23, 10,165, 80, 40,160, 20, 12, 72,176, 73, 21, 7, 75, 74,211,172,200,176,233,220, 60,193, 19, 10, 66,128,171,137,183,161,
+226,185, 28,103,143,221, 89,254,173,154,179,103,131,206, 46, 49,165,132,179, 29,220,217,249,100,154, 76,147,105, 50,205,135, 91,
+243, 63, 99,176, 8, 37,239,172,216,254,199, 98, 81, 86,220, 11,151, 53,111,222, 28,130, 32, 96,231,206,157, 69,198,131,231,249,
+162, 38, 61, 71,250, 96,149, 32,161,107,215,174,229, 77,197,144,224,136, 8, 5, 77,104,251,216, 16, 99,121,235,157, 77, 88, 69,
+134,109,213,161, 63,255,255, 36,114, 92, 14, 71,200, 59,172, 56,149,113,254,105,225,120,203,187,167,103, 96, 48, 24, 12, 6,227,
+ 63,103,176,226, 19, 18, 54, 0,216, 80,124, 89,239,222,189, 83,251,247,239,111,144, 36, 9, 54,155, 13,130, 32,192,110,183, 67,
+ 16, 4,216,108, 54,232,245,122,167,102,220,116,100, 18, 81, 71, 72,187,176,181, 73,117,158, 20, 71, 12, 91,114,114,114, 19, 86,
+124,156,183, 90,249,239, 35,100, 70,139,193, 96, 48, 24,255, 81,131, 85, 26, 22,139,197, 23,128, 42, 41, 41,233,158,117,183,110,
+221, 2, 0,233, 97, 56, 41,213,109,216, 24,229, 27,173,127,227, 12,244, 12, 6,131,193, 96, 84,155,193, 58,120,240,160,244,176,
+152, 40,198, 3,100,180,152,185, 98, 48, 24, 12,198, 67, 6,155, 73,155,193, 96, 48, 24, 12, 6,163,154, 33, 0, 90,150,182,194,
+153,209, 1,132,144,150,206,238,184, 34,125,166,201, 52,153, 38,211,100,154, 76,147,105, 62,124,154, 21,105, 83, 74, 47, 16, 66,
+ 70, 81, 74,191,254, 87, 27,172,191,115,206, 71, 54,132,149,105, 50, 77,166,201, 52,153, 38,211,100,154,149,208,255,215, 27, 44,
+214, 68,200,184,111,132,143,142, 50,176,179,192, 96, 48, 24,140,135, 17,213,131,152,168,240,240,240,186,148,210, 48,142,227,106,
+ 82, 74,247, 70, 70, 70,222, 98, 89, 85,169, 39, 0, 21,165, 84,122, 16, 53,141, 67, 55,253,172, 83,242,158,244,237,127, 41,161,
+147, 70,223, 98,243,230, 65, 50,203, 49, 6,131,193, 96, 48,131, 85, 64,251,246,237, 3,101, 89,126, 17,192, 80, 0,231, 35, 35,
+ 35, 95,116, 86,227,145, 71, 30,209,139,162, 56, 6, 64,123,112,170,176,198,173,187,214, 11,235,208, 21,153,102, 5,123, 55,125,
+ 18,215,189,123,247,182, 7, 15, 30,180, 57,163,217,182,109,219,159, 41,165,189,202, 48, 9, 31,158, 57,115,102,190, 51,122,109,
+218,180,233,193,243,252, 59, 0, 32,203,242,226,179,103,207,238,125, 16, 51,212,219,219,219,213,221,221,253,189,134, 13, 27,246,
+120,241,197, 23,131, 59,119,238,156,145,156,156,124, 90, 20,197,133, 73, 73, 73,231, 43,171,233,233,233,249, 94,139, 22, 45,158,
+124,245,213, 87, 27,116,238,220, 57, 35, 41, 41,233,180, 36, 73,149,210,236, 56,241,100,125,106, 74,239,245,203,138, 55, 49,118,
+222,134,128,243,146,254, 69, 0,107,156, 54,226,163,127,169,203,169,120,213,233,229,253, 18, 1, 32, 48, 48,176,190, 40,138,221,
+ 20, 69,105,165, 82,169,206,243, 60,127, 40, 62, 62,254, 70, 85,206,231,191, 69,147,193, 96, 48, 24, 15,129,193,106,222,188,185,
+171, 70,163, 25,192,113,220,176, 54,237, 58,119,234, 55,232, 21, 34,114, 6,124,240,246, 11, 78, 71, 54,194,195,195,219,131,240,
+ 95,191, 60,126, 65,112, 64, 80, 83,232, 92, 60, 96,178, 3,183,179, 21,104,205, 50,140,173,175, 54,184,126,114, 67, 39, 0,251,
+157,209,165,148,246,218,180,227, 36, 82,178,100, 16,146,223,155,159,227,128, 60,171,130,233, 35, 30,157, 14,192, 41,131,197,113,
+220,180,145, 11, 15,181, 87, 40,240,221,212,174, 26, 0, 15,156,193,242,245,245,125,164, 99,199,142,107,222,126,251,237,186, 94,
+ 94, 94,112,117,117,133, 90,173,174,147,148,148,212,119,220,184,113, 79,251,249,249, 77, 73, 74, 74, 90,225,172,102,175, 94,189,
+214,189,251,238,187, 62,132, 16,168, 84, 42,104, 52,154, 58, 73, 73, 73,125,223,121,231, 29,167, 53, 9, 33, 92,139,199, 71,140,
+112,243,233, 10,142, 35,240,112,213, 35, 59,254,252,224,192,192,183, 54,199,199,199, 59,108,162, 67, 71,239,152, 73,161,155,164,
+ 72,132,180,124, 97,229,206, 59,135,231,222, 12, 9, 9, 33, 35, 70,140,184, 35,203,178, 69, 20, 69,239,136,136,136,113,190,190,
+190,148,227,184,131, 54,155,237,104,122,122,122, 94,121, 9,155, 83,240, 58,159, 53,107, 60,107,216,237,134, 71, 41,165, 93,155,
+ 52,105, 66, 70,142, 28,153, 33,138,162,197,106,181,250,172, 89,179,198,113,205, 98,212,174, 93,187,134, 86,171,237, 66, 41,237,
+ 86,165,116, 22, 99,112, 15,114,118,243, 94,218,166,178,235, 75, 28,190, 7, 0, 61,165,244,150, 3,219,250, 0,112,161,148,198,
+253,211,154,127, 7,126,126,126,217,148, 82,181, 51,255,163,209,104,106, 57, 83, 94, 25, 12, 6, 51, 88,229, 85,128, 36, 52, 52,
+180, 51, 33,228,165,192,160,134, 3, 6,190, 56,218, 16,216,168, 37,242, 20,119,196,165, 83, 68, 29,248, 1,132,144,159, 28,213,
+107,216,176,161,214,195,195,227,253,128,198,109,199,143,154, 56,155,187,112, 91,143, 67,113, 50, 84,156, 29, 60, 0,187, 57, 13,
+ 57, 41, 49,184, 29,123,208, 34,203,242,201,202, 28, 92, 82,166,132,195, 49,118,240, 92,190,185,226, 57, 2, 85,229,231, 15,175,
+ 75, 1,252,126,206, 2, 66, 72,189, 7, 45, 35,141, 70,227,147,125,251,246,221, 60, 97,194, 4,149,217,108,134,213,106, 5,165,
+ 20,122,189, 30,190,190,190,248,233,167,159, 84, 67,135, 14,253,216,223,223,255,108, 98, 98,226, 41, 71, 53,135, 15, 31,190,249,
+205, 55,223, 84,197,196,196, 64, 16, 4, 24, 12, 6,232,245,122,212,170, 85, 11, 17, 17, 17,170,215, 94,123,205, 33,205,166, 77,
+155,118,208,233,116,243,218,181,107,215,182, 97,176, 55,159, 94,171, 49, 0, 32, 32,168, 17,220,112,187,235,245, 20,159,180,176,
+176,176, 88,179,217, 60, 63, 54, 54,246,215,242,180, 90,190,177,195, 83, 5,242,246,138,183, 59,113, 42,158, 39, 99, 63, 61,218,
+123,253,175,135,150,117, 13,111,152, 9,192,180, 99,199, 14,107,239,222,189,237, 35, 71,142, 20, 98, 99, 99,185, 79, 63,253,180,
+245,254,253,251,251,249,251,251, 31, 73, 76, 76,252,161, 52,205, 57,179, 65,118,164,252,122, 89, 16, 37,255,154, 93, 69,219,211,
+254, 23,191,120,237,181, 81, 57,254,254,254, 98,129,166,173,119,239,222,246,209,163, 71,219,175, 93,187, 70, 22, 47, 94,220,114,
+207,158, 61,207, 24,141,198, 35, 9,249,111, 61, 40,147,176,161, 75,119,251,180,121, 94,211,167, 93,205, 99,111,141,125, 61,219,
+215,215, 87,170,108, 58, 75,208,168,138,235,139,195, 3,152, 75, 8, 89, 77, 41, 61, 81, 78, 61,208, 6,192, 96, 0,159,222, 39,
+205,114, 49, 24, 12,241, 86,171,213, 27, 0,244,122,125,154,197, 98, 9,116,224, 97,140, 44, 93,186, 20, 26,141, 6, 28,199, 65,
+150,101,200,178, 12, 69, 81, 64, 41, 45,250, 46, 28, 16, 52,117,234, 84,214,156,205, 96, 48,170,207, 96,133,133,133,253,210,123,
+224, 43, 61, 59,118,237, 9, 73, 83, 7, 49,169, 4, 9,113, 20, 42, 94, 2, 7, 5,113,167,183, 82,158,231,127, 40, 81,113, 93,
+ 40, 43, 2,230,225,225,121, 96,208,232,217,205,130, 90,116,193,246,139, 2, 20,217,142,244,203,191, 35,235,198, 41,152,110, 95,
+182,139,182,188,139,132,144,227, 90,173,246,211,243,231,207,155, 43,210, 44,141,252,119, 8, 82, 16, 74, 0, 5, 0, 40,192,145,
+210, 42,216, 10, 53, 57,142, 59,191,245,192, 69, 35, 81,187, 2,192, 53, 7, 42,237,106, 31, 93, 81,150,166,159,159, 95,239,113,
+227,198,109,236,211,167, 15,151,158,158, 14, 0,216,178,101, 11,206,156, 57, 3,163,209,136,201,147, 39, 35, 32, 32, 0,115,230,
+204,225,135, 15, 31,190, 0,192, 99,142,104,190,247,242,203, 27,251,140, 28,201,157, 57,115, 6,146, 36, 97,239,222,189,184,112,
+225, 2,234,213,171,135, 9, 19, 38, 32, 32, 32, 0, 51,102,204,224,199,140, 25, 83,174,102,219,182,109, 47, 6, 6, 6, 26, 95,
+126,249,101,174,111,223,190, 36, 53, 23, 24,179, 44, 38,191, 0,106,116, 24, 50,248, 57,238,233,143, 94,199,158, 61,123,154,173,
+ 94,189,122, 77,219,182,109,237,103,206,156,241,118,248,124, 18, 66,107,184,123,101, 0, 72, 5, 0,119,119,119, 87, 0,102, 0,
+230,144,144, 16,213,151, 95,126, 41,197,196,196, 92,235,213,171,215, 83, 0,126, 40, 75, 83,146,148,186,223, 78,239,137,145, 31,
+238,209,205,154,245,126, 42,199,169, 69, 0, 2, 0,120,122,122, 22,105, 6, 7, 7,171,150, 45, 91, 38,198,196,196,196, 21,104,
+110, 40, 47,157,162,218,171, 83,155, 71, 91, 8, 7, 19, 50, 90,102,175,191,122,252,205,103,117,123, 90, 4,213,202,171,108, 58,
+ 7,247, 32,103, 11,205,211,224, 30,196, 92, 65,148,203, 12,224,175,146,145,172,146,154,148,210, 59,132,144, 85, 0, 54, 16, 66,
+134,149,102,136, 8, 33,143, 0, 88, 7, 96, 0,165, 52,173,162,242, 89, 92, 83,167,211,105,236,118,187,103, 73,227,227,172,102,
+177,180,152, 35, 35, 35, 17, 30, 30,142,226,223,133, 15, 22, 5,219,120, 59,122, 29,241, 60,143,175,190,250, 10, 28,199, 65,163,
+209, 64,173, 86, 67,163,209,220,243,105,211,166, 13, 40,165, 32,132, 56,124,189, 19, 66,248,128,128,128,183, 85, 42,213,112,187,
+221,238,167,211,233, 82, 68, 81, 92,231,229,229,245,113,100,100,164,248, 32,212, 33, 76,147,105, 62, 8,154, 21,208, 14, 64,241,
+107,218, 14, 64, 91,240,119, 58,242, 27,170,188, 74, 44, 47,190, 93,225,119, 97, 61,227, 93,240,127,180,152,110, 26,128,211,213,
+106,176, 8, 33,148, 82, 74, 10,191,203, 56,153,110,137, 22, 79,228,197,121, 67,197, 41, 80,241, 4, 42, 30, 0, 8, 50, 18, 47,
+193,154,151,126, 60, 50, 50, 50,222,145,157,234,245,250,121,131,199,206,111, 38,123,181,195,111,231,236, 16,115, 18,144,120,232,
+ 19,106, 78,187,178,138,231,249,213,178, 44, 95,142,138,138, 18,171,122,112, 10, 5,228,226,198, 74, 1, 8, 42, 61, 45, 69,241,
+ 23, 70,167, 60, 40, 14,217,215,215,183,223,148, 41, 83,126, 8, 11, 11, 35,107,215,174, 69,203,150, 45,177,106,213, 42,122,229,
+202,149,207, 8, 33,159,197,199,199, 63,102, 50,153, 86,255,240,195, 15,232,216,177, 35, 60, 60, 60,218,132,135,135,171,203,171,
+216,125,125,125,251,173,121,235,173, 31, 90,117,238, 76, 22,247,232, 1,223,231,159,199,198, 67,135,104, 92, 92,220,103,132,144,
+207, 18, 18, 18, 30,179, 90,173,171,191,249,230, 27,180,109,219,182, 66, 77,158,231,253, 55,108,216,192,187,184,184,128,231,121,
+212,215, 3, 62,158, 26,124,188, 41, 6,105,217, 86, 76, 26,224, 11,149, 74,133, 30, 61,122,192,207,207, 79, 53,118,236,216,114,
+ 71,183, 94,248,178,119, 86,232,232, 29, 75,198, 44, 62, 54,133, 35, 28, 13,242, 81, 29,240,224,179, 46, 1,158, 42, 0, 30,222,
+222,222, 34, 0,216,237,246,236,223,126,251, 77,138,138,138,170, 21, 20, 20,228,229,204,121,141,142, 62,107,174, 89,211, 43,163,
+ 65,131, 6, 42, 0, 30, 94, 94, 94, 85,210,124,169,119,107,109,158,197,142,131,103,174, 63, 58,114,193,129,206, 13,124,221,206,
+245,111, 87,107, 31, 0,147,179,154,133,102,105,112, 15, 98,222,188,249,120, 26,168, 12, 72,185, 34,132,108, 17,114,182, 8, 33,
+ 71,130,120, 71, 28, 60, 97, 73,203,205,123,169,139, 19, 21,230, 41, 66,200, 48, 0,235, 74,154,172, 98, 70,104, 24,165,244,188,
+179,154,118,187,125,111,161,241,209,235,245,222,132,228, 27, 67,189, 94, 47, 90,173,214,167,157,209, 4,128,200,200, 72,132,133,
+133,213, 40,208,164,133,223, 5,134,213,105, 10, 95, 90,207,243, 60,194,194,194,208,183,111, 95,132,132,132, 32, 49, 49, 17, 7,
+ 15, 30,196,149, 43, 87,138, 34, 92,206, 64, 8,225, 3, 3, 3,247,247,236,217,179,249,248,241,227,245, 1, 1, 1,136,137,137,
+ 49,126,249,229,151,255, 59,122,244,104,159,240,240,240, 46,229, 93,139, 12,198,127, 1, 71, 60, 8, 0,111, 66,200,246, 98,117,
+203, 51,133,191,167, 78,157, 58,125,193,130, 5,127, 18, 66,182, 23, 95, 94,124,187,226,223, 5,251,220, 78, 41,125,102,218,180,
+105, 45, 22, 46, 92,248, 97,225,182,247, 37,130,165, 86,171, 95,184,176,243,179, 99,141, 5, 90,207,167, 69,159,130,186,140, 0,
+160,184,113,118, 39, 20, 69, 89,231,136, 78,104,104,104, 23, 99,147,142,175,251,134,116,196,142,179, 54,228, 94,221,133, 91, 39,
+150, 39, 40,146,125, 76,116,116,244,225,234, 56,168,176,176,176, 1, 53,107,215,131, 77,160, 5, 6,235,110,147,245,176, 16, 16,
+ 16,240,220,252,249,243, 35,130,131,131,201,230,205,155, 65, 41,197,143, 63,127, 11,148,161, 0, 0, 32, 0, 73, 68, 65, 84,254,
+ 72,175, 94,189, 58, 54, 37, 37,101,109,225,253, 56, 36, 36,100, 57,207,243, 6,142,227, 96, 52, 26, 53,231,206,157,243, 5,112,
+163, 44,205,141, 83,166,124,223, 38, 36, 4, 73,131, 7,227, 81, 73,194,183,107,214,208, 27,138,114,151,102,227,198,141,151,171,
+ 84, 42, 3,207,243, 8, 8, 8,208,156, 61,123,182, 76, 77, 0, 16, 69, 17,231,206,157,131, 74,165, 66,173, 90,181,240,209,203,
+254, 56,121,249, 14, 90, 5,249,192,146,153,136, 77,251,162, 17, 23, 23, 7, 79, 79, 79,199, 12,208,202,222,243,234, 55, 14,107,
+186,102,221,166,100, 29,205,188,144,145,145,225,149,145,145, 1,119,119,247,108, 89,150,197,143, 63,254, 88,125,245,234, 85, 15,
+189, 94, 15,157, 78, 7, 81, 20,157,114,214,146, 36,113,213,173, 89,211, 77,143,129,143, 55,215, 60,213,169, 49,142,158,189, 17,
+254,201, 79,113, 45, 19, 46, 29, 24, 81, 21, 77, 80, 25, 56,209, 37,234,158,229,254,195,189, 43,249, 84,122,162,192,100,237, 32,
+132,104, 10, 22,167, 22,124, 15, 43,175,169,175, 2,205,162,223, 54,155,173,120,148, 73, 93, 25,205,240,240,240, 66, 13,165,196,
+195, 91, 90, 97,228, 74,175,215,167, 57,170, 39,203, 50,180, 90, 45, 90,180,104,129,119,222,121, 7, 49, 49, 49, 56,122,244, 40,
+124,124,124,208,171, 87, 47,168, 84, 42, 36, 36, 36, 56,109,176,252,252,252,222,126,226,137, 39,154, 46, 93,186, 84, 31, 31, 31,
+143,152,152, 24,184,187,187, 99,222,188,121,134,169, 83,167, 6, 29, 59,118,108, 26,128,185,236, 22,203, 96, 56, 92,159, 60, 83,
+242, 55, 33,100,251,130, 5, 11,158, 41,205, 84,149, 98,230,238, 90,190,112,225,194, 15,139,253,206,172,206,180,114,197, 29,100,
+121, 27,138,162,248,136,103,109, 95,239, 81, 47,246,130,162, 0,146, 2, 72, 50,133,217,108,194,173,152,131,102, 65, 16,182, 84,
+180,179,230,205,155,187, 18, 94,179,226,213,113, 51,201,142,104, 27,172,119,226,145,114,124,217, 77, 21, 71,219, 87,179,185,138,
+152,249,241,183, 56,125,221, 94,208, 76,152, 31,201,146,149,252,191, 31, 6,124,125,125, 67,158,121,230,153,136,160,160, 32,178,
+105,211, 38,216,108, 54, 36, 36, 36,208,168,168,168,209, 73, 73, 73,107,139, 85,240,195,159,126,250,105, 3,207,243, 16, 69, 17,
+215,175, 95, 55,221,190,125, 59,161, 44,205,145, 93,186, 68,180,242,247, 71,226,139, 47, 66,206,206,198, 57,131,129,158,166,244,
+ 30,205, 1, 3, 6, 24, 52,154,252,251,239,181,107,215,202,212, 44, 81,176, 97,183,219,145,148,148,132,243, 81, 39, 97, 74, 56,
+129,141,107, 86, 98,205,154, 53,136,139,139,131, 74,165,130, 36, 57, 62, 78, 66, 50,167,218,130,125, 13,185,197,151,229,228,228,
+120, 68, 69, 69, 41,151, 47, 95,246, 40,188,113, 2,128,162, 40,149,182,214, 37, 53,139, 34,164,149,212, 52,232,212,120,172,109,
+ 16, 47, 42, 84, 83,229,116,202,185, 66,169,203,133, 59, 98, 21, 42,176, 19, 0, 52,197,250, 29,249, 84,214, 92,149, 48, 62,247,
+ 52,173, 85,150,200,200,200,194,136,213, 93, 88, 44,150, 64, 74,169, 75,100,100, 36, 28,233,127, 85, 44, 47,161,213,106,209,175,
+ 95, 63, 92,190,124, 25, 73, 73, 73,224,121, 30, 54,155, 13, 54,155, 13, 97, 97, 97,208,104, 52, 78,167, 95,167,211,189, 48,126,
+252,120,151,184,184, 56,100,100,100,128,227, 56, 72,146, 4, 89,150,241,218,107,175,185,232,245,250,161,236,150,201, 96,148,238,
+ 65, 8, 33,163, 8, 33,163, 74, 26,164,170, 26,180,210, 52,166, 77,155,214, 2,128,238,111,137, 96, 21,134,231,202, 50, 45,158,
+181,125, 35,166, 45, 88,165,250,229, 28,143,204,148, 88, 88, 83, 99, 97, 12,235,143,212,216, 99,160,178,240,235,197,139, 23, 77,
+ 14, 84, 54,111, 15,124,125,118,192,145,120, 29, 44,130, 21,105, 71, 63, 81, 8,149, 70,157, 60, 25,153, 91, 93,230,202,211,171,
+110,196,123, 31,125,171,250,245, 79, 53,238, 36,199, 34,102,235, 20,200,130,185,100,166,237,114, 50,227, 73,120,120,120,221, 70,
+245, 12,224, 52, 58,252, 65,136,207,224,193,131,249,205,155, 55,223,183,206,174,201,201,201,177,190,190,190, 31,216,237,246,153,
+ 28,199,225,214,173, 91,244,236,217,179,163, 18, 19, 19,215, 23,110, 99, 52, 26,159,108,223,190,253,103, 83,167, 78, 5, 33, 4,
+251,247,239,135,201,100, 58, 70, 41, 85,202,211,172,245,231,159, 51,187,153,205,216,226,229, 69, 87,202,242, 61,154, 61,123,246,
+252,108,226,196,137, 32,132,224,200,145, 35,229,106, 22, 39, 46,157,194,100, 3, 2,189, 56,120,122,122,226,224,193,131, 69,253,
+ 93,178, 68, 55,200,146, 22,190,106, 75,165,207,137,162, 40, 36, 43, 43,139,183, 88, 44,188, 40,138,156, 74,165,162,133, 55, 97,
+ 81, 20,149,234,210,148,101,185, 74,154, 37, 30, 92,170,150, 78, 49,187,116, 35,101, 79,171,142,102, 39,123,193,183,182, 42,230,
+170,208,248, 20,118, 64,215,233,116, 69, 70,197,153, 40, 83, 25, 17,172, 74,173, 47,205, 96,169,213,106, 52,106,212, 8, 39, 78,
+156,128,187,187, 59,106,212,168, 1,131,193, 0,157, 78, 7,119,119,119,104,181, 90,112, 28,231,148,201, 18, 4,193,223,223,223,
+ 31,127,253,245, 23,244,122,125,209, 71,171,213, 34, 36, 36, 4,102,179,217,151,221, 90, 25,140,210, 61, 72,105, 51,185, 87, 71,
+ 51, 94,105, 38,107,225,194,133, 31, 22,143,130, 85,171,193, 42,215,180,212,246,141,152,250,225, 42,213,230, 40, 14, 89, 41, 49,
+184,177,115,186, 36, 11,230, 52, 69, 17,235,101, 94, 59, 10, 69, 81,214, 58,120, 80,143,214, 13,106,133, 99,209, 2,172, 49, 63,
+193,158,117,125, 89,100,100,228,177,234, 52, 87,211, 23,126,171,250,249,156, 10,119,146, 99,113,237,183,169,178,100, 55,189, 30,
+ 21, 21,181,169,178,186, 29, 58,116,104,248, 72,219,208,175, 94,170, 35,116,236, 55, 56, 8, 90,131, 6, 83,174,169,158,184,120,
+ 60,254, 72,219,182,109, 71,159, 57,115,230,226,125, 52, 89, 11,235,214,173,171, 54, 26,141, 83,146,146,146, 94, 75, 78, 78,222,
+ 88, 44,202,212,123,224,192,129, 27,199,140, 25,195,185,187,187, 35, 35, 35, 3,179,102,205,178,240, 60, 63,197, 17,205,125, 94,
+ 94, 83, 78,203,242, 61,154,221,250,143,222, 56,229,127,175,112,106,181, 26,233,233,233,152, 51,103, 78,133,154, 84, 95,143, 60,
+255,233, 77,212, 48,168,161,211,232,145,112,204,132, 15, 7,228, 55, 21,105, 52, 26,156,201,105, 9,206, 61, 0, 6,141, 10, 81,
+137,153, 16,221, 46,146,240,209, 81,234,200,149, 97, 21,154, 4, 66,136,156,158,158,174,142,139,139,211,219,237,118, 46, 48, 48,
+208, 10,228, 55,241,101,102,102,106,180, 90, 45, 8, 33,130, 36, 73, 78,197, 46, 51, 51, 51, 85, 87,175, 94,215,137,162, 88,166,
+166, 32, 8, 85,142,135, 86, 53,157, 16,179, 75, 15,249, 9,233, 85, 53, 88, 9,132, 16, 99,225,223,213, 81, 94,173, 86,171,119,
+177,166, 65, 80,234,120,255,176, 50, 34, 88,149, 94, 95, 74,221, 4,173, 86,139,171, 87,175,194,219,219, 27,146, 36,193,213,213,
+ 21, 6,131, 1, 6,131, 1, 22,139, 5, 90,173, 22, 60,207,151,218,201,189, 44,180, 90,109, 98, 76, 76, 76, 35, 79, 79, 79, 40,
+138,114,151,201,138,139,139,131,171,171,107, 50,187,181, 50, 24, 78, 5, 60,182, 23, 55, 90,132,144,237, 83,167, 78,157, 94, 89,
+189,169, 83,167, 78,175,106, 84,172, 92,131, 85,216,169,172,100,231,178,176,176,176, 1, 30, 94,245, 34, 38,125,240,141,234,135,
+ 51, 28,178, 83, 46, 35,121,207, 12, 73, 22,204,195,213,106,245,137,155,199, 86,174,227, 56,206,114,246,236,217,163, 14,156, 20,
+ 46,188, 99,151, 86,188,166, 6, 40,181,192,154,116, 18, 42,149,234,179,234, 52, 87, 83, 23,172, 82,109,142, 86, 33, 51, 37, 6,
+ 55,126,159, 38,203,130,185,210,230,170,123,247,238,170,188,188,188, 9, 45, 92,229,247,222, 9, 16, 53,126, 90, 5,151,190,154,
+130,152, 0,119,180,232,104, 64, 96, 19,185,245,201, 93,182,227,225,225,225,139,109, 54,219,194,139, 23, 47, 10,247,163,176,221,
+186,117,107,158,191,191,255,175,201,201,201, 69, 35, 58,124,125,125,251, 13, 27, 54,108, 93,183,110,221,184,245,235,215,163,127,
+255,254,120,255,253,247,105,122,122,250, 91,201,201,201,215, 42,171, 57,112,252,234, 31, 6,247,121,132, 12,153,244, 41,102,190,
+254, 24,190, 93, 54,191, 66,205, 90,125,214,158, 52,250,246,225, 27,215,178, 96,236,144,206,249, 79, 10, 27, 47,227,202,237,252,
+128,167,168,168,144,141, 58,248,106, 68,107,112, 28,193,225, 51, 87,176,250,118, 75,146, 20,127,240, 2, 16,214,164,188,116,202,
+178, 76,190,255,254,123,247,212,212, 84, 46, 36, 36,228, 78,235,214,173, 77, 90,173, 86,177, 88, 44,178, 94,175,151, 92, 93, 93,
+ 21,171,213,170,189,113,227, 70,205,164,164, 36,190,176, 25,206, 17,246,236,217, 83,175, 73,147,102, 25,161,161,161,101,106, 38,
+ 39, 39,115,206,104,150, 70, 85,211, 89,102, 4, 75,168, 90, 4,139, 82,218,132, 16, 98,174,138, 9,250,187, 40,136,132, 1,128,
+169,172,169, 24,156,137, 96, 21,246,171,210,106,181, 56,126,252, 56,158,122,234, 41, 40,138, 2,157, 78, 87, 52, 45,201,169, 83,
+167,160,209,104,192,243,188, 83,105, 21, 4, 97,253,178,101,203,222, 93,184,112,161,107, 97, 51,164,139,139, 11,180, 90, 45, 22,
+ 47, 94,108,178, 88, 44, 27,217, 45,147,193,162, 87,165,123,144, 18,164,149,136, 94,217,139,253, 78, 67,254,187,149,159, 41,248,
+ 27,165,252,109, 47,101, 89,198,130, 5, 11, 14, 20,139, 92,165, 85,231,113,149, 25,193, 10, 13, 13,125,194,179,182,111,196,187,
+ 31,124,163, 90,115,146, 71, 86,202, 37,164, 31,120, 79, 82, 68,203,240,168,168,168,194,254, 86, 61, 28,221, 81,120,120,120,195,
+250, 77, 58,184,164,230, 42,160,138, 4, 41,251,122,234,153,211, 39, 83,171,122, 0,161,161,161, 79,120,122,213,141,152, 60,127,
+149,106,125,164, 10, 89,201,151,145,188,103, 70,149,204, 85,155, 54,109,122,232, 84,220,183,227,253,197, 90,207,212,150, 32, 83,
+ 96,237, 45, 53, 54, 68,159, 60, 42, 16,197,214,226, 17,125,143,150,157,181,120, 98,168,139,234,218,121, 97,202,153,189,120, 51,
+ 52, 52,116,120,116,116,244,206,251, 81, 56, 19, 19, 19,139,140,144,191,191,255,192, 17, 35, 70,124,223,189,123,119,178,115,231,
+ 78, 40,138,130, 69,139, 22,209,115,231,206,141, 47, 30,141,114, 86,115,224,248,213,223, 63,215,175, 39,153,177, 89,196, 29,179,
+ 11, 38,205,254,148,218,147,207, 87,168,217,220,168,105,254,213,123, 47, 1, 0,254,184,120, 11,251,206,101, 34, 41,221,140,145,
+237,129,139, 0, 84, 68, 68, 77,238, 22,102,174, 62,143,214,129, 53, 48,232,177,198,232,218,182, 49,190,248,254,119, 99,237, 94,
+ 31,214, 77,223, 53,189,204, 73, 42, 21, 69, 73,223,179,103,143,203,204,153, 51,243,234,213,171,167,202,203,203,227,138,247, 97,
+210,104, 52,168, 87,175,158,148,149,149, 37,236,217,179,167,129,162, 40,119,202,189, 24, 84,220,173,145, 31,238,241,215,114,138,
+117,192,128,129,180,118,237,218, 42,139,197, 82,170,102, 70, 70,134,176,127,255,254, 32, 69, 81,210, 43, 58,151,188,156,155,190,
+120,221, 97,207,193, 61, 90,171, 27,248,222,219,137,223,217,116,222,109,176,238,136, 48,190, 82, 27,246, 59, 34,236,105, 18,132,
+ 12, 17, 66,154, 8,201,244,192, 13,231,168,108, 7,244, 10, 34, 97,222,213, 21,193,210,104, 52, 72, 72, 72,192,190,125,251,208,
+190,125,123,184,185,185,193,100, 50,225,196,137, 19,184,117,235, 86, 81, 4,203, 25,110,222,188,185, 68,173, 86,247, 30, 55,110,
+ 92,147, 49, 99,198,184, 54,109,218, 20,241,241,241, 88,178,100,137,249,252,249,243,113,181,106,213, 90,192,110,175, 12,134, 67,
+156,254,183, 37, 88, 85,206, 83,221,164, 71, 6,205, 84, 69,252,161, 66,102,210,159,200, 62,242,126, 73,115,229, 72, 40,175,232,
+109,219,178, 44,183,105, 17,250, 8,174,221,150, 32,229,196, 3, 84,142,174,100,120,240,174, 55,120,115, 28,247,110,167, 65, 51,
+ 85,107, 78,171,144,157,124, 9,105, 7,102, 58,109,174, 74,209,156,122, 96,210,160, 90,144, 36,156,219,177, 17,159, 38,104, 76,
+215, 45,100, 74,116,116,212,247,148, 82, 26, 26, 26, 58, 52,241,138,184,164,195,211,122,247,231, 6, 62,143,129, 3, 36,215,137,
+175, 70, 76, 6,176,179, 44,205,106, 10,141,150,171,233,235,235, 27,210,172, 89,179,136,222,189,123,147, 45, 91,182, 32, 55, 55,
+ 23,153,153,153,248,227,143, 63,222, 76, 78, 78,254,190,178,154,245,154,247,141, 24,208,183, 39,153,249,163,140,216,147,155, 80,
+195,118, 19,182,148,147, 14,105, 94, 72, 16,206,190, 56,249,187, 80,157,222, 0,217,224,135,119,251,251,162,169, 55,129,197,252,
+255, 93,246,218,213,252, 11,121,200,194,209,232,186,248,117,247, 97,240,138, 25, 55, 83,173,137,233,251,254,223, 92,149,150,206,
+180,180,180,201, 26,141,166,235,136, 17, 35,158,239,210,165,139,219,168, 81,163, 82,221,221,221, 77, 90,173,150,175, 85,171,150,
+150, 82,170,221,189,123,183,239,173, 91,183,106, 2,216,144,150,150,118,184,172,116,206,154, 13,138,217,253,154, 94,186, 4,114,
+250,180,111,151,225,251,213, 67,187,116,233, 82, 99,212,168, 81,105,197, 53,101, 89,214,238,222,189,219,239,214,173, 91,158, 0,
+214,167,165,165, 29,169,232,124,158,219,144, 26,212,168, 87,226,251,203,239,228,190, 21,236,239,205, 63,219,163,133,186,102,141,
+252,247, 92, 59,155, 78,160,196, 60, 88,227, 63,109, 85, 94,153, 41,107, 30,172,251, 81, 62, 45, 22, 75,160,179, 81, 49, 71,210,
+ 25, 21, 21,101, 46, 57, 31, 86,121, 17,172,178, 52,181, 90, 45, 84, 42, 21,210,210,210,176,103,207,158,187,230,194,210,106,181,
+ 69,211, 56, 56,163, 73, 41,149, 9, 33,143,203,178,252,246,196,137, 19,135,155,205,102, 63, 23, 23,151, 20,187,221,190,174,102,
+205,154,229,206,131,117, 63,242,136,105, 50,205,251,169,249,176, 81, 94, 31, 44,195,209,200, 43,224,117,169,200, 61,249,177,211,
+230,170, 52,110,221,177, 34, 81, 47, 65,188, 19, 11, 0,103,171, 41,180,232,118, 36,234, 42,212,250, 12,100,255,241,145,172,136,
+150, 42,245,185, 42, 40, 56, 34, 36, 9,246, 67,235, 49,254,138, 62,131,112,124,251,168,168,211,183, 11,215, 71, 71, 71,111, 12,
+ 13, 13,221,191,107,141,233, 76,143,174, 82,237,243,113,191,130,227, 56,225,126,103,102, 65, 39,245,249, 63,254,248,227, 76,147,
+201,132, 59,119,238,208, 83,167, 78,141, 73, 74, 74, 90, 87, 85,205, 79,191, 27, 56,243, 74,108, 54, 12,185, 39,169,237,198,214,
+177,197, 71, 21,150, 71,214,111, 47, 61,218,252,181,157,157, 72,214,133,246, 46, 87, 86, 76,252, 53,195,215,211,247,141, 55, 72,
+189,122,245, 80,179,102, 77,120,121,121, 33, 47, 47, 15,215,206,252, 78, 45, 41, 41, 54,169, 70,248, 87,246,122,143,239, 73,219,
+215,239,168, 3,121, 79, 1, 28, 10, 15, 15, 63,126,240,224,193,167,142, 29, 59,214,239,241,199, 31, 79,237,212,169, 83, 94, 84,
+ 84, 84,253,184,184, 56, 31, 0,219,124,124,124,118, 86, 56,215, 16,165,116,214,255,143, 74, 59, 24, 30, 30,126,172, 64,179,111,
+143, 30, 61,210, 58,118,236,152, 23, 21, 21, 85, 63, 62, 62,222, 91,150,229, 95, 27, 54,108,184,235,224,193,131,146, 99,101,116,
+150, 2, 96,118,171, 39, 39, 45,186,156,229,186,228, 90,210,157, 33,173, 26,251, 17, 0,196,233,116,162,196, 60, 88,229,204,115,
+ 85,209,122, 7,136,252, 27,138,105,149, 53, 75, 70,194,194,194,194, 2, 11,205, 84,201,111, 39,174,121,180,110,221, 26,197, 71,
+ 58,114, 28,119,215,135,231,121,168, 84,170,202,212, 81, 50,128, 69, 5, 31, 6,131,241, 95, 55, 88, 42,149,106,146, 41,242,243,
+185,148, 82,111, 0, 83,163,162,162,118, 85,101, 71, 26,141,230, 88,212,238,111,178,180,126,151, 61,173, 9,135, 77, 28, 33,107,
+170,227, 0, 8, 33,147, 77,145,159,207, 5,224,165, 40,202,123,209,209,209,219,170,170, 41,203,242,226, 71,151,108, 5, 96, 32,
+178, 44,127,114, 54, 50,234,118,201,109,162,163,163,211,219,180,105,243,250, 59, 35,215, 20,189, 0,250, 65,200,208,194, 78,234,
+ 65, 65, 65, 83,110,222,188,121,215, 8,192,170,106, 26,234,182,155, 34,166, 71,143, 78, 74, 74,250,193,153,255,191,184,234,169,
+227,192, 83,199,129, 41, 75, 66, 66, 66, 6, 79,159, 62,125, 89,179,102,205, 12,181,107,215, 38, 39, 79,158,164,215,174, 93,147,
+ 76, 38,211, 39, 23, 46, 92,248,160, 82,119,236,124, 83,178,205,215,215,119,223,158, 61,123, 6,236,222,189,187,189,162, 40,167,
+ 20, 69,153,159,156,156,108,169,170,230,174, 93,187, 6,236,220,185,179, 61,165,244, 4,165,244,215,164,164, 36,107,101, 52,207,
+239, 94,244,127,236,157,103,120, 20, 85,195,134,159, 51,179,125, 55,189,145, 70, 9, 9,132, 16, 18, 32,155, 2,129, 64, 64,144,
+174,162,160, 84, 1, 41,138, 32, 8,250, 34,189,247, 94, 68,225,149,222, 4, 20, 16, 5,164, 72,111, 9,161, 67, 40,129, 4,210,
+123,207,110,182,204,156,239, 7,129, 15,120,129,108, 2, 42,226,185,175,107,174, 77,102,103,238, 61, 83,246,236, 51,103,206,204,
+148, 0, 24, 84,239,173,177, 19, 46, 20, 39,175,224,101,214,129,119,239,222,141,125,137,114,222,126,201,247,203, 99,231,159,176,
+139,190,180,179, 34,183, 95,176, 48, 0,209,225,195,135, 87,100, 22,254,225, 45, 74, 24, 12, 6,227, 69,149,203,159, 54, 0, 8,
+120,252,255,240,240,112,171,250,245,235,191, 19, 16, 16,160,126, 85,206, 63,163,156,111,130,211,195,195, 35,224,117,118,214,169,
+ 83,103,120, 88, 88, 88, 70,131, 6, 13,190, 3, 32, 97,219,253,245,115, 2,208,252, 9,206, 42,108, 27, 49, 39,115, 50,167, 5,
+254,129,127,166,255,175, 24, 36,127,101,152, 59,121,242,100, 17,128, 95, 88,172,253,243,121,188,147,250,235,232,140,141,141, 93,
+ 4, 96, 17,219, 82,175,245,193, 87,241,159,224, 76,103,107,150,193, 96,252, 27,224,216, 42, 96, 48, 24, 12, 6,131,193,120,181,
+ 16, 0, 1,207, 57,210,180,184,181,130, 16, 18, 80,137, 35,217, 43,204,201,156,204,201,156,204,201,156,204,249,239,114,150,231,
+166,148, 94, 33,132, 12,124,214,157,220,255, 81, 1,171,162, 87,219, 84, 72,206, 46, 97,101, 78,230,100, 78,230,100, 78,230,100,
+206,138,251,255,241, 1,139,157, 34,100, 48, 24, 12, 6,131,193,120,197, 72,216, 42, 96, 88,130,135,135,199,148, 70,141, 26, 13,
+140,142,142, 94,124,255,254,253, 74,221,125, 58, 36, 36,164,190, 90,173,158,100, 54,155,181,102,179, 89,161, 82,169, 98, 11, 11,
+ 11,191, 59,119,238,220,150,202,150, 43, 36, 36, 36, 88,173, 86, 79, 48,155,205, 13,202,156,215,242,242,242,150, 93,184,112,225,
+167,215,201,201, 96, 48, 24, 12, 22,176, 30,177,104, 44,113,149,149, 66, 50,120, 62, 77, 2,128, 26, 53,106, 84, 55,153, 76,205,
+ 69, 81, 12,148, 72, 36,151,121,158, 63,154,144,144,112,239,101, 10,240, 79,113,254, 83, 32,132, 84, 81,171,213,189, 9, 33,173,
+ 41,165,191,151,148,148,108,160,148,190,212, 35,137,170, 84,169,226,220,181,107,215,145,139, 23, 47, 70,191,126,253, 70, 57, 59,
+ 59, 47,205,204,204,172,208, 21,102, 77,155, 54, 29,172, 82,169, 38,125,254,249, 16, 85,112,112, 48, 81,171,213,184,121,243,102,
+208,130, 5,243, 23, 53,111,222,188,203,177, 99,199, 62,160,148, 86,232,241, 46, 17, 17, 17, 95,170, 84,170,177,195,135, 15, 87,
+ 52,108,216,144,200,100, 50, 92,188,120, 49,120,201,146, 37,203,155, 55,111,222,249,216,177, 99, 61,104, 5,207,129, 63,237, 84,
+ 42,149,184,114,229, 74,240,252,249,243, 43,229,212, 14, 58, 47,149,169,141, 18, 0, 48,150,200,204, 49, 43,130, 76,150,142, 99,
+213, 19,131,193, 96,188,129, 1,107,249,104, 50, 94, 14,124, 13, 25,200,228, 65,242,125, 43,127,115,188,239,235,235, 75,250,245,
+235,151, 35, 8,130,206,100, 50, 57,175, 93,187,118,136,187,187, 59,229, 56,238, 72,105,105,233,137,172,172,172, 34, 75, 62,212,
+201,201,201, 74, 46,151, 71, 80, 74,155,249,250,250,146,254,253,251,231,152, 76, 38,157, 94,175,119,217,184,113,227, 80,119,119,
+119,209, 98, 39, 33,100,242, 36,144,141, 27,237, 53,122,189,178, 41,165,180,249,171, 42,231, 63, 40, 84,201,149, 74,101, 39,169,
+ 84,250,137,163,163,163, 83,187,118,237, 46, 85,169, 82,229,122,122,122,122,157,189,123,247,238,177,177,177,201, 52,153, 76,171,
+245,122,253,110, 74,105,133,239, 56, 47,149, 74,171, 19, 66,144,156,156, 12,169, 84, 42,149,203,229, 53, 0, 92,181,116,254,176,
+176,176, 0,153, 76, 54,229,187, 85,155,149,102,222, 26,217,102, 17,217, 5,128,204,201, 23,147,102, 46,210,204,155, 62,174, 73,
+227,198,141,135, 3, 88, 80,145, 86, 38,149, 74, 53,118,235,214,173, 74, 23, 23, 23,136,162,136,194,194, 66,248,249,249, 97,218,
+180,105,234,153, 51,103,190, 21, 22, 22,246, 41,128,239, 42,235,164,148,194,104, 52,162, 94,189,122,152, 59,119,174,122,210,164,
+ 73, 21,114,106, 87,158,151,154,140, 55,194,140, 37,194, 40, 0, 32, 82,126,118,228,100,135,115, 38,227,141,224,242,198,105, 87,
+226,108,204, 64, 22,178, 24,127, 45,238,238,238,141,189,188,188,126,188,127,255,254, 25,158,231, 63, 78, 72, 72, 40,125, 5,245,
+147, 7,128, 26, 0,236,240,224,194,170, 92, 0,247, 40,125,112,224, 94, 25,156,106,181,104, 15,185,186, 23, 64, 3, 9, 0,112,
+220,101,106, 42,222,144, 21,123,120,207, 75, 57, 21,154,222,160, 66, 32, 1, 68,112,252, 21, 34, 20,175,201,184,118,120, 63,219,
+ 51, 24,175, 44, 96,109, 30, 77,236, 64, 49, 98, 96,183,129, 28,207,243,100,197,143, 43,219, 31,248,245,191,203,234, 54,108,151,
+ 11,160,120,207,158, 61,250,246,237,219, 27, 62,249,228, 19,227,205,155, 55,185,133, 11, 23,214,255,227,143, 63,222,241,244,244,
+ 60,158,148,148,244,220,187,124,175,156,160,185, 41,152, 74, 60, 39,124,162, 42,205,150, 15, 92, 50,112,224,224, 2,119,119,119,
+115,153,179,180,125,251,246,134, 65,131, 6, 25, 30,115,190,235,233,233,121,236, 69,206,201,147, 64,100, 57,234,125,145,245,137,
+204,213,183,219,169,254, 3,191, 40,112,119,119, 55,115, 28, 87, 84,217,114,254,147,176,182,182,158,163,209,104, 58, 6, 5, 5,
+197,126,249,229,151, 71,223,121,231,157, 76, 0, 88,187,118,173,231,236,217,179, 47, 3, 56,245,203, 47,191, 56, 47, 92,184,176,
+219,249,243,231,167, 90, 91, 91,255, 90, 88, 88,248, 31, 11, 43, 70,206,213,213,117, 76,155, 54,109, 70,245,232,209, 3,214,214,
+214,232,211,167, 15,244,122,253, 73,119,119,247,169,169,169,169,243, 45,105,205, 81, 40, 20, 99, 63,251,236, 51,133, 40,177,198,
+184,117,113,200, 41,122,144, 27,212,114, 14,159,183, 82,160, 75,151,174,234,153, 51,103,124, 83,145,128,165, 86,171, 39, 12, 31,
+ 62, 92,225,226,226, 2, 0, 40, 42, 42, 66, 81, 81, 17, 10, 11, 11, 81, 90, 90,138,119,222,121, 71,253,253,247,223, 79,168, 72,
+192,122,220,121,243,230, 77, 24, 12, 6,232,116, 58,232,245,122, 88, 91, 91,163,115,231,206,234,101,203,150, 89,236,116, 75,131,
+244,158, 81, 92, 56,242,179, 15,157, 0, 96,254,119,219, 22, 2,186,230,212,130,113,110,105,136, 0,192, 2,214,139,247, 79, 30,
+192, 59, 82,169,244, 29, 31, 31,159,160,184,184,184, 75, 38,147,233, 23, 0,187, 40,165,166,151,116, 71,186,185,185, 77, 74, 77,
+ 77,253,158, 82,186,229,223,178, 78,189,189,189,183,108,218,180,201, 97,207,158, 61, 29,166, 77,155,246, 62,128, 77, 47,177, 14,
+165, 0,194,202,254,189, 89, 22,172, 80, 22,180,124, 9, 33, 94, 0,206, 84,228,160,207,217, 63, 82, 35, 66,181, 46, 60,178, 77,
+120,215, 46,157,173,156, 29,108, 81, 92, 42,224, 86, 66, 90,213,253,123,126,142,112, 13,236,112, 70, 16, 74, 62,206,188,118,164,
+184,162,206,150,109,223, 9,111,249, 86, 43, 43, 91, 91, 59,100, 23,154,112, 39, 33,169,218,209, 3,187,154, 84, 9,236,112, 2,
+ 48,245, 79,191,188,191,132,125,235, 24, 21,193,162, 78,238, 4,160, 14,118,234,108, 0,105, 0,138,108,108,108,140, 0, 74, 0,
+228,250,250,250,230, 47, 95,190, 60,121,215,174, 93,127, 80, 74,223,122,124,190,167,175, 48, 16,133, 82,215, 79,123, 12,133, 66,
+ 38,202,198,124, 51, 34,199,221,221, 61,163, 28,231,161,242,156, 0, 96,163,210,133,119,142,180, 11,172,202, 45,255,236,242,193,
+254,161, 57,169, 49, 37,128, 80,108, 99,101,101,170, 76, 57, 95, 5,127,149,211, 96, 48,188,107,103,103,151,159,147,147,163, 49,
+153, 76,164, 64,103,146,222, 72,210,219,220,215,185,185,222, 72,210,219, 20,232, 76, 82,147,201, 68, 50, 50, 50, 52, 74,165, 50,
+191,180,180,244, 93, 75,203,233,230,230, 54, 97,230,204,153,163, 87,175, 94,205,133,132,132,192,218,218, 26,141, 27, 55,198,134,
+ 13, 27, 36, 19, 39, 78,156,236,230,230,246,181, 37,229,164,148,134,104,181, 90, 34, 2,200, 45, 50,227,240, 76, 45, 78,206, 13,
+ 65,137, 65, 68,126, 65, 17, 56,142,131, 68, 34, 33, 65, 65, 65,222,150, 46,187,217,108,110,208,176, 97, 67, 2, 0,133,133,133,
+101,225,234,193, 80, 84, 84, 12,153, 76, 14, 81, 20,101, 13, 27, 54,116,171,140,211, 96, 48,160, 70,141, 26,168, 94,189, 58, 10,
+ 11, 11, 81, 80, 80, 0,153, 76, 86, 33,167, 65, 45, 37, 20,212, 69,165, 84, 56,170,148, 10, 71, 10,234, 2, 0,150,140, 51,168,
+165,228,239,220, 63, 9, 33, 78, 60,207,127,239,227,227,115,158,231,249,255, 18, 66,170,188,140,147, 16,162, 37,132, 76, 86,171,
+213,191,213,173, 91,247,150, 70,163,217, 75, 8,153, 74, 8, 9,171,140,147, 16, 34, 87,171,213,123,102,204,152,177,225,194,133,
+ 11, 31, 28, 58,116,168,198,165, 75,151,222,155, 51,103,206, 90, 43, 43,171,253,132, 16,213,203,124, 55,189,188,188,190,139,138,
+138,210, 54,105,210,100, 57, 33, 68,241, 42,190,239,132, 16,158, 16, 82,159, 60,124,216,225,107, 82,135, 60,196,211,211,211,187,
+ 97,195,134,142, 60,207, 35, 34, 34, 2,130, 32, 52,121, 73,103, 24,128,116, 74,233, 9, 74,105, 22,165, 84, 40, 27,178, 41,165,
+ 39, 1, 36, 1, 8,175,136, 83,132,106,221,240, 47,255,211,250,171, 47, 6, 88,157,191, 39,224,191,251, 83,177,245, 68, 38,146,
+ 11, 21,104,253,238, 39, 54,145,237,122,180,226,121,245,186,138, 58,199,140, 30,221,186,127,159,158, 86, 87, 82, 56,108, 59,153,
+133, 19,177, 5, 40, 33,246,136,124,119,160, 93,221,144,118,109, 65,100, 43, 94,135,109,244,166, 59,255, 21, 45, 88,221,103,210,
+188,229,163,201,130,239,183,172, 28,197, 17, 66, 53, 14, 1,135,117,212,243,122,217,244,182,206,206,206,166,178, 31,161,252,223,
+126,251,205,124,254,252,121,135,154, 53,107, 58, 90,190,101, 64, 46, 93,186,168,115,114,241, 74,247,242,242,122, 37,206, 86,225,
+ 45,228,250, 82, 29, 46,221,184,210,100,247,202,102,225,246, 46,126,151, 92,234, 12,248, 3, 66,120,177,193,108,206,171, 84, 57,
+255, 1,240, 60,175,219,190,125,251,127, 15, 28, 56,224, 54,110,194,148,214, 83,254,123,212,197,166, 94, 55,123,147,104, 99,117,
+104,209,133,162,188, 43, 27,115,115,110,236,203,208, 54,168,247, 71,231,206,157, 83,231,205,155,247, 69,121, 78, 79, 79, 79,165,
+ 68, 34,169,221,161, 67,135,145, 31,127,252, 49, 18, 18, 18,240,213, 87, 95,233, 46, 94,188,152, 19, 28, 28,236, 48,119,238, 92,
+213,192,129, 3,113,250,244,233,177, 94, 94, 94,191,152, 76,166,196,164,164,164,231, 62,159, 79, 16, 4,133, 82,169,132,174,172,
+ 77,193,104,166, 0,196, 71, 45, 79, 28,205,131, 68, 34,129, 40,138,181, 8, 33,119, 45,105, 21, 51,155,205, 10,165, 82,137,226,
+226, 98, 20, 21, 21, 33, 57,179, 8,247,210,139, 81, 88, 92, 10,157,206,132,146, 98, 19,164,106, 71,152,205,233,126,132,144,180,
+138, 56, 5, 65,128, 78,167, 67,113,113, 49,116, 58, 29,116, 58, 29, 68, 81, 68, 65, 65, 1,164, 82, 41, 53, 24, 12,190, 0, 82,
+203,221, 54,114,149, 25,224,230,126,191,118,215,216,178,227,153,185, 86,208,139,217, 22,140,123, 48,239,223,214, 50,164,112,114,
+114,218,183,125,251,246, 58,181,106,213, 66,124,124,188,111,215,174, 93,131, 9, 33,225,148,210,146, 10,186,212, 28,199, 77,237,
+219,183,239,192,238,221,187,147,218,181,107, 67, 34,145,192,108, 54,123,196,197,197, 53,219,186,117,235, 8,137, 68,178, 70, 16,
+132,111, 44,189,115, 60, 33,132, 83, 40, 20,235, 86,172, 88,209, 52, 44, 44, 12,235,214,173,195,217,179,103,197,208,208, 80,174,
+119,239,222,168, 94,189,122,232,199, 31,127,188,137, 16,242, 65,217,131,150, 43,186,252,213,122,246,236,233,201,243, 60, 26, 55,
+110, 44, 59,121,242,100, 3, 0,103, 94,114,157,106, 60, 60, 60,246,183,104,209,162,254,193,131, 7, 47, 18, 66,218, 84,228, 78,
+249,238,238,238, 29,171, 84,169, 50,205,218,218,218,222,210,121,138,138,138, 74, 50, 50, 50,198, 36, 37, 37,237,176,112,150,176,
+192,192, 64,152,205,102,216,218,218,194,205,205,173,177,167,167,231, 23, 54, 54, 54,239, 20, 22, 22,126,147,152,152,120,174, 2,
+203,235, 14,128,163,148,198,149,253, 95, 29, 64,237,178,183,111, 83, 74, 19, 40,165,241,132, 16, 55, 66,136,167, 37,167, 11,157,
+106,181,104,223,164,101,251,240,136,176, 0,110,230,246, 4, 8,162, 8, 9, 4, 72,120, 17, 89,130, 20,132, 16, 84,243, 13,225,
+171, 92, 57, 23,234,228,215,170,125, 86,236,193, 61,150, 56,219,117,234,220,196,183,182, 47, 55,127,231,125,228, 37, 95, 17,210,
+ 99,255,200, 38, 28, 7,175, 6,173, 29,107,248, 54,228,125, 26,182,148,166, 37, 92,105,238,232,219,172, 69,246,205, 99,135, 89,
+108, 96, 84, 56, 96, 17, 66, 40,165,244,209,145,213,224,153,116,106,160, 95, 21,191, 45,155,214,164, 20,155, 28,174,100,103,103,
+ 59,102,103,103,195,198,198, 38, 95, 16, 4,211,156, 57,115,164,113,113,113,182, 74,165, 18, 10,133, 2, 38,147,169, 66,157,137,
+ 69, 81, 36,175,218,169, 81, 91,161,137, 54, 92, 22, 28,160,197,181,184,235,218,243,135,135, 5,156,190, 80,240,201,173, 91,119,
+ 42,237,252,167,208,186,117,235,212,218,218, 54,191, 45,253,195,244,159, 69, 67, 66,212, 84, 20, 40,225,120,205,208,197, 34, 9,
+173,235,185,202, 65,150,159,199,243,124,185,158,106,213,170, 77,106,209,162,197,112,137, 68, 34, 29, 48, 96, 0, 0, 96,216,176,
+ 97,133,209,209,209,129,233,233,233,153, 85,171, 86,117, 27, 57,114,228,165,237,219,183,171, 63,249,228, 19,137, 78,167,187, 32,
+149, 74,169,155,155,219,204,212,212,212,233,207,114,202,100,178,203,215,175, 95,111,106,227, 17, 0, 39,107, 14,109,198,158, 7,
+ 0, 88, 41, 41,114,179,210,112,231,254,101, 84,175, 94, 93, 85,173, 90,181, 31,221,220,220,196, 70,141, 26,205,243,244,244,156,
+185,109,219,182,231,254, 56,170, 84,170,107, 23, 47, 94, 12,174, 91,183, 46,138,138,138,144,152, 81,140,213,167, 9, 74,244, 42,
+ 0, 42,112,176,130,149,189,135, 66, 74,117, 91,194,194,194,184,198,141, 27,207,242,240,240, 88, 80,158,243,250,245,235,193,245,
+234,213,131,201,100, 66, 76, 76, 12,138,139,139, 97, 48, 24,144,155,155,139,248,248,120,120,123,123, 43, 69, 81,220,213,161, 67,
+ 7, 33, 59, 59,123, 82, 84, 84,212,146,231,133,183,125, 95,248, 24,155, 79, 58,178,210,160, 43,252, 9, 0, 28, 29, 61,115,127,
+157, 20,100,104, 62,169,168,220,113,251,190,240, 49, 98,232,223,182,171,246, 26, 59,118,108, 29, 7, 7, 7,124,250,233,167,152,
+ 60,121, 50, 38, 76,152,224,243,233,167,159,246, 3,176,180, 2, 63,178, 42, 87, 87,215,227,139, 23, 47,246,109,210,164, 9,246,
+236,217,131,205,155, 55,227,238,221,187,102, 47, 47, 47, 73, 88, 88, 24, 38, 78,156,136, 54,109,218,244, 29, 58,116,104,211,178,
+ 0,103, 73,232,232, 61, 97,194,132,142, 77,155, 54, 69,223,190,125, 75, 15, 31, 62,220, 27,192,161,131, 7, 15, 54, 63,118,236,
+216,198, 13, 27, 54,168,166, 79,159,222,122,196,136, 17, 3, 0,124, 95,137,229,239,212,172, 89, 51, 0, 64,211,166, 77, 49,103,
+206,156, 86, 47, 19,176, 8, 33,114, 7, 7,135,159,215,175, 95, 95,223,215,215, 23,189,122,245,106,240,225,135, 31,254, 76, 8,
+233, 68, 41, 53, 88,226,112,117,117,157,186,114,229, 74,111,149, 74,101,241,231, 26, 12, 6,251, 65,131, 6, 77, 1,176,195,194,
+ 58,185, 81, 64, 64, 0,142, 28, 57,130, 86,173, 90,161, 94,189,122,222,131, 6, 13,154,217,166, 77, 27,124,249,229,151, 7,221,
+221,221,189, 83, 82, 82,178, 45,252,248,106, 0,110,149, 45,127, 85, 0,222, 0, 78,151,189, 23, 66, 8, 1,165, 52,161,108, 26,
+223,178,214,172, 23,163,212,244,122,167, 83, 7,171,159, 79,101, 64, 16, 69,248,121, 40, 81,183,154, 13, 18, 50,244,184,151,156,
+ 13, 41, 49,194, 90,165, 64, 96,120, 7,187,156,244,132, 94, 0,202,239,143, 37, 87,247,122,239,157, 14,154, 29,167, 51,144,151,
+124,149, 38, 68,111, 61, 42,148,234, 62, 7,128,235,199, 55, 44,113,179, 87,182,172,221, 64,203,151, 68,188,107,119,100,103,122,
+ 47, 0, 44, 96,253,121, 7,118, 79,100,144, 55,182, 5,235, 33, 57,133,146, 82, 91,151,192,194,226,228,228, 71,227, 10, 10, 10,
+108,111,221,186,149, 17, 27, 27,107, 43,149, 74, 33, 8,194,195, 47,167, 88,217, 66,188,106,167, 92, 38, 71,125,223, 64, 62,230,
+242, 57, 89,108,108,172, 45,207,203,232,171, 40,231,235,206,149, 20,161,170, 73,228, 53, 74,153,228,209,166, 21,137, 76, 83, 64,
+ 92,171, 58, 32, 63,175,188,249,181, 90,173,180,101,203,150,195, 87,173, 90, 37, 77, 77, 77,133,157,157, 29, 76, 38, 19,206,159,
+ 63,159,156,158,158,158, 9, 0,137,137,137,169,158,158,158,169,130, 32,248,248,249,249, 97,208,160, 65,168, 83,167, 14, 25, 57,
+114,228, 8, 66,200,204,103, 93, 9, 88, 80, 80,240,237,252,249,243, 27, 78,158,177, 64,221, 51,140,160,184,196,128,162,162, 34,
+164, 36,220,130,194, 76, 49,125,250,116, 40,149, 74, 0,224,179,179,179,249,217,179,103,141,186,120,241,226, 91, 0,154, 63,175,
+172,121,121,121,203, 22, 45, 90,180,124,206,156, 57,106,157, 78, 7,157, 94,143, 66,157, 28,103, 23,132, 62, 56, 20, 31, 17,133,
+ 89,179,231, 32,160,186, 70,149,156,156,140,137, 19, 39,126,117,247,238,221,198, 0,222,123,145,115,238,220,185,203,231,207,159,
+175,182,178,178, 2,165, 20,162, 40, 34, 49, 49, 17, 0, 48,117,234, 52,148,253,192,241,169,169,169,252,140, 25,211,167, 41, 20,
+138,150, 0, 58, 61,167, 9,157, 2, 40, 37, 4,105, 30, 30, 53,189, 21, 10,110,172,135, 71,233,169, 35, 19,147, 54, 19,130,180,
+ 7,211,128,186,175,116,255,232,254, 58,121,184,193,128,101,169,169,241,183, 41, 5,197,196,191,239, 56,192,201,201,233,179,119,
+223,125, 23,179,102,205,194,238,221,187,191,113,112,112,152, 53,121,242,100,184,185,185, 13, 34,132, 44,171,192, 85,148,211, 23,
+ 46, 92,232,235,231,231,135,143, 63,254,216,112,240,224,193, 73, 0,118, 3,184,127,252,248,241,170,107,215,174,109,191,117,235,
+214, 41,139, 22, 45, 82, 46, 93,186,212,251,131, 15, 62,152, 11,224,179,242,164, 85,170, 84, 25,218,189,123,119,204,155, 55, 15,
+135, 15, 31,238, 65, 41,253,189,236,173,253,132,144, 46, 51,102,204,216, 51,110,220, 56, 44, 92,184,240,243,138, 6, 44, 66,136,
+198,207,207,239,155,182,109,219,226,248,241,227,136,136,136, 64,120,120,248, 80, 66,200,114, 74,105,118, 37,126, 52, 56,107,107,
+235,117,107,215,174,109, 82,163, 70, 13, 76,155, 54, 13, 95,127,253, 53, 86,173, 90,213,164, 87,175, 94,235, 8, 33,221, 45,185,
+122,214,198,198,198, 74,165, 82, 97,214,172, 89,244,254,253,251,229,126,151,221,220,220,236,198,143, 31, 79,108,108,108,108, 45,
+ 40, 35,239,225,225, 97,227,234,234,218,196,213,213, 21,139, 23, 47,134,139,139, 11, 70,140, 24, 1, 71, 71, 71, 20, 23, 23,163,
+115,231,206,210, 51,103,206,116, 5,176,220,194, 69,119, 0,240,176,197,171, 14,128,211,148,210,162,178,207,139,194,131, 83,131,
+ 9,120,208, 47,203,162, 86, 57,142, 82,127,123, 59, 91,164, 92, 78,135, 4,102,248, 85,179,198,185,184, 98, 24, 5, 10,149,198,
+ 10,197,133,121,104,224,227,140,130, 18, 79,128,138,254,150, 56,101, 60,105, 40, 87,168,144, 81,144,143,180,235,135,114, 76,162,
+113,104,222,157, 99, 73, 0,224,224, 19, 57,244, 74,212,222, 19,157,219, 69, 56,103,228, 86, 3,165, 66, 48,139, 65,140,138, 48,
+126,107,157, 0, 0, 32, 0, 73, 68, 65, 84, 80,161, 27,141,138,162, 72,114,114,114, 36, 58,157,142, 55,153, 76,220,227,105,211,
+100, 50, 85, 42,184,252, 25,206,199,249, 51,156,175, 43,181, 92,184, 84,158,199, 19,167,234, 8,168,222,138,100,165, 90, 50,127,
+ 76, 76,140,233,216,177, 99,155, 70,143, 30,141, 5, 11, 22,224,206,157, 59,144, 74,165,240,243,243,115,117,118,118,214, 0, 64,
+205,154, 53,109, 2, 2, 2, 92,120,158, 71, 92, 92, 28, 54,111,222,140, 73,147, 38,209,152,152,152,117,207,251,161, 56,127,254,
+252,175,165,165,165,123,230, 76, 31, 95, 82,154,117, 19,106, 33, 19,180, 32, 30,106, 94,135,190, 3,135,226,110,166,128, 11,241,
+133,184, 16, 95,136,148, 98, 5, 62, 31, 49,150,243,242,242, 10, 10, 13, 13,253,228,121,101,189,112,225,194, 79, 37, 37, 37,135,
+166, 76,153, 82,114,247,238, 93,232,116, 58, 0,128,209, 44,194,104,126,178, 24, 30, 30, 30,152, 53,107,150, 70,163,209,132,107,
+181,218,238, 47,114, 22, 23, 23, 31,154, 48, 97, 66, 73, 92, 92, 28,242,243,243,145,150,150, 6, 66, 8,250, 15, 30,137,187,153,
+226,163,114,102, 27,173, 49,252, 63, 19,185,170, 85,171, 54,111,216,176,225,251, 47, 90,175, 30, 30,158,222,126,126,222, 27,206,
+156, 57,211,211,219,219,123,224,195, 96, 69, 41, 40, 0, 84,175, 94,189,127, 76, 76, 76,239, 6, 13,252, 54,186,185,185,215,254,
+155,143, 34,155,125,244,209, 71,181, 69, 81,196,182,109,219,174, 82, 74,151,238,220,185, 51,166,180,180, 20,221,187,119,175, 1,
+160,181,133, 30,109,143, 30, 61, 6, 70, 68, 68, 96,216,176, 97,198,131, 7, 15, 54,161,148, 46,161,148,222,163, 15,184, 79, 41,
+ 93,126,228,200,145, 70, 67,135, 14, 45, 13, 13, 13, 69,159, 62,125,122, 19, 66,154,148,227,109,212,189,123,119, 95, 81, 20,177,
+121,243,230, 43,143,133,171,135,161,246,232,182,109,219,162, 12, 6, 3,122,246,236,233, 69, 8,105, 94,129,101,151, 41,149,202,
+141,211,166, 77,179, 77, 78, 78, 70,239,222,189, 75,111,220,184,129,137, 19, 39,170,108,109,109,119, 16, 66, 52, 21, 93,159, 74,
+165,114,217,242,229,203, 59, 6, 6, 6,226,179,207, 62, 51, 44, 95,190,252,171,193,131, 7, 27,180, 90, 45,190,253,246,219,142,
+114,185,124, 89, 69,124,105,105,105,249, 71,142, 28,241, 44,111, 72, 79, 79,183,232,214, 44, 53,106,212,176,173, 87,175, 94, 84,
+ 72, 72, 72, 98,253,250,245,107, 2,192,213,171, 87,179,182,109,219, 70, 29, 29, 29,177,111,223, 62,172, 92,185, 18, 77,155, 54,
+133,181,181,117,151, 10, 20,149,150, 13,120,236,245,233,247,159,158,174, 92,103,126,137, 25, 18,142,131,148,167,184,151,174,131,
+ 81,160,144, 73, 57, 72,121, 64,194, 81, 56, 90, 75, 33,149,242, 0, 33, 22, 57, 57, 66,144, 91,108,130,132, 39,144,202,165,132,
+ 23, 68,229,195,247,120,169,168,148,203,149,196,197, 86, 6,185,132,128, 35, 96, 48, 94, 93, 11, 86, 89,165, 35,100,101,101, 73,
+227,227,227,149, 6,131,129,171, 81,163,134, 30, 0,204,102, 51,151,155,155, 43,147,203,229, 32,132, 24,205,102,115,133, 14,185,
+115,114,114,165, 9,247,111,189, 82,231,179, 48,155,205, 92, 73, 73,174,252, 85, 58, 95, 71,110,220,184, 97,117, 59, 62, 69, 83,
+133,175, 27, 51,116,105, 76, 24, 5,164,132, 82,147, 66,119,227, 76, 86,198, 69, 25,108, 21,106, 79, 79,207,114,251,207,220,189,
+123,247,115,119,119,247,217,148, 82, 63, 74,233, 79, 11, 22, 44, 32, 75,150, 44,177, 27, 60,120,240, 85,119,119,247, 20, 95, 95,
+223,106, 11, 22, 44,176, 6,128, 13, 27, 54,136,123,247,238,237,164, 80, 40,110, 36, 36, 36,164,191,200,123,244,232,209,190,161,
+161,161,159,124,247,221,119, 83,204,102,179,194,217,217, 89,177,126,253,122, 36,231, 25, 48,110,253,255, 95, 89,168, 81,240, 24,
+214, 70,131,200,200,150,220,253,251,247,191, 2,176,234,121,206, 99,199,142,245, 8, 11, 11,251,244,219,111,191,157, 0,171,234,
+ 10, 69,157,126,178,150,163, 31,156,126,116,115, 80, 60,170, 16,243,243,243,145,155,155,139,206,157, 59,171, 55,110,220,248, 25,
+128,205,229, 57,151, 46, 93, 58, 65, 16, 4,153,179,179,179, 98,211,166, 77,136,207, 50,224,155,181,113, 40,212, 63, 40,167,149,
+ 66,130,161,173, 20,104,217,178, 37,159,146,146, 50, 10,192,207,207,242,121,122,122,250,248,249,249,109,216,180,105, 83,157, 69,
+139, 22,229,222,186,117,171,196,205,205,109,220, 83,147, 25,102,206,156,153,179,126,253,250, 90,189,123,247,222,232,230,230,214,
+ 43, 53, 53,245,198,223,177, 31,217,218,218, 78, 29, 52,104, 16,126,252,241, 71,228,230,230, 46, 43, 91,127,203, 54,109,218,180,
+182,127,255,254, 88,183,110,221, 84, 66,200, 1, 11, 90,177,222,238,214,173, 27,246,238,221,139, 63,254,248, 99, 10,165, 52,246,
+ 57,173,124,113,132,144,241,187,118,237,154,219,189,123,119,172, 94,189,186, 53,128,147, 47,240,182,108,211,166, 13,246,236,217,
+131,156,156,156,103,118, 60,206,207,207, 95,185,123,247,238,208, 54,109,218, 96,230,204,153,111, 1, 56,106, 65, 61,231,107,107,
+107,187, 98,241,226,197,218,192,192, 64,244,232,209, 67,111, 52, 26,223,251,234,171,175,182,111,217,178,197,106,221,186,117, 65,
+ 3, 6, 12, 56, 70, 8, 25, 76, 41,141,178,100, 93,242, 60, 63,121,233,210,165, 31, 71, 70, 70, 98,228,200,145,230,223,127,255,
+189, 43,165,244, 16, 33,228,206,168, 81,163,126,158, 55,111, 30, 63,111,222,188,143,121,158,207, 18, 4, 97,226,223,177,189, 69,
+ 81,156, 57,127,254,252, 58,254,254,254,208,235,245,184,115,231, 14,210,210,210,126,204,200,200, 56,116,229,202,149,233,169,169,
+169, 59, 93, 93, 93,251,142, 24, 49,194, 35, 56, 56, 88, 91,173, 90, 53, 59, 75, 90,208, 30,107,153,202, 4,112, 3, 64,104, 89,
+203, 21, 0,132, 0,184, 93,246,183, 29,128, 60,139, 10, 75,184,171,183,226,147,189,236,173,108,144, 43,202, 17,159,156, 13,149,
+ 70, 3,142,114, 48,235,114, 81,171,186, 11, 68, 10, 20,100, 37,131,227,136, 69,183,145, 49,137,244, 66, 66, 98,186,187,157, 70,
+137, 90,218, 14, 14, 23, 15,175, 94,101,231,211,108,136,132, 23,120,137,220,102,105,143,238, 31, 59,154, 5,138,162,220, 84, 16,
+158, 63, 7, 6,227, 85, 5, 44, 65, 16,200,186,117,235,108, 50, 50, 50, 56, 95, 95,223,156,250,245,235, 23,203,229,114, 81,167,
+211, 9, 74,165,210,172,209,104, 68,189, 94, 47,191,119,239,158,125,114,114, 50,255,240, 52,156, 37, 28, 61,122,220,213,167,118,
+ 96,198,171,116, 62,231, 8,210,172, 82, 73,132, 87,233,124,157, 16, 69, 81, 62,125,250,244, 70, 14, 14, 14,197,161,161,161,201,
+225, 62,206,187, 83,138,113, 98,193,194,255,246,246,175, 91,109,189, 45,159,155, 87, 44,167,210,164,164, 36,215,219,183,111,171,
+ 41,165,178,242,156, 41, 41, 41,137, 0, 18,221,220,220, 86, 70, 70, 70, 14,234,216,177, 35,142, 28, 57,226, 92, 92, 92,236,172,
+209, 60, 56,136,255,233,167,159,176,115,231,206, 37,105,105,105, 71, 44, 45,107, 84, 84,212, 42, 0,171, 26, 54,108,168,181,181,
+181, 61, 98, 99, 99,195, 37,230, 23, 63,186,178, 80, 38,225,208,228,235,104,100,231,230, 65,202, 17, 40,149, 74, 15, 66, 8,247,
+188,150,177,178, 31,249,239, 0,124, 23,218,174,255,187, 54,247,182,172,154,191, 96,129,226,225,145,105, 21,123, 25,242,242,242,
+144,153,153,137,172,172, 44, 72, 36, 18,232,245,122,191, 23, 30, 34, 63,230, 12, 12, 12,108,225,232,232,184, 75,173, 86,243, 52,
+171, 24,185, 69,198, 39, 78, 65,230,230,149, 66, 42,149, 66,163,209,248, 60,203,229,228,228,100, 37,147,201, 86,252,240,195, 15,
+190,214,214,214,252,128, 1, 3,108, 7, 12, 24,208, 24, 64,227,103, 77,175, 86,171,249,213,171, 87,251, 52,104,208, 96, 69,205,
+154, 53, 59,222,189,123,183,224, 47,108,185,226, 1,244,255,234,171,175,130,148, 74, 37,150, 46, 93, 26, 15,224,199,178,183,127,
+ 94,190,124,249,232,110,221,186,213, 30, 54,108, 88,221,113,227,198, 13, 37,132,124,251,162, 14,228, 50,153,172, 97,221,186,117,
+177, 99,199, 14,224,193,105,193, 23,177,227,212,169, 83,115, 59,118,236, 8,149, 74,165, 45,175,209,165,106,213,170,216,181,107,
+ 23, 0, 92,122,206, 52,151, 98, 99, 99,209,185,115,103,112, 28, 87,221,130,101,239,248,246,219,111,111,156, 57,115,166,196,218,
+218, 26,159,124,242,137,225,236,217,179,157, 41,165, 39, 8, 33,109,123,245,234,245,251,134, 13, 27, 52,199,142, 29,243,157, 62,
+125,250, 31, 60,207,207, 21, 4, 97,114, 57,206,222,211,166, 77,251,234,189,247,222,195,228,201,147,233,143, 63,254,216,143, 82,
+122,168,108, 31, 59, 72, 8,233,111,111,111,191,122,204,152, 49, 36, 63, 63,255, 43, 66, 72, 50,165,244,191,207,243, 21, 21, 21,
+ 21, 8,130, 80, 69,167,211, 89,212,103,203,210,233,125,124,124,222,246,247,247,199,174, 93,187,208,169, 83, 39, 28, 56,112, 0,
+ 18,137,100, 95, 82, 82,210, 49, 0,135, 0,192,205,205,205, 38, 46, 46,238,139,102,205,154,113,127,252,241,199,187, 0,214, 88,
+ 80,132, 4, 0,245, 0,252, 65, 41, 77, 42,187,112,178, 17, 30,220, 7,235, 6,165, 52,177,108, 58,127, 0,119, 45,170,235, 76,
+ 69,155, 14,237,217,222,188,245, 7,131,109,120,158, 64, 2, 25, 74, 10, 11, 0, 65,128, 79,245, 42, 8,173, 91, 5,151, 18,116,
+ 56,117, 96, 91,126, 73, 73,177, 69,183,151, 16, 76,197, 27, 14,253,190, 51, 34,164,117, 31, 27,133, 79, 93, 84,173, 50,188,254,
+213,168,253,191, 42,229, 50,242,254, 7, 93,109, 91,132,214,194,161,203, 5, 56,125,104, 71,158,174, 56,111, 3,139, 12,140, 74,
+ 5,172,103,117, 46, 19, 69, 49,235,192,129, 3,234,241,227,199, 23,185,185,185, 73,138,138,138,184,199,251, 48,201,100, 50,184,
+185,185,153,243,242,242,140, 7, 14, 28,240, 18, 69, 49,231,133,205,177,188, 34,237,251, 77, 75, 61, 5,162, 54,180,105,215, 73,
+244,244,172,241,210, 78, 0,208, 27, 20, 89,219,247,237,176,107, 30,218, 84, 90,197,169,202,179, 42,251, 10, 59,255, 65,164,222,
+190,125,219,105,250,244,233,151, 60, 60, 60,244, 0,224,168, 17,210,178,175,253,156,107, 85,163, 99,154, 84,161,128,179,179,115,
+169,149,149,149,121,207,158, 61,111, 81, 74,211, 44, 21,219,219,219,127, 51,104,208, 32,238,248,241,227,253,123,245,234, 69,188,
+188,188,112,225,194, 5,108,216,176,129,110,219,182,237,219,180,180,180, 74, 29,117, 43, 20,138,120,163,241,201, 91,223, 60,126,
+101, 97,110,110, 46,184,194, 44, 8,130, 96,182,244,238,238, 66,230,165,168, 82,149, 10,245,170,253,255, 89,156,220,220, 92,100,
+102,101, 61, 10, 88, 25, 25, 25,224,121, 94,111,105, 57,229,114,249, 61,131,193,240, 84, 57,197,199, 91, 74, 32,228,101,193,248,
+244,194,148,145,149,149, 85,228,225,225,241,253,210,165, 75,103, 78,153, 50,197,121,225,194,133,185,177,177,177,133, 28,199,233,
+159,250,158, 41,189,189,189,173,230,207,159,239,178,100,201,146, 92, 0,223,253,197,225,170, 83, 64, 64,192,202,246,237,219, 91,
+ 13, 30, 60, 24, 75,150, 44, 65, 90, 90,218, 4, 74,169,185,172,110, 16, 9, 33, 99,151, 47, 95,254,211,168, 81,163, 96, 52, 26,
+103,238,217,179,103, 28, 33,228, 11, 74,233,143,207,114, 58, 59, 59,123, 72, 36, 18,196,196,196, 20, 82, 74,239,150, 19,106,211,
+125,125,125, 51, 8, 33, 46,174,174,174, 94, 47,154,214,193,193,161,166,181,181, 53,146, 31,244, 11, 77,120,206,100,247, 83, 82,
+ 82,168, 92, 46, 39,110,110,110, 62,229, 45,191,157,157,221,151, 63,252,240,131,228,240,225,195,152, 56,113, 98,242,189,123,247,
+ 62, 41,187,141, 0, 40,165, 23, 9, 33,173, 91,180,104,177,118,212,168, 81,181,102,207,158, 77, 98, 99, 99, 7, 0,120, 97,192,
+170, 94,189,122,255,126,253,250, 97,233,210,165, 88,177, 98,197, 48, 74,233,207, 79, 45,243, 54, 66,136,189,131,131,195,252, 65,
+131, 6, 97,205,154, 53, 31, 1,120,110,192, 74, 75, 75, 27,247,209, 71, 31,141,206,205,205,157,107,201, 54,181,100,122, 15, 15,
+143, 14, 61,123,246,116,161,148, 98,201,146, 37,233, 75,151, 46, 45,201,207,207,255, 49, 53, 53,245,216, 83, 45,113,187,246,237,
+219,247,197,224,193,131,113,228,200,145, 5, 30, 30, 30, 52, 57, 57,121,109, 57,219, 52,141, 16, 82,147, 16, 82,135, 82,122,163,
+236, 42,193,164,167,246,187, 90,101,211, 38, 91,178, 76, 89,177,135,247,184,212,107,127,250, 98,212,145,183,188,234, 69, 72, 93,
+236,173,225, 81,219, 9, 14, 26, 25, 40,128, 43,247,116, 56,115,108,191, 41, 35,253,254, 25, 75,174, 32,124,232,116, 13,236,112,
+ 70,237,120,252,173,154,254,225, 18,175, 90,181,209,186, 73,125, 59, 71, 27, 41, 12, 38,138, 3, 23,243,113,250,216, 94, 83,102,
+ 70,210, 81,118, 5,225,159,203,155,214,193,189,220, 22,172,204,204,204,255,200,100,178,102,253,250,245,235, 22, 17, 17, 97, 61,
+112,224,192, 12, 27, 27,155, 98,185, 92,206, 59, 56, 56,200, 41,165,242,253,251,247,187,167,165,165,217, 3,216,146,153,153,121,
+236,169, 47,208, 19, 79,219, 30, 56,165,216,151, 16, 66, 60, 60,236,154, 73,182,124,214, 45, 34, 34, 66,243,178,206, 73,147, 64,
+ 39, 53,215,251,156,118, 37,227,179,243,246, 12,241,116,117,229,155,133,132, 75,173,212,154,178,144,224, 32, 23, 69,200, 42,226,
+124, 69, 63, 90,127,137,211, 96, 48,188,117,231,206,157, 15,123,245,234, 53, 82,171,213, 94, 27, 51,102,204, 89, 59, 59, 59, 83,
+217,145, 34, 12, 6,131,244,192,129, 3, 97, 73, 73, 73,254, 38,147,105, 62,128,173,150,150,243,218,181,107, 70, 0,195,221,221,
+221,127,203,200,200,248,165, 91,183,110, 88,179,102, 13, 78,157, 58,213, 58, 37, 37,229,116,101,151,253,244,233,211,185,109,219,
+182,213,221,184,113, 67,195,107,170,194,213, 94,134,182,227, 47,128,138, 20, 86, 74,138,226,194,124,152,114,114, 80, 82, 82,114,
+221, 82,103, 76, 76, 76, 90,211,166, 77,245,119,239,222, 85,212,172, 89,243, 65,184, 42, 11, 86,153,153,153,200,201,201, 65, 65,
+ 65, 1,149, 74,165, 49,150, 58,163,163,163,227,219,180,105, 35, 36, 36, 36,240, 60,239,140, 42,118, 50,180, 28,253, 96,118,123,
+ 53, 80, 88,144, 15, 93, 86, 22,116, 58,221,115,157,201,201,201,219, 60, 60, 60, 0, 96,230,132, 9, 19, 28,219,182,109, 27, 23,
+ 21, 21,213,230,241,207, 9, 14, 14,254,113,202,148, 41,109,167, 79,159,158,189,110,221,186,113, 41, 41, 41, 91,254,202,125,201,
+193,193,225,139, 61,123,246, 88, 25,141, 70, 44, 89,178, 4, 11, 22, 44, 88, 71, 41,221,249, 84,229,183,143,231,249, 21, 28,199,
+ 13, 26, 50,100, 8, 6, 13, 26,164, 14, 14, 14,254,226,177, 86,174, 39,156,201,201,201,147,131,130,130, 70,103,102,102, 90, 20,
+ 8,110,221,186, 53, 36, 40, 40,104, 84,102,102,230,194, 23, 45,187, 70,163,209, 8,130,128,248,248,248, 60, 74,105,193,115, 42,
+106,189,175,175,111,138, 32, 8, 30, 26,141,198,190,188,253, 51, 47, 47,111,174, 86,171, 29,155,145,145,113, 8,192,108, 74,169,
+254, 41,223,101, 66, 72,240,176, 97,195, 62,155, 57,115,230, 59,233,233,233,219,203,115,222,187,119,111,110,139, 22, 45,190,185,
+121,243,230, 70, 74,233,170,231,148,243,123, 66,136,113,227,198,141, 3,226,227,227,231,189,200,153,148,148,180, 23,192, 94, 75,
+183,239,243,166,127,106,187,143, 24, 58,116, 40,246,238,221,139,162,162,162,111,147,147,147, 23, 60,199, 21,229,229,229,245, 91,
+227,198,141, 59,204,157, 59, 87,214,190,125,251, 1, 0,214, 90,176,127,158, 5,208,168,172, 31,220, 77, 0, 15, 15,108,237,241,
+224,150, 13, 4,207,185, 58,243,121, 78, 74,117,125, 46, 28,223,177, 54,241,246,165, 48,109,100,103,187,252, 18, 79,200, 36, 28,
+138,114, 83,113,250,224,207,121, 41,201,119,206, 26,141,197,125, 42,226, 20,132,146,143, 47,157,216,177, 46, 45,225, 90,104, 73,
+147,246,118,121,133,213, 33,147, 16,228,101, 37,225,236,145, 93,185,169,137,241, 39, 77, 66,233,160,191,179,158,255,183, 56,255,
+ 85, 1,171,236,116,201, 81,173, 86,123,234,200,145, 35,109, 79,158, 60,249, 78,203,150, 45, 51,194,195,195,139,206,159, 63, 95,
+ 61, 62, 62,222, 5,192,110, 23, 23,151,125, 49, 49, 49, 22,221, 57,249, 85, 59,203,124,102,128, 76,154,252,185,211,220,164,203,
+ 89, 11, 82, 51,182,119,245,169,238, 69, 0,144,152,152, 11,213,227,227,227,157, 43, 90,206,127, 80,234,167, 0,126, 36,132,236,
+ 56,123,246,236,128,247,223,127,127, 80,203,150, 45,207, 82, 74,201,169, 83,167,180,247,238,221, 11, 19, 4, 97,149, 40,138,131,
+ 42,243,152,156,135,167, 92,100, 50, 25,245,245,245, 37, 42,149, 10, 10,133,226,250,203,150, 59, 47, 47,111,228,252,249,243,151,
+ 79,159,179,132,255,252,109, 91,100,101,103, 35, 59, 59, 27,185, 57, 57,144, 65,135,139,215,174, 10, 69, 69, 69, 35, 43,226, 52,
+ 26,141, 99,198,143, 31, 63,119,222,188,121,154,194,194,194, 71, 1, 43, 39, 39, 7, 58,157, 14, 71,142, 28, 41, 53, 26,141,227,
+ 42,226, 44, 40, 40,152, 48,119,238,220, 25, 67, 71,142,229, 6, 68, 72,145, 87,160, 67, 94, 94, 30,138, 10, 11,161, 32, 58, 68,
+ 93,189, 42, 24, 12,134,175, 95,228, 40, 11, 89, 52, 49, 49,113, 92, 97, 97,225,237,103,124, 70,218,144, 33, 67, 82, 79,157, 58,
+ 53, 53, 41, 41,105,243, 95,189, 15,229,228,228,204,105,212,168,209,236,204,204,204,120,163,209,248, 51,165,244,153,101, 16, 4,
+ 97, 4, 33,228,236,178,101,203,186, 56, 57, 57,185,164,165,165,205,127,193,126, 89,161, 64, 96,233,244,247,239,223,159,160,213,
+106,191,206,200,200,152, 95, 78, 96,251,178,108,186,133, 22,124,246, 62, 0,251,202,153,198,140, 7,183,168, 88,106,225,242,252,
+ 10,224, 87, 11,166, 91, 13, 96,245,223, 81,119,228,230,230,206,235,216,177,227,248,244,244,244,163,105,105,105,139, 95, 52,173,
+201,100,234, 51,104,208,160,241,174,174,174, 97, 25, 25, 25, 75, 44, 92, 7,102, 0, 39,202, 30,149,227, 13,224,225, 85,120,121,
+ 0, 18, 42,243,168,156,178, 59,180,127,224,228,215,170,253,193,237,139,123, 65, 16, 2, 1, 2, 78,202, 95,214,151, 20,111,176,
+180,229,234, 25,206,247,157,252, 90,181,207, 73, 79,232, 45, 10, 66, 32, 71, 32, 18,158,191, 82,170, 47, 94,147,113,237, 32,123,
+ 84, 14,163,114, 33,180, 34,207,194,117,119,119, 87, 73,165,210,247, 40,165,161,162, 40, 70,137,162,184, 51, 37, 37, 69,247, 50,
+ 9,247,213, 59, 9,249,178,151,170,138,149, 10,223, 91,169, 16,176,108,135,253,120,179, 89,220,241,178,229,252,167, 28, 49, 16,
+ 66, 52, 50,153,108,164, 40,138, 61, 68, 81,220, 36,138,226,252, 23,221, 91,200,210,114,214,170, 85,107,121,139, 22, 45,122,253,
+254,251,239, 43,239,221,187, 55,242, 85, 44,123, 68, 68,196,154,170, 85,171,190, 31, 25, 25,201, 43,149, 74,164,166,166, 34, 39,
+ 39, 7, 55,111,222, 52,103,103,103,207, 56,113,226,196,236, 74, 56,255, 43,151,203,223,233,212,169,147, 90, 38,147, 33, 39, 39,
+ 7,249,249,249,244,196,137, 19, 6,142,227, 70,159, 58,117,106,101, 5,215, 39,137,136,136,248,185,106,213,170,111,133,135,135,
+243, 50,153, 12,185,185,185,200,206,206,198,141, 27, 55,132,204,204,204,255,156, 57,115,230,123, 75,156, 62, 62, 62,242,184,184,
+184,103,246,137,209,106,181,210,231,133,127,118,148,204,156,204,201,156,255,182, 22, 44, 66,200, 64, 74,233,202, 55,182, 5,235,
+105,202, 66,202, 38,188,196,243,169,254,124, 39,165, 11, 55, 32, 13, 32,239, 78,158, 12,114, 63, 81,247,224,130,248,127, 9,101,
+ 97,106, 50,202,233, 35, 82, 81,110,223,190, 61,216,221,221,253,171, 23, 5,213,138,114,252,248,241,190, 65, 65, 65, 91,147,146,
+146,198,169, 84,170, 58,130, 32,152, 13, 6,195, 69,131,193, 48,246,236,217,179,231, 43,233, 28, 16, 20, 20,244,211,206,157, 59,
+135, 11,130,224,207,113, 92, 41,165, 52,134, 82, 58,245,212,169, 83,177,149,108, 33,236, 28, 20, 20,212, 57, 57, 57,249,107,133,
+ 66, 81, 91, 20, 69, 83,105,105,233, 57,131,193,240,159,179,103,207, 90,236,124, 94,184, 2, 30,220, 34,131, 29,239, 49, 24, 12,
+198,155,131,228,205, 93, 52, 74, 39, 78, 4,197, 68,182,145, 95,113, 24,126,165,156, 63,127,254,119, 0,191,191, 98,231,126, 0,
+251, 95,177,115, 7, 44,188, 35, 54,131,193, 96, 48, 24, 28, 91, 5, 12, 6,131,193, 96, 48, 24,175, 22, 2, 32,224, 89,111, 84,
+228,220, 42, 33, 36,160,162, 31,108, 65,223, 23,230,100, 78,230,100, 78,230,100, 78,230,124,195,156,143,185,167, 60,231,173,228,
+ 50,207, 63,186, 15, 22,249, 51,187, 39,177, 14,128,204,201,156,204,201,156,204,201,156,204,249,111,132,157, 34,100, 48, 24, 12,
+ 6,131,193, 96, 1,139,193, 96, 48, 24, 12, 6,131, 5, 44, 6,131,193, 96, 48, 24, 12, 22,176, 24, 12, 6,131,193, 96, 48, 24,
+ 44, 96, 49, 24, 12, 6,131,193, 96,188, 54,144,127,209, 77,206, 25, 12, 6,131,193, 96, 48,254, 18,158,104,193, 34,132,176,180,
+197, 96, 48, 24, 12, 6,227, 47,231, 77,203, 32,236, 20, 33,131,193, 96, 48, 24, 12, 6, 11, 88, 12, 6,131,193, 96, 48, 24,255,
+128,128,197, 78, 13, 50, 24, 12, 6,131,193,248, 59,120, 83, 51,200,195, 22,172,200,178, 5,140,100,155,154,193, 96, 48, 24, 12,
+198, 95,200, 27,153, 65,216, 85,132, 12, 6,131,193, 96, 48, 24,175, 24,214, 7,139,193, 96, 48, 24, 12, 6,227,159, 20,176, 8,
+ 33, 1,204,201,156,204,201,156,204,201,156,204,201,156, 44, 96, 49, 24, 12, 6,131,193, 96, 48, 88,192, 98, 48, 24, 12, 6,131,
+193, 96, 1,139,193, 96, 48, 24, 12, 6,131, 5, 44, 6,131,193, 96, 48, 24, 12, 6, 11, 88, 12, 6,131,193, 96, 48, 24,127, 19,
+ 4,192, 51,175, 4,160,148, 94,177, 88, 82,137,171, 9,202,243, 51, 39,115, 50, 39,115, 50, 39,115, 50,231,155,231, 44,207, 93,
+145,252,241, 90, 7,172, 63,243, 70,163,132,144,128, 87,189,162,152,147, 57,153,147, 57,153,147, 57,153,243,205,115,190,105, 72,
+216, 42, 96, 48,254,225,108, 39, 60,156,234,214, 0,161,174, 32,178,116, 28,185,116, 23, 19,169,248,210, 78,215,122,213, 96, 48,
+185, 64,165,202,194,129, 11,241, 47,237,100, 48, 24, 12, 22,176, 24, 12,198, 63, 6, 79,255, 90, 48,137, 83, 0,184, 2,134, 59,
+104, 22, 48, 15,192,181,151,114,186,248,215,130, 40, 78,132,140,243,128,177,244, 54, 90,212,157, 7, 32,150,173,108, 6,131,193,
+176,140,191,165,147,123,112,112,240,201,144,144,144, 9,145,145,145, 10,182, 9, 24,140,151,224, 74,160, 26, 38,211,219,165, 70,
+209,125,223,169, 28,231, 98,189, 80, 27,156,177, 13, 98,253, 53, 47,229,228,196, 86,122,163, 80,117,195,193, 98,151, 34,189,185,
+ 14, 68,225,229,156,101, 52,104,208,192, 54, 52, 52,116,151, 86,171,117,100, 27,143,193, 96,176,128,245,138,161,148, 54,112,113,
+113, 25,170,211,233,110, 4, 5, 5,117,248, 55,173,240,176,176,176, 63, 26, 55,110,156, 16, 30, 30,158, 16, 30, 30,126,170,188,
+241,111, 42,193,193,193, 13,154, 54,109,186,215,223,255,193,143,118,224,103, 59,157,131,250,239,247, 14,251, 98,159, 7,251, 90,
+ 86,128, 66,234, 2,240,205, 99,227, 75, 84,233,185,102,151,152, 27,197, 86,160,124, 51,100,139,174, 47,229, 20, 73,243, 11,113,
+122,245,233, 59,206, 46, 39,175,150, 90, 3,124,243,151,114,150, 33,145, 72, 6, 0,104,201,243,252, 16,182,241,254,221, 16, 66,
+252, 9, 33, 29, 8, 33,218, 87,232,156, 86,183,110,221, 56, 66,200,231,108, 13, 51,254, 49, 1,171,139, 55,105,220,195,155,252,
+222,173, 38,201,232,238, 77, 50,122,122,147,131, 93,106,147,166,149,253,224,159,126,250, 73,181,126,253,122,231,128,128,128,181,
+ 97, 97, 97, 7,195,194,194,124, 42,227, 9, 13, 13,221, 21, 28, 28,252,254,211,227,180, 90,109,151,167,198,157, 11, 13, 13, 77,
+ 11, 9, 9,185,106,137, 87,171,213, 94,214,106,181,153,193,193,193,151,159, 26,223, 37, 52, 52,116,215, 83, 97,225,253,167,199,
+ 61, 15,158,231, 61,118,239,222,237,252,219,111,191, 57, 75,165, 82,151,167,199,255,250,235,175, 79,140,175, 40, 33, 33, 33,125,
+ 67, 66, 66,254,120,124, 92, 80, 80, 80,159,167,199,149,179,236,127, 4, 5, 5,245,121,202,251, 71, 72, 72, 72,223, 87, 20, 50,
+131,228,114,249,239, 70,163,177,169, 70,163, 81, 3,128,196,164,178, 22,101,146, 46, 70, 42,105, 24,248,245, 1,103,246,213,180,
+128, 88,127, 25, 68,115, 19, 65,164, 78, 87,227,245,206,237, 58,118,145, 92,186,173,115, 50, 9,130, 61, 68, 52,195,209, 26,138,
+ 74, 57, 5, 67,184, 64, 69,151, 67, 23,164,206,145, 29,134,240,135,175, 72,157, 76,130,224, 0, 65,108, 90, 41,231,255,239, 87,
+ 82,158,231,191, 24, 56,112, 32, 71, 8,249,212,199,199, 71,254,111,218, 92,141,235, 19,247,183,130, 37,199, 66,234,145,198,175,
+ 48, 80,212,181,178,178, 58, 65, 8,169,245, 15, 11, 87, 13, 0,168, 41,165,191, 1,112, 33,132, 72, 94,129,115,246,148, 41, 83,
+190,188,124,249,178, 91,205,154, 53,199, 17, 66,120, 86, 73, 48, 94,251,128,245,145, 23, 25,235,230,234,241,203,216,133,155,154,
+254,247,232, 93,205,183,187,207,107, 70,142,154,209,216,205,214,121, 71, 79,111, 50,245,121,243,189,232, 10, 3,185, 92,142, 59,
+119,238, 96,233,210,165,202, 73,147, 38, 53,178,178,178, 58, 27, 22, 22, 54,231, 97,139,134,165, 78, 74,105, 35,153, 76,182, 60,
+ 44, 44,108,197, 99, 21,118, 35,165, 82,185, 44, 44, 44,108,213,195,211,144, 90,173,182, 70, 84, 84,148, 53, 33,196,197,146,114,
+134,134,134,186,198,196,196,168, 9, 33,174, 0, 16, 25, 25,169, 8, 13, 13,253,193,211,211,115, 41,128, 70, 0,224,227,227, 35,
+ 15, 11, 11, 91, 81,181,106,213,111, 9, 33,141, 44, 89,118,142,227, 96,103,103,135, 77,155, 54,129,227,184,199, 43, 7,216,217,
+217, 97,227,198,141, 32,132, 84,120,125,250,251,251,107, 66, 67, 67, 55,185,185,185,205, 17, 69, 49, 12, 0, 2, 3, 3,213,161,
+161,161, 27, 61, 61, 61,231, 62, 28,103,161, 51, 76,161, 80,204, 9, 13, 13,221, 24, 24, 24,168, 6, 0, 81, 20,195,164, 82,233,
+236,208,208,208, 77, 21,221, 70,205,155, 55, 31,220,168, 81,163,220,144,144,144,194,136,136,136,141, 60,207,239,157, 62,125,186,
+ 90,169, 84, 26,204,246,213, 53,218, 65,135,170,202,164,114, 51, 37, 92, 41, 21, 48, 69, 90, 40,179,247,249, 98,159,220,210,101,
+175, 44,255,120,103, 38,239, 12,130, 22, 55,239,233,148, 94,181,130,213, 46,126, 93,224,108, 39, 85,156,185, 94,108, 5, 9,137,
+ 4,167,113,170,148, 19,210, 22, 87,239,232, 84, 14,222,237, 84, 33,141,155, 1,234, 90,138,163, 23,139,173, 33,225, 43,231,252,
+255,247,223, 11, 15, 15,151,181,106,213, 10,238,238,238,156,141,141,205, 71,111,252, 54,122, 44, 92, 89, 41,228, 71,231, 79,249,
+ 50,200,213, 65,189,213,146,144,101,193,229,243,117, 93, 92, 92,246, 45, 91,182,172,161,181,181,245, 1, 75, 66,214,235,176, 62,
+203,194,149,140, 82, 26,245, 48,214, 3, 8,127, 73,231,236, 73,147, 38, 13, 25, 61,122, 52, 10, 11, 11,209,167, 79, 31,107, 0,
+ 51, 43,227,236,218,181, 43,223,181,107, 87,254, 95, 81,135,188,102,206,114,144, 3,104, 1,160, 3,128,183, 0,132,150,253, 29,
+ 82, 54,116, 0,208,234,169,215,144,135,109, 4,101,255,135, 61,199,209,225, 25,243,133, 60, 54,254,241,255,159,254,251,197, 1,
+139, 16, 66, 31,127,125, 98,103,243, 33,141,156,220, 60,190,156,181, 35, 90, 37,222,186,136,243,159,180,196,141, 97,239, 65,117,
+251, 34, 70, 13,253, 70,101, 99, 99,247,105, 87, 31,210,172, 50,107,235,214,173, 91,216,188,121, 51,156,156,156,200,170, 85,171,
+ 20, 31,126,248,225, 0, 27, 27,155, 91,193,193,193, 31, 89,234,224, 56, 78, 92,189,122,181,230,221,119,223,237,226,224,224, 16,
+ 29, 18, 18,226,197,113,156,184,110,221, 58, 77,183,110,221, 58, 27, 12,134,152,176,176, 48,159,243,231,207, 11,209,209,209,224,
+121,203, 14,106, 98, 98, 98,132,189,123,247, 62,108,113,241, 1, 16, 51,107,214,172, 46, 59,118,236,176,178,177,177,161, 33, 33,
+ 33, 94, 85,171, 86,141,158, 51,103,206, 71, 63,253,244,147,149,181,181, 53,181,176, 34,128, 94,175,135, 82,169,124, 34, 72, 61,
+ 28,175, 80, 40,158, 27,176, 94,208,106, 85,215,209,209,241,252,204,153, 51, 59,238,220,185, 83,101,109,109,141, 70,141, 26,213,
+177,179,179,187, 48,119,238,220, 78,187,118,237, 82, 89, 91, 91, 91,236,147,201,100,216,176, 97,131,186, 71,143, 30, 29, 20, 10,
+197,249, 70,141, 26,213,145,201,100,216,180,105,147,186, 71,143, 30,237,212,106,117, 76, 72, 72, 72, 93, 75,125,130, 32,140, 90,
+184,112,161,124,235,214,173,124,245,234,213, 91, 79,159, 62, 93,173,213,106, 9,165, 20, 84, 94,203,214, 44,161, 93,244,156,217,
+131, 55, 24,127,229, 64,210, 5,137,177,167,157,192,179, 86,172, 23,177,157,240, 32,198, 6, 0,241,142,185, 85,226,216, 32,162,
+167, 4, 25,191, 32,212,207, 74,114, 56,166,208,133,138,168, 6,193, 28,140,163,145,146, 10, 57,101,166, 64,112,212,231,192, 69,
+206, 49,188, 85, 79,201,253,251,247,225, 85, 55,146,223, 29, 13, 23, 74, 81, 3, 68, 8,170,144,243,201,253,106, 76,215,174, 93,
+ 53, 9, 9, 9, 8, 15, 15, 87, 43, 20,138,209,175,164, 21,239,180, 95, 53, 28,247,139,192, 9, 63,215,202,150,237,207,110,185,
+178, 82,200,143,108,218,240,163, 91, 96, 68,127,178,226,203,234,246,142, 86,178,173, 47,211,146, 85, 22,174,246,158, 61,123,214,
+225,237,183,223,198,164, 73,147,156,108,108,108, 14,188,238, 45, 89,143,135, 43, 66,136,170,236,244, 96, 10, 0,143,151,112,206,
+157, 52,105,210,144, 49, 99,198,224,204,153, 51,152, 51,103, 14,218,181,107, 7, 59, 59,187, 80, 75, 29,193,193,193, 33,205,155,
+ 55,223,220,188,121,243,212,196,196,196,130,123,247,238, 21, 68, 68, 68,164, 54,111,222,124,115,112,112,112,200,203, 44,114,217,
+192,120,241, 54,124,110, 6,121,140,250,163, 71,143, 14, 37,132,252, 58,122,244,232, 96, 0, 78,132,144, 95, 1, 56, 3,112, 46,
+251, 91,254,212,171,115, 89,104,122,248,190,227,179, 28, 15,135,167,230,115,126,108,252,227,159,241,244,223,229,183, 96, 17, 66,
+154, 3, 56,246,244, 4, 82, 17,227, 7,141,152,170,140, 95,187, 0,169, 27, 22,130,100, 37,131,207, 75, 67,233,177, 95, 96, 58,
+254, 11,122, 55, 14, 87,169, 64, 38, 86,102,165, 90, 89, 89, 65, 38,147,225,214,173, 91,184,126,253, 58,218,181,107, 39, 91,178,
+100,137,109, 64, 64,192,178, 38, 77,154,156, 9, 11, 11, 11,176, 96,195,160,118,237,218,232,214,173,155,124,216,176, 97, 53,229,
+114,249, 41, 74,169,196,203,203, 11, 31,126,248,161,108,212,168, 81,213,229,114,249, 9, 81, 20,101,106,181,218,226,240, 66, 8,
+129, 90,173, 6, 0,169,183,183,247,201,205,155, 55,215,104,210,164,137,100,255,254,253, 40, 44, 44,228,107,213,170,117,102,243,
+230,205,222,141, 27, 55,150,156, 56,113, 2, 58,157,206,226,128, 85, 92, 92,252,204,128, 85, 84, 84,244, 63,227, 45, 8, 87,125,
+107,214,172,121,124,203,150, 45, 30, 77,155, 54,229, 15, 31, 62,140,194,194, 66,120,122,122,158,216,178,101,139, 71,120,120, 56,
+127,234,212, 41, 20, 22, 22, 86, 40, 96,149,173, 63,233,200,145, 35, 61,120,158, 63, 46,147,201, 80,189,122,117,124,248,225,135,
+178, 17, 35, 70,120,200,100,178,163,150,158, 50, 20, 4, 65,238,236,236, 12, 91, 91, 91,244,239,223, 95, 93,167, 78, 29, 98, 54,
+155, 65, 41,133,220, 88,108, 36, 34,173, 77, 8,247, 62,225,121,163, 0,178,145, 80, 62, 66, 52, 75,100,172,218,121, 1, 54, 1,
+ 14,224, 73,203,123,169,165, 10,165,166,170,149,198,169, 14,144,115, 12, 53, 61, 20, 32,132, 83, 68,197, 22,105,192,147,150, 16,
+178, 29, 42,228, 20,208,242,110,114,169,194,168,170,167,113,247,168,134,172,172, 44, 84,245,242,131,158,115,150,159,186, 90,164,
+ 1,173,160,179, 12,173, 86,219,164,106,213,170,174, 53,106,212, 64, 86, 86, 22,106,213,170, 5, 43, 43, 43,187,134, 13, 27,182,
+172,244, 58, 56, 90, 67,129, 2,174, 17, 4,204, 4, 48, 14,224,166,128,100, 53,192,121,173,244,117, 11, 87,155, 55,254,232,238,
+232, 86, 7,184,210, 31, 85, 28,228, 88, 53,186,190,189,163,149,162, 82, 33,139, 16, 82,183, 74,149, 42,123,207,158, 61,235,168,
+ 84, 42, 17, 19, 19, 3,127,127,127, 44, 88,176,192,201,206,206,238,181, 13, 89, 79,133, 43,123, 74,169, 14,128, 8,160, 43, 42,
+113,213, 43,121,192,130,169, 83,167, 14, 30, 51,102, 12, 78,159, 62, 13, 15, 15, 15,100,100,100,160, 89,179,102,247,243,242,242,
+102, 91,210, 90,213,172, 89,179,111,237,237,237,127, 29, 48, 96, 64,199, 77,155, 54,217,236,220,185,147, 52,111,222,156, 84,171,
+ 86,205,102,192,128, 1, 29,237,237,237,127,109,214,172,217,183,150,182,106,149, 33, 1,160, 4,160,126, 56,220,185,115, 71,238,
+227,227, 35, 39,132, 40,203,194,165,130, 16,194,158,166, 82, 78, 6,121, 12,167, 89,179,102,205,160,148,118,156, 53,107,214,140,
+199,230,251,245, 5,206,199, 67, 19, 0,224,105, 7,165,180,227,227,175,143,207, 75, 41,237, 72, 41,237,248,248,252, 47,250,188,
+231, 6, 44, 0, 71, 40,165,205,255,167, 25,144, 32,192,181,102, 29,228, 29,216, 6, 21, 79,158, 24,184,187, 87, 80, 85, 41,129,
+153,210,186,149, 89,161, 86, 86, 86,143, 6,142,227,144,154,154, 10,158,231, 49, 97,194, 4,229,144, 33, 67,234, 73, 36,146,195,
+205,155, 55,159, 82, 94, 96, 1,128,168,168, 40,212,170, 85,139,140, 25, 51,198,186, 89,179,102, 18, 0,184,116,233, 18,124,124,
+124,200,180,105,211,172, 58,117,234, 68, 42, 18,176, 56,142,131, 82,169, 68,100,100, 36, 89,179,102,141, 70,161, 80,224,183,223,
+126, 67, 86, 86, 22,222,126,251,109,201,154, 53,107, 52, 74,165, 18, 71,143, 30, 69,126,126,126,133,130, 91,105,105, 41,158, 46,
+203,243, 90,182, 94, 68,147, 38, 77,190,115,117,117,157,179,126,253,122,133, 74,165,194,225,195,135,145,159,159,143,238,221,187,
+155, 55,110,220,168,180,177,177,193,169, 83,167,144,159,159, 95,169, 29,254,177,117,170, 10, 15, 15, 55, 1,192,133, 11, 23,224,
+235,235, 75,198,140, 25,163,178,177,177,153, 29, 17, 17,241,157, 5, 77,201, 40, 41, 41,129, 94,175,199,237,219,183,145,147,147,
+131,164,164, 36,136,162, 8,130,140, 66, 81, 38,221, 74, 68,225,125, 94,170, 80, 72, 56, 18, 11, 2, 63, 42, 17,101,100,242,100,
+ 86,249, 60,111, 39,146,149,214,130, 72, 26,156,190, 86,100,223,244,237, 30, 50,100,238, 5,168, 9, 32, 18,180, 8,243,148,252,
+114,170,196, 5,148, 4, 64, 69,124, 1, 11,118, 40, 66, 8,164, 6, 31, 80, 18,116, 32,198,236,208,180,205,103,178,164,164, 36,
+200,100, 50, 40, 20, 10, 4, 53,254, 64,178,249,136,201, 21, 64, 32,148,164,182, 69,206, 39, 67,251, 55,253,250,245, 83, 39, 39,
+ 39, 63,114,182,107,215, 78, 99,101,101, 53,166,210,225,138,183, 10,133, 89, 24,114,245,174,174,218,180,245,169,117,226,146,116,
+190,224,232, 23, 48, 8,245, 95, 54,100,121,121,121, 69,212,169, 83,231,154,183,183,119,248,203,132, 43,107,133,252,240,150,141,
+ 63,186, 59,184, 62, 8, 87, 16, 74, 0, 94, 5, 87, 23,123,172,154, 24,105,239,104,173,170, 80,200, 42, 11, 87,123,206,156, 57,
+227,168, 84, 42,113,238,220, 57,200,229,114, 40,149, 74, 4, 6, 6, 98,229,202,149, 78,246,246,246,175, 69,200, 34,132,216, 17,
+ 66, 90, 17, 66, 58, 19, 66,222,123, 44, 92,213, 0, 16, 73, 8,105, 9,160, 10,128, 19,148,210,203, 22, 58,195, 37, 18,201,207,
+ 13, 26, 52,184, 35,145, 72, 98,102,204,152, 49,104,212,168, 81, 88,188,120, 49, 34, 35, 35,239,126,243,205, 55,184,113,227,134,
+185,184,184,184, 43,165,116,111,121,190,148,148,148,113,222,222,222, 93,118,238,220,169,169, 94,189, 58, 87, 92, 92,140, 3, 7,
+ 14, 96,238,220,185, 40, 45, 45,133,167,167, 39,183,115,231, 78,141,183,183,119,151,148,148,148,113, 22,148,207,201,201,201,169,
+ 22, 30,156,206, 82, 0, 80, 1, 80, 39, 36, 36,104, 14, 31, 62,108,223,160, 65, 3, 59, 43, 43, 43,245,184,113,227,220,135, 13,
+ 27,214,177,188, 22,144,127, 25,207,204, 32,207, 9, 77,143,255,190,116,124, 94,232,121,248,222,179,194, 83,101, 11,249,162,207,
+123, 81,192,138, 36,132, 28,125,214, 68,198,112,179,214,203, 0, 0, 32, 0, 73, 68, 65, 84,156,116, 40, 32, 64,205, 19,168, 36,
+228,193, 43, 79,160, 34, 34, 36,185,233, 21,172,106,159, 12, 88,214,214,214,176,182,182,126, 34,104,233,116, 58, 20, 23, 23, 63,
+209, 71,233,121, 60, 60,229,103,111,111,143,194,194, 66,152,205,102, 60, 60, 29,230,224,224,128,210,210, 82, 16, 66,160,209,104,
+160,209,104, 42, 28,176, 0,224,244,233,211, 56,121,242, 36, 36, 18, 9, 28, 28, 30, 28,188,159, 59,119, 14,151, 47, 95,134, 92,
+ 46,135,163,163, 99,133,188, 6,131, 1, 74,165,242,127,250, 96, 25, 12, 6, 40, 20, 10,139, 79, 99,114, 28, 7,189, 94, 79,207,
+157, 59,135, 43, 87,174, 64,161, 80,192,217,217, 25, 50,153, 12,137,137,137,136,141,141,133, 92, 46,135,179,115,229,190,195, 54,
+ 54, 54,200,203,203,131, 40,138, 80,169, 84,143,198, 21, 21, 21,129,227, 56,139,182,207, 67, 46, 92,184,128,211,167, 79, 35, 62,
+ 62, 30,151, 46, 93,194,141, 27, 55,240,196, 83, 4,104, 89, 51,186, 73, 52, 81,128,227, 77, 60, 55, 9, 19, 89,149,243,204,106,
+168,190, 13, 56,201, 91,153,121, 38, 69, 86,145,220,166,138,207, 91, 64,214, 94,128,240,128,212, 14,141, 26,214,196,253, 52, 65,
+125, 35,169, 84, 9,163,208, 26,251,235,218, 89,228,148, 72, 90,102,228,153, 20,241,249,206,214,117, 3,180,200,200,200,128, 66,
+161,128, 66,161, 64,112,216, 91,184,147, 38,170,174, 38,232,212, 16,197, 86, 22, 57,255,191,245,170,166, 82,169, 12, 13, 10, 10,
+ 34,233,233,233, 80, 40, 20, 80, 42,149,104,220,184, 49, 56,142,171,167,213,106,125, 43,180,252,119,124,228,144, 89,133, 0,194,
+144,235,119, 75,220,118,157,212,213,122,231,157, 15,236, 23,109,207,244,189,158,160,175, 1,179,113, 24, 10, 77, 13, 43, 27,178,
+188,188,188,154,170,213,234,159,198,141, 27, 87, 67, 42,149,238,168, 89,179,102,147,202,120,212, 10,126,201,216, 97,221,221,237,
+ 31,134, 43,115, 49,192,171, 0, 94,253, 32,100, 85,113,194,180, 97,173,236, 85, 82,217,102, 75,157, 42,149,106,237,178,101,203,
+156, 30,134, 43,153, 76, 6,165, 82,249,104, 8, 10, 10,194,196,137, 19,157,236,237,237,215,252,205,225,202, 30, 64, 19, 0, 87,
+ 0,236, 4,112,248,177,112,229, 13, 96, 87, 89,171,213, 69, 74,233,125, 11,157,141,218,182,109,187,247,206,157, 59,109, 46, 94,
+188,232,154,150,150,230, 59,114,228, 72, 44, 90,180, 8,163, 70,141,218, 74, 41,109,176,109,219,182,198, 81, 81, 81,161,148,210,
+107, 22,214,161,159,244,236,217, 83,173, 82,169,160, 84, 42,177,126,253,122,124,246,217,103, 80, 40, 30, 92,203,161, 86,171,161,
+ 82,169,208,179,103, 79, 53, 33,164,159, 5,202,156,130,130, 2,171,206,157, 59, 87, 45,107,185,210, 24, 12, 6,171,172,172, 44,
+ 27,142,227,108,235,213,171,231, 50,113,226, 68,223,162,162,162,250,187,119,239,206, 0,144,197, 42,180,242, 51,200,211, 1,199,
+146,113,149,157,222,210,144, 85,161,128, 69, 41, 61, 10,160,217, 51, 38,184,114, 63,250, 40, 28,252,131,158,108,193,146, 16,168,
+173,109,112, 55, 57, 17, 82,144,235,149, 40,224, 19, 45, 88, 15,135,212,212, 84,124,243,205, 55, 37, 27, 54,108,184,106, 52, 26,
+ 91, 28, 61,122,116,130, 37, 45, 88, 46, 46, 46,184,127,255, 62,157, 59,119,110,225,190,125,251,204, 15,199, 37, 38, 38,210,241,
+227,199, 23,253,248,227,143,180,162,167, 8, 85, 42, 21,142, 30, 61, 74, 39, 76,152, 80,144,156,156, 76, 29, 28, 28,224,232,232,
+136, 67,135, 14,153, 71,143, 30, 93, 16, 23, 23, 71, 29, 28, 28,224,224,224, 80, 33,175, 32, 8, 80,169, 84, 79,204,195,113, 28,
+ 76, 38,211,255,140,127, 17,199,143, 31,255, 44, 63, 63,127,212,215, 95,127,173,187,118,237, 26,117,118,118,134,179,179, 51,214,
+174, 93, 43,233,211,167,143,238,210,165, 75,143,198, 85, 6, 39, 39, 39,220,184,113,131,206,156, 57, 83,119,240,224, 65, 41, 0,
+ 56, 59, 59,227,198,141, 27,116,234,212,169,186,188,188,188, 81,199,143, 31,255,204,146,109,157,147,147,131,172,172, 44, 36, 37,
+ 37, 33, 43, 43, 11,217,217,217, 16, 69, 17, 20, 46,214,156,209,244, 33,120,110,135, 96, 42, 45, 53, 73, 72,109,128,222, 21, 68,
+163, 97,226, 68,176, 59,135, 63, 11,185, 80, 5,160,141, 79, 92, 46,178,109,221,254, 35, 57, 41,136, 2, 76, 69,128,212, 30,144,
+218, 67,162,116, 68,219,150, 13,249, 53,251, 11,170,128, 32, 12,182,242,242,251,183, 72, 69, 23, 80, 49,252,224,121,189, 93,211,
+118, 67,229, 57, 57, 57,224, 56,238, 81,192, 82,107, 52,104,213,190, 39,183,250,128,190, 10, 68,218, 8, 42, 98,113,159, 25,153,
+ 76,246,101,191,126,253,100, 79, 59, 85, 42, 21,222,125,247, 93,133, 70,163, 25,101,241,178,199,250,203,144,161, 10,129, 40, 12,
+185,145,160,115,219,121, 74, 87,107,228,196,213,170,122,245,195,240,233, 59,206,170,153, 27, 50,253, 46,222, 41,169, 1,137,121,
+ 40,138, 76, 65, 88, 89,177,144, 85,179,102,205, 38,106,181,250,231,157, 59,119,170, 91,180,104,129,175,190,250, 74, 35,147,201,
+118,120,121,121, 85,248,138,105, 93,161, 48, 98,234,162,245, 25,151,182,182, 5,204,133,101,225,234,255,135,140,124, 17,227,151,
+ 29, 46, 48, 80,177,143,197, 78,157,110, 64,255,254,253,115,126,250,233,167,255, 9, 87, 74,165, 18,241,241,241,152, 54,109, 90,
+110,110,110,238,192,191,121, 47,173, 15,224, 18, 0, 61,128,166, 0,212,101, 87, 10,134,150,133, 45,129, 82,154, 65, 41, 77,179,
+ 84,200,243,252,136,229,203,151, 75,116, 58, 29, 6, 12, 24,128,196,196, 68,164,164,164, 96,236,216,177, 9,162, 40, 14, 40,115,
+ 94,166,148,222,180,212, 89, 92, 92,252,233,148, 41, 83,116,201,201,201, 8, 8, 8, 64, 70, 70, 6,218,183,111,143, 14, 29, 58,
+ 64,173, 86, 35, 48, 48, 16,137,137,137,152, 60,121,178,190,164,164,196,146,186, 78, 52,153, 76,215, 15, 31, 62,172,236,216,177,
+ 99,237,121,243,230,121, 29, 62,124,216,167,164,164,164, 70,105,105,169, 95,106,106,170,255,238,221,187,171,173, 92,185, 50, 49,
+ 33, 33, 33,154, 82, 42,176, 10,237,197, 25,228, 21,240,219,203,180, 84, 61,171, 5,204, 82,184, 50, 17,121,252,245,137,214, 43,
+130,169,235,182,175,213,203,171,215,134,173, 95, 3,168,149, 74,168, 20,114,168,236, 28,160, 23, 69,252, 16,159, 86, 82, 12, 58,
+249,101, 3,150, 40,138, 88,177, 98,133,126,218,180,105,249,169,169,169, 95, 28, 59,118,172,209,217,179,103,203,189, 74,129,227,
+ 56, 20, 20, 20, 96,219,182,109,186, 53,107,214,220, 45, 45, 45, 13,151, 74,165,102,131,193,128, 77,155, 54,233, 23, 47, 94,124,
+ 79,175,215, 55,149, 74,165,198,138,156,126,123, 24,176,164, 82,169,169,180,180, 52,124,235,214,173,119,126,253,245, 87,157,141,
+141, 13, 36, 18,137, 89,175,215,135,174, 95,191,254,214,150, 45, 91,116, 54, 54, 54, 21,242,138,162,248,204, 62, 88,130, 32, 60,
+ 58,114,178,148,232,232,232, 53, 38,147,169,249,230,205,155,147,215,172, 89,163,183,177,177, 1, 0, 8,130, 16,177,110,221,186,
+228,239,191,255,190,180, 34, 29,220, 1,192,104, 52, 66, 16, 4,172, 91,183,174,116,203,150, 45,201,162, 40, 70, 60, 28,183,122,
+245,106,253,250,245,235,147, 77, 38, 83,243,232,232,232, 53, 22,110,107, 67, 74, 74, 10, 82, 83, 83,113,233,210, 37, 67,108,108,
+ 44,205,202,202, 2,165, 20, 38,137, 70, 66, 57,114, 75,164,116, 59, 21, 4, 25, 79,241, 17, 1, 57, 70,120,222,200,170,156,231,
+ 80, 4, 53, 8, 81,221, 76,212, 91, 43,101, 38,130,180,159, 1,153,253,163,128, 5,169, 61,220, 61, 60, 17,125,163,196, 10, 4,
+114,232, 77,229, 39,236, 18,170, 1, 33,234,171, 9,212, 90, 34, 83,145,244,244,244, 71, 63,218, 15, 3,145,151,183, 63, 46,220,
+ 42,209,128, 64, 1, 17, 22,223, 74, 68, 20,197,118, 86, 86, 86,146,135,206,135, 62,133, 66,129,154, 53,107,242, 38,147,169,181,
+197,203,158, 46,186, 66, 48,127,122,243,158,222,109,231, 9,157,207,136,241,171, 85, 42, 46, 23, 72, 88,140,122,181, 92, 49,226,
+227,250,242,177,171,178,234, 70, 95, 47,169, 9, 78,232,143,186,197, 78,150,170,189,189,189,195, 85, 42,213,142,157, 59,119,170,
+ 53, 26, 13,238,220,185,131,250,245,235, 99,218,180,105,106,149, 74,245,179,151,151, 87, 68, 69, 54,211,169, 88,122,191,164, 72,
+104,241,159, 21,137,233,151,226,133, 7,193,138,123, 16,174, 50, 11, 40,250,143,255, 37, 63,183, 72,223,253,204, 69,211,209, 10,
+212,155,151,242,243,243, 59,141, 31, 63, 62, 39, 43, 43,235,137,112,117,239,222, 61,116,235,214, 45, 55, 43, 43,171, 13,165,244,
+250,223,188,151,106,240,160,243,186,111, 89,139, 85, 32,165,212, 12,160,168,178,161,162,110,221,186, 13,170, 87,175,142,239,190,
+251, 14, 63,252,240, 67,222,130, 5, 11, 64, 41, 69,237,218,181,109, 42,235,188,120,241,226, 94,157, 78,247, 77,239,222,189,117,
+ 27, 55,110, 20,250,244,233,131,144,144, 16,104,181, 90,244,238,221, 27, 63,252,240,131,185, 87,175, 94,122,189, 94, 63,234,226,
+197,139,123, 45,220, 70,165, 5, 5, 5, 23,127,251,237,183,203,203,151, 47, 79, 26, 62,124,120,209,192,129, 3,101, 51,102,204,
+200,218,182,109,219,197,227,199,143,255,174,215,235,163, 41,165,165,172, 50,123,180,206,158,155, 65, 30, 35,179, 44,232, 24,158,
+122,205, 44,231, 61, 75,231,125,230,223, 22, 76,247, 92,202,189,226,102, 91, 28, 61,211,211,155, 44,156,186,250,251,225,189, 2,
+235,170,106,120,213,133, 80,148,135,203,105,105, 88,151,154, 95, 98, 20,233,138,109,119,232,177,202, 6, 44,158,231,241,251,239,
+191, 11,155, 54,109, 50, 2, 88,157,159,159, 63,229,218,181,107,197, 21,168,188,185,126,253,250, 21,231,228,228,236, 74, 77, 77,
+253, 34, 46, 46,206, 16, 17, 17,193,245,232,209,163, 56, 59, 59,251, 55, 66,200,231,103,207,158, 45,109,218,180, 41, 42,242, 96,
+107, 66, 8,100, 50, 25, 8, 33,136,138,138, 74,240,247,247, 15, 57,115,230,204,194, 91,183,110,125, 64, 41,229,162,163,163,147,
+180, 90,109,216,169, 83,167,230,199,198,198,126, 40,138, 34,103,169,151,227,184,255,105,169, 34,132, 60, 10,117, 21,189,138, 48,
+ 58, 58,250,186,191,191,191,246,204,153, 51, 43, 6, 14, 28,216, 10,128,250,204,153, 51, 55, 2, 3, 3,131,206,156, 57,179,226,
+227,143, 63,110, 93,214, 92,109,113,192,122,239,189,247, 74,242,243,243, 15, 20, 22, 22, 14,186,124,249,114,137, 86,171,197,123,
+239,189, 87,146,151,151,119, 48, 47, 47,111, 80, 69,182, 17,165,116,246,137, 19, 39,166, 81, 74, 37, 42,149,106,239,197,139, 23,
+ 91,149,148,148,168, 41,165, 32,194,221, 2,206, 16,246,147, 64, 36, 28,149,240, 29, 64, 80, 11, 60, 38,200,228,106,214,116,254,
+ 60, 20,230, 66, 16,146,218,181,165,131, 98,241,178,213,210,190,157,106, 42, 3,252,170, 63, 8, 87, 50,123, 68, 95,207,195,196,
+ 5,219,196,153, 3,157, 18, 32,210, 36, 24,233,173,114,157, 54,124, 33, 74,197,204,126,109,228,138, 89,255, 29, 94,163, 73,135,
+175, 21,117, 3, 66, 31, 5,161,216,107,231,176,104,214, 23,226,204, 1,118, 9, 16,145, 10, 3,110, 86,224, 59,218,115,214,172,
+ 89, 59,251,246,237,171,169, 87,175,222, 35,103,124,124, 60,230,204,153,163,211,235,245,221, 45,253, 86, 66,234, 87, 95, 48, 83,
+231,141, 7,178,125,190, 28,250,169, 90,197,229, 0,119,231, 61, 8, 47, 82, 91, 52,172,231,132, 9,159,187, 74, 71,206,221,237,
+119, 98,113,205, 34,136,242, 58, 0, 82, 45, 58,218,228,184,159,103,204,152,161, 86,169, 84,184,117,235, 22, 30,158, 54,210,106,
+181, 88,180,104,145,122,200,144, 33, 59, 35, 35, 35, 93,142, 28, 57, 98,174, 72,200, 10,247, 35, 45,254,179, 60,238,240,156, 97,
+118, 85,234,215,113, 70, 86, 33,208,127,226,238,188,236, 34,125,207,138,132,171,199, 67, 22, 33,164,211,176, 97,195,118,175, 93,
+187,214,161,110,221,186, 72, 76, 76, 68,183,110,221,114,178,178,178,218,190, 6,225, 10, 0,138, 1,184, 3,184,133, 7,125,145,
+238, 16, 66,228,120,137,199,179, 93,191,126,253,226,189,123,247, 92, 63,249,228, 19, 20, 20, 20,216,125,244,209, 71,184,115,231,
+ 14,110,222,188,121,233,101, 10, 26, 21, 21,181,170, 81,163, 70,167,215,172, 89, 51,146,227,184, 38,165,165,165,206, 0,196,253,
+251,247,167, 9,130,112, 92,167,211, 45, 57,119,238,220,173, 10,110, 35, 10, 32,187,108,184,197, 42,173, 87, 66,244,223, 52,111,
+165,177,104,103,223,120,135, 78,239,226, 77,142,252,112, 38,106,130,145,210, 6, 0, 32,227,200,149, 34, 66,167,108,191, 67, 79,
+188, 32, 76,188,240,105,219,241,241,241, 88,188,120,113, 73, 81, 81,209,101,179,217, 60,248,236,217,179,113, 22, 4,148, 39,156,
+ 18,137,228, 76, 98, 98,226,134,115,231,206,253,252,248,184,164,164,164, 77, 81, 81, 81,219, 31, 27,151,216,162, 69, 11, 15, 66,
+ 72,182, 37,229, 36,132,164,189,251,238,187, 60,207,243,201, 0,112,237,218, 53, 35,128,207, 67, 66, 66,126,183,178,178,234, 3,
+ 0, 49, 49, 49, 38, 0, 95,132,134,134, 30,208,104, 52,125, 45, 89,118, 66, 8,120,158,127,102, 11, 22,128, 23,118,114,127,209,
+250, 44, 11, 60, 61, 66, 66, 66,250,170,213,234,158, 0,112,249,242,229, 18, 0, 61, 67, 66, 66,250,168,213,234, 94,150, 58,213,
+106,245,217,244,244,244, 13,209,209,209,107,159, 26,183,209,146, 86,171,167,157,209,209,209,203, 1, 44,127,248,127, 88, 88, 88,
+208,237,219,183,247,138,162,168,146,100,223, 45,185,240, 91,187, 12,237,160,195, 53, 5,142,106, 64,232,120, 51, 71,114, 46, 44,
+104,164,175,200,190, 84, 25,254,177, 78, 71,238, 62,178,201, 34, 31,119,229,200,129,157, 28,200,236, 45,119,107, 12,237,233, 42,
+ 15,106, 96,143,179,215,114,241,213,180,141,226,172, 65,206,119,155,248, 91, 37, 64,196,114, 8,165,153,229, 58,173, 76,247,161,
+ 55, 45,168, 93, 85, 49,114,228,251, 34,153,176,126,186,151, 82, 57, 77, 22, 28, 22,137,235, 87,163, 48,123,210, 32,113,246, 32,
+187,187, 77,234, 90, 39,130,112,223, 66,208,103, 90,186,236,209,209,209,167, 67, 66, 66,222, 91,187,118,237,206, 97,195,134,105,
+ 2, 3, 3, 17, 31, 31,143, 41, 83,166,232, 74, 74, 74, 62,184,112,225,194, 49,139,151,157, 18, 10, 80,136, 2,132,111, 38,125,
+107,208, 25, 4,162, 51, 82,162, 55,128,211,149,138,164,200, 32, 18,147, 73, 36, 30,206,234, 7, 45, 26,220,255, 30,248, 60,175,
+156, 28,199,229, 15, 27, 54,204,234,185,185, 86,161, 40,174,204,118,127, 20,178, 22,199, 28, 30,213, 95, 86,101,201,166,115,185,
+ 89, 5,250, 94,229,133,171, 23, 57, 31,134,172,190,125,251,238,158, 59,119,174,195,232,209,163,179, 51, 50, 50,218,149, 23,174,
+254,194,125,254, 18, 30,220,219,234, 44,165,244, 56, 33, 68,131, 7,247, 32,186, 90, 89,167, 32, 8, 11, 62,253,244,211,214, 51,
+102,204,144, 76,156, 56, 17,113,113,113,152, 58,117,170, 96, 54,155,231,190,236,119,243,204,153, 51, 55, 0,244,255,215,212, 33,
+175,169,243, 77,131, 84,164, 85,231, 85,109, 0,173, 86, 91,210,166, 77, 27,221,209,163, 71,139,245,122,253,208,243,231,207,255,
+246,111,217,249, 90,182,108,249, 7,207,243, 94,132, 16, 80, 74, 83, 15, 28, 56, 16, 14, 0, 45, 90,180,248, 67, 34,145,120,149,
+ 29,241,167, 30, 58,116, 40,252, 77,254,226, 5, 7, 7, 55, 0, 48, 93,175,215,119,189,118,237, 90,113,195, 47,246, 57, 17, 29,
+103, 67,120,222, 24,179,226,173, 68, 86,233,148,227,220,231, 35,135, 90, 17, 4,208,145,151,239,148,212, 24,191, 54,219,171, 99,
+235,198,210,117,219,143,137,179, 62,125, 20,174, 22,128,234,206,161,121, 66,169,197, 78, 37, 23, 12, 94, 50,242,194,237,146,106,
+ 95,173,200,245,110,221,177, 63,255,235,207, 43,196,217,131, 28, 30,134,171,249, 16,138,162, 44,118, 62, 70, 72, 72, 72, 99,153,
+ 76,182,179,123,247,238,154, 45, 91,182,148, 27,174,158,233, 60,229, 95, 21,102, 58, 9,132,150,223, 7,140,114,119, 96,194, 44,
+188,117, 45,241,117,216,238,225,126,164,154,202, 74,249, 83,177,209,244,181, 37, 45, 87,150, 56, 9, 33,245,237,236,236, 86,229,
+229,229,245,182,164,229,234,175, 92,118, 66,136, 19, 0,109,217,129, 60, 1,112,157, 82,122,247, 37,157,225, 60,207,143,240,241,
+241, 9,136,139,139,187, 38, 8,194, 66, 74,233,113, 22, 92, 88,192, 98, 1,171,140,136,136,136,147,162, 40, 30,144, 74,165,115,
+142, 28, 57, 82,202,118, 62,230,100,206, 74, 56, 31, 11, 89,231,110, 21,123,205,218,146, 91,245,203, 46,182, 73,229,133,171,114,
+157,101, 33, 43,234, 70, 73,245,217, 91, 11,170,142,248,192, 42,169,188,112,101,233,178,135,132,132, 52,150,203,229, 43, 75, 74,
+ 74, 62, 47, 47, 92, 61,211, 25,235, 47, 67,182,217, 29,148,248,131,210,231, 63,106,135,240, 37, 32,220, 53,100,208, 12,116,185,
+102,100,251, 18,115, 50, 39, 11, 88,127, 53,127,203, 93,143,143, 31, 63,222,132,173,122, 6,227, 37,105, 27,103,192, 62,159,243,
+ 80, 43,230, 7,251,170, 62,253,121,178,186, 4,148, 36, 67,164,223,190, 40, 92, 89,224, 60, 7,165,121,126,104,109,213,231, 59,
+ 38,169, 75, 0,164, 3,220,210, 23,133, 43, 75,137,142,142, 62, 13,192,191,210, 2,191,107, 70, 0, 9, 0,185,135,201, 47,184,
+ 67,246, 68, 80,224, 79, 60,122,100, 48, 24,140,215, 49, 96, 49, 24,140, 87, 24,178, 98,253, 99,144, 41, 29, 3,130, 26,144,154,
+ 18, 81, 96, 74, 71,219, 4,195, 75, 58,163,145,201,223, 3, 69, 45, 72, 76,119, 81,160,127, 57,231, 43,135,210, 7, 33,138,193,
+ 96, 48, 88,192, 98, 48, 24,127, 6,126,215,140,240, 67, 50,128,228,215,218,201, 96, 48, 24,255, 34, 8,128,128,103, 31, 31, 90,
+126,110,149, 16, 18, 80,209, 15,182,160,243, 38,115, 50, 39,115, 50, 39,115, 50, 39,115,190, 97,206,242,220,111, 74,223,174,191,
+165,147, 59,115, 50, 39,115, 50, 39,115, 50, 39,115, 50,231,155, 12,123,152, 46,131,193, 96, 48, 24, 12, 6, 11, 88, 12, 6,131,
+193, 96, 48, 24, 44, 96, 49, 24, 12, 6,131,193, 96,176,128,197, 96, 48, 24, 12, 6,131,193, 96, 1,139,193, 96, 48, 24, 12, 6,
+227,181,225, 79,189,138,144,193, 96, 48, 24, 12, 6,227,223, 8, 7, 0,132, 16,150,178, 24, 12, 6,131,193, 96,252,229,188,169,
+ 25,132,157, 34,100, 48, 24, 12, 6,131,193, 96, 1,139,193, 96, 48, 24, 12, 6,131, 5, 44, 6,131,193, 96, 48, 24,140,127,103,
+192, 34,132, 80,214, 23,139,193, 96, 48, 24, 12,198, 95,205,155,152, 65,216, 85,132, 12, 6,131,193, 96, 48, 24,175, 24,118,138,
+144,193, 96, 48, 24, 12, 6,227,159, 20,176, 8, 33, 1,204,201,156,204,201,156,204,201,156,204,201,156, 44, 96, 49, 24, 12, 6,
+131,193, 96, 48, 88,192, 98, 48, 24, 12, 6,131,193, 96, 1,139,193, 96, 48, 24, 12, 6,131, 5, 44, 6,131,193, 96, 48, 24, 12,
+ 6, 11, 88, 12, 6,131,193, 96, 48, 24,127, 19, 4,192, 51,175, 4,160,148, 94,177, 88, 82,137,171, 9,202,243, 51, 39,115, 50,
+ 39,115, 50, 39,115, 50,231,155,231, 44,207, 93,145,252,241, 90, 7,172, 63,243, 70,163,132,144,128, 87,189,162,152,147, 57,153,
+147, 57,153,147, 57,153,243,205,115,190,105,176, 83,132, 12, 6,131,193, 96, 48, 24,175, 24,201,155,182, 64,254,254, 93,101,249,
+ 82,250,142,189,189,205, 72, 80,138,220,188,194,249,182, 38,242,203,181,107,219,140,127,214,103, 18, 66, 8, 0,208, 55,244,185,
+ 67,132, 16,101,189,122,245, 66, 0,224,234,213,171,209,148, 82,253,203,174, 47,103,255,206, 35,172,109, 84,189,204, 38,129,234,
+117,165,107,210,175,238, 88,242, 42,203,236,236,236,175, 49, 40, 53,211, 0,241,109, 16,112,148,146, 35,146, 34, 97, 84,110,110,
+ 76,129,165, 14,247,102,163, 70,241, 50, 73, 63,193,104,154,157,114,108,206,106,247,200,201,142,130,185,120,150, 84, 33,143, 16,
+ 13,198, 57, 41,199,231,252,192,170,144,138, 99,227,223,198, 94, 37,179,230,211, 46,108,203, 98,107,131,193, 96,176,128, 85, 70,
+181,128, 30,118,165,196, 56,150,151,240,239, 81, 42, 90,165, 93,216,230,252, 58, 44,136, 75,189,247,106,218,217, 91, 15,173,215,
+200,175, 75,143, 15,218, 40, 3,235,249,202, 75,141,102,252,178,231,216,183, 91,127,217, 63,207,183,217,199, 59,243,114, 11,151,
+254, 31,123,215, 29, 31, 69,181,182,159, 51,179,125, 55,157,100, 55,217, 77, 0, 9, 36, 64, 18, 32, 84, 19, 66,145,222,155,160,
+162,136,160, 2, 74, 19,229, 74, 71,244,162,160,116, 68, 64,138,210, 81,144, 94, 2,210,123, 73,168, 9, 4, 8,164,215, 77, 79,
+182,100,203,204,249,254, 72,194,141, 24,200, 6,240,126,247,122,231,209,253,177, 51, 57,231,217,119, 78,125,230, 61, 45, 59,102,
+207,163,151, 44, 62,100, 51, 70, 4,116,243,112,146, 73, 9, 33,187, 41,165,246,170,194,105,154,191,125,130,128,188, 82, 22,135,
+ 1, 97, 0, 2,154,145,118,117,115,120, 21,156, 74, 0,222, 0,146,158,198, 87, 21, 20,218, 96, 95, 9, 35,253,130, 49,226,179,
+154, 8,137,103, 60,155,186,126,253,250,225, 1, 1, 1,234,113,227,198,137, 1, 96,241,226,197,141, 26, 52,104,144, 29, 31, 31,
+127,129, 82,154,253, 92,121, 21,212,127,234,172, 41, 31,205,236,215, 61, 2,249, 37, 54,124,191,254,215,121,154,144,129,108,214,
+237,221, 75, 94, 74,158,104, 91, 40,220,157,156,174,140,255,244, 75, 93,207,142, 45, 68, 5, 70, 59,118, 70, 94,124,107,239,207,
+243, 58,184,187,183,104,237, 72,218,232,194,255,241,170,239, 43,190,179, 7,246,239,139,239, 87,173, 27,167,141,152,154, 35,150,
+137, 86,133,133,181,119,243,241,173,131, 93, 59,183, 78, 0, 32, 8,172,154,149, 39,151,166, 1,110, 65, 3,154,133,238, 60,119,
+223,224,228, 21, 50, 96, 23, 88, 44,213,223,216,115,211, 81, 14,223, 70,225, 23, 68, 12,235,195,241, 92, 90,202,221, 11, 17,127,
+133,157, 42, 77,227, 78, 32, 88, 79, 40, 21, 83,208,239, 89,158,236, 42,206,137,123,248,162, 47, 80, 46,190, 65,238, 28,111,237,
+ 38,101,148,205,172,188,233,154, 72,162, 56, 90,144,120,163,240, 37,165, 45,171,212, 4,190, 35,151, 41, 63,169, 31,216,168, 65,
+ 66,194,131, 7,134,226,194,229,198,172,251, 27, 41,165,124, 77,184,252, 59, 79,123,131, 3, 63,141,183, 91, 24, 17, 37,223, 62,
+ 58,179,100,171, 80,122, 5, 8,248,139, 5,150, 87,208, 16, 21, 17,209,171,237,195, 95,245,152, 62,118,160,116,233,150, 51,240,
+110,246, 70,124,230,141, 95,235,255,127, 62,132, 79,232,160,218,132,224,214,164,209, 67,241,254, 27, 93, 73, 78,177, 29, 69, 38,
+ 14, 68, 12, 12,121,189,183,114,208,128, 30,202,111,151,173,255,224, 96,228,201, 15,124, 66, 7, 53,206,184,190, 43,185, 58, 78,
+239, 22,111, 31, 1, 72, 64,197, 53,229,236,114,194,138,204, 0,202,197, 17, 3,149,155,250,236,236,145,129,251,231,188, 31, 60,
+103, 67,100,210, 74, 0,181, 0,100, 85,217, 0, 50, 34,221,166, 53,139,189,116,181,164, 96, 24, 6, 5, 6, 27,222, 28, 57,137,
+171,162,161, 84,173,158, 28,218,255,189,222,117,223,146,117,216, 53,147, 16,114,203,145, 6, 82,165,105, 24, 44,149,187, 28,240,
+111,214,197, 45,225,230,177, 32, 39, 77,163, 15, 12,114,243, 67,154,152, 88, 90,211,134, 90,165, 82, 5,184,184,184,180,236,209,
+163,135, 98,202,148, 41,226,246,237,219, 63,254,251,168, 81,163,196,103,206,156,209,125,251,237,183, 3,117, 58,157,169,168,168,
+ 40,202, 96, 48,220,167,148,114,142,254,134,187,187,251,123,131,122,183, 71,159,183,198,130,130,193,228,169,179,112,248, 80,228,
+112, 0, 47, 69, 96,185,176,204,204, 81, 19,103,233,218,135, 53, 23, 45,216,157, 12, 59, 79,209, 49,184,169,168,244,141, 79,189,
+143,253,186,228, 91, 0, 99,170,227,224, 36,204, 63,123,119,123, 13,224, 44,176,217,173, 94,110,181,220, 54, 15, 30, 56, 64,108,
+231, 40,142, 29, 59, 14,222,198,255,228,136, 45,222,205,135,158, 3, 97,116, 21,101,134, 16,128, 33, 0, 1, 1,165,124, 90,202,
+149,205, 47, 44, 18, 8, 33,172, 66,211,176, 59, 67,249, 97, 0,192, 19,102,179, 41, 43,238, 72, 77,242, 4, 0, 52, 77, 95, 79,
+164, 60,247,167, 23, 38,150, 21,235, 51,110,236,168,251, 2,246,121,246, 8,215,180, 56,253, 67,199, 46, 97,193,238, 33, 63,254,
+ 94,234,210,162,231,120,164, 21, 96,240,222,221,187, 6,123,133, 12, 56,195,128, 46,206,186,189,247,120,117, 92,114,153, 76,189,
+127,255,126,175, 30, 61,122,185,169, 67, 6,236,225, 9, 50, 25,138, 76,194, 51,153,132,216, 51,237, 12,205, 4, 75,178,114,253,
+165,217,190,177,233,167, 89,134,213,217,121, 46, 35,245,238,133,112,199, 13,198,250,200, 99,231, 60,205, 54,138,239,126,216, 58,
+203, 88,152, 53, 43,241,142,103,146, 82,211,112,138, 49, 43,238, 96, 77,158, 93,225,219, 84, 43,226,205, 61,124,180,245, 94, 31,
+ 63,241,243,214, 93, 59,181, 23,215,243,211,144, 71, 41, 89,244,247, 19,103,172,129,173,123, 94,202, 72, 75,216,197,219, 68,135,
+ 13,250,216,172,231, 75,223,142, 34, 39,117,163,159,251,190,241,254,192,126,131,134,194,205,197, 9, 22,107,105,131,147,191, 31,
+ 90,177,118,197,252, 48, 66,200,168,154,136, 67,142,218,167,173,157, 55,182, 62,192, 99,248,132,185, 51, 8, 33,219,107, 42,210,
+ 4, 8, 16, 80, 67,129, 69, 88,251,236,176, 54,175,122,124, 50,110,164,116,204,242, 83, 72,190,114,216,244,178,196,149, 74, 29,
+172, 22, 73, 68,239, 50, 12,235, 70,192,200,121,142, 75, 41, 36,250,213, 52, 53,181,218,225,168,140,235,187,146,189, 67,251,183,
+ 90,246,227, 47,179,163,110,196,182, 31, 51,124,160,202, 87,167,101,108,118,138, 11, 81,183,184, 21,107,182, 21,229,229, 23, 93,
+ 32, 34,250,149, 35,226, 10, 0, 40,133,255,162,133,223,121,233,106,201, 80,104,180, 99,236,167,179,240,237,215, 95, 56,213, 86,
+203, 97,182,240, 88, 25,153,170, 15,202, 95, 24, 61,103, 96,240,156,125,231, 51,214,143,156, 27,117, 19,128,241,153, 2,213, 85,
+138,241,171,239, 65, 33, 23,193, 85, 41, 1, 75,152, 63,137,171, 85,159,135,246, 27,213,175,222,244,111, 54,222,221, 0, 64, 12,
+ 64, 10,224,153,105,224,228, 29,212, 81,233, 82,107, 75,207, 17, 95,185, 42, 93, 53,120,103,112,207,160,179, 71,127,251, 61, 37,
+ 37, 17,126,141, 35,204,118, 59,127,162,184, 40,255,123, 67, 86, 92, 76,117,207, 93,183,110,221,161,189,123,247, 86,125,254,249,
+231, 98,157, 78,135, 95,247,157,208,117,126,125, 98,215,180,172, 92,111, 0,208,105,106,101,126, 56,172,239,239,135, 15, 31, 78,
+ 75, 75, 75,115,153, 55,111, 94,196,174, 93,187,154, 2,216,230,104, 94, 83,202,195,206, 81,112, 60, 5, 79,121,228, 22, 91,158,
+ 75, 84, 60, 85, 64, 16,244,233,222,161,165,104,233,254, 20,220, 79, 47,203, 18,153,152, 69,139, 22,173, 68,199,119,145,246,213,
+138,162,118, 83,123, 53, 13, 14,124,213, 87,171,198,165,168,155,144,138,197,110,111, 13,234, 11,185, 66,129,109,191,238,226,179,
+178,210,199,101,158, 93,184,209, 49, 67, 25,221,154,149, 75,188,106, 57, 75,192, 18, 2, 86,196,128,101,128, 18, 51,135,119, 63,
+152,240, 66,117, 70,161, 13,246,101,169,109,184,179,182,241,240, 65,131,222,244, 25,250,214, 16,202,178, 12,118,236, 62,208,231,
+151,109, 27, 50,157,124, 2, 55,112, 68,188,209,148, 30,147,234, 80,190,240,156,215,254,157, 27, 80,203, 69, 2,134, 0,185,197,
+ 28, 18,178, 76,152, 48,118,244,115,121,169, 9, 33,110, 31,247,127,165,251,205, 77,157, 59, 4,214,118,174,127,243, 65,193,221,
+ 17,255,140,254,225,104,106,195, 87,231, 44,104, 4,163,185, 20, 99, 62,157,137,156,244,196,246, 71, 14,237,107, 95,171, 97,247,
+251,196, 82,244, 69, 78,194,165, 3, 79,227, 52,155,205, 5, 61,123,244,118,241,246, 86, 43,214,175, 91,211, 53,175,208,132,188,
+130, 98,232,243,138,144,147,155,143,140,172, 28,164,165,103, 32, 53, 37,141,207, 99,245,136,140, 60,196,244,237,219,151,171,169,
+237, 38, 43,143, 27,143, 74, 80, 39,176, 37, 60,212,190,104,213,109, 68,157, 27,167,183,255,234,228,221,120, 97, 73,230,157, 47,
+ 28,225,112, 86, 7,126,247,230,219, 35, 62,124,115,240, 64, 81,195,250,190, 76,166,190,128,158,191, 20,157,191,116,241,178, 59,
+109, 59,116,108,220,183,103, 23,247,209,239, 13,233, 16, 23,159,218,110,219,206, 61,139,156,188, 26,110, 46,209,199, 77,168,105,
+ 61, 80,106, 26,174,127,173,223,136,129, 33,109,186, 34, 62, 62, 30, 15, 98,163,208,177,115, 15,244,232, 61, 8,150, 82,243,208,
+141,235,150, 70, 3,248,177,202,248, 45, 90,136,221, 10,220, 20,127,104,139,181,129, 34,128,130, 82, 10,187,169, 80,162,210, 52,
+243,112,175,215,197, 10, 0, 5,110, 5, 38, 26, 29,109, 19,186, 78, 1, 2, 94,178,192, 98, 88,105,207, 73, 35,123, 73,167,174,
+186,136,228, 43,191,152, 50,175,255,234, 89,241, 55,223, 22,111,197,166, 70,111, 15,250, 99, 71, 90,253, 10, 3, 66, 90,136,221,
+116,248, 84,237,227, 51,250,157,247,199,179,117,124, 53, 76,137,217,110,207, 74, 79,165,145,251,183,125,236, 90,187,217,119,133,
+201, 55,214, 62,141,147,212,239, 41,165,241,135, 45,153,215,247,222, 5,240,166, 58,120,168,250,252,149,219,147,221,221, 92,134,
+216, 57, 59,138,139,141, 59, 10, 10,108, 11,179, 99,182,101, 87,106,148, 72,229, 55,186,167,217,233,238, 36,193,167,235,239,195,
+108,225, 64, 41,133,151,155, 20,243,127, 75,130,136, 37,250,224,130,133,139,191, 26,104, 29,245,235,121,203,142, 25,187,253,218,
+ 2, 23,214, 83, 74, 75,158,106, 39, 0,150, 1, 84, 10, 49, 84,114, 17,156, 21, 98,148,205,220,250,151,184,250,225,179,166,253,
+ 70,247,171, 55, 99,222,150,184,159,103,174,185,115, 1, 64,124,229,249, 78, 85,217,233,226, 19,242,182,187,151,110, 97,255, 81,
+115,157, 19,243, 25,136,237,128,167,182, 30,249, 98,206, 92, 23,185,148,129, 66, 76, 93,110,197, 61,122,123,236,216, 79,122, 43,
+181,141,122, 27,211,239, 94,127, 86, 30,153, 76, 38,217,176, 97,195,196,102,179,217,250,254,164,249,237, 18, 83,178,186,125,253,
+197,100, 89,109,157, 26, 28, 79,113,251, 94, 74,253, 57, 95, 47,242, 61,248,251,165,200, 33,221,155, 28,245,241,241,113, 51,153,
+ 76,124, 77,242,189,176,176,104,235,150,221,199,166, 44, 91,188, 0,137, 89, 6,108,217,182, 19, 28,199,111,124,182, 40,251, 35,
+231,156, 57,115,188, 67, 66, 66, 36, 49, 49, 49, 89,148, 82,211, 19,161, 93,244, 69, 86,216, 56, 30, 4,128,167,155, 12,110, 78,
+ 82,176, 12, 1, 67, 72,181,249, 14,194,143,232,223,163, 29,164, 98, 22, 9,137,201,104,213,188, 41,188,106,185, 35,238,193, 35,
+100,102,101,101, 49,132,121,175, 78,183,217,243,109,165,230,153,233,103, 22,172,127,150,157,132, 1, 60,157, 37,248,102,103, 34,
+ 20, 82, 17, 20, 82, 22, 10, 89,217,191, 4,196, 65, 65,250,103, 59, 85,222, 13, 63,107, 26,220,108,206, 7, 31,188,207,180, 13,
+111, 67, 89, 86,132,172, 66, 27, 97, 8,240,201,216, 49,152,240,241, 40, 77, 98, 82,234,180,149,171,215, 76,113,210, 52,154, 95,
+146,117,247,107, 71,242,168,150,179, 4,179,183, 36, 64, 33, 43,179, 51,244, 21, 39,135,219,135, 39, 57,181, 77,123, 29, 58,153,
+ 45, 14, 44, 62,104,190,242,224,254,245,111,175,222, 74,138,162,148,230,171, 67, 6,192, 98,167, 40, 49,217, 16,147,108, 7,111,
+ 22, 99, 64,143, 86,104,234,230, 25,176,108,227,201,117,132, 16, 77, 69,253,124,146, 51, 53,238, 98, 75,247, 22, 67, 92,168, 65,
+121,107,193,238, 68,207, 58, 26, 23,120,187, 59,195, 75, 91, 11,141, 26, 5,194, 93, 37,134,139,130,133, 66,202, 50, 29,122, 12,
+ 65,247,238, 61, 77, 28,111,207,174, 73,249, 36,148,140, 28,212,171,253, 70, 2, 72, 24, 86,146,238, 83,167,129, 95,235, 30, 31,
+200, 91,118, 29, 1,155,197,252,153,147,119,208,233,146,204,216, 83,213,113,186,121,105,223, 29,249,254, 40, 73, 61,141, 12, 39,
+ 78, 95,180, 79,159, 49,227,118, 97, 73,254,162,146,140, 7,177,199, 79, 28,245,118,117,247,152, 49,125,214,220,176, 78,225,161,
+108,151,222,111, 73, 34, 35,143, 14, 6, 48,161, 58, 59, 9, 33,140, 66,221, 96,100,131, 70, 77, 39,125, 52,235,199, 58,105,185,
+ 22,184,107, 3,112,235,122, 20, 34,119,124,127,163,180,164,112,217,209,131,191, 77,250,226,155,229, 77,122,247,127, 19, 7,246,
+108,159, 64, 8, 89, 67,203,240,152,211,163, 65,135, 46, 77,234,132,172,247,110,168,246,168,204,207, 83, 22,115,230, 47,135,185,
+ 36, 31,117,181,110,222,206,141,235, 39, 81,134,128,242,128, 94,159,105,241, 12,236, 48, 40,231,222,233, 83, 53,105,231,107, 10,
+129,243,127,147,179, 26,180, 2,224, 5, 64, 15,224,234, 19,215, 40,255,142, 42,174,115,202,187,224, 90, 0, 44,229, 78,139, 10,
+ 84, 92, 63,237,126, 69,252, 88, 0,141,203, 57, 57, 0, 87, 0,228, 87, 43,176,202,181, 6,169, 84,121,255,112,253,199, 55, 92,
+155,206, 75,227, 13,142, 38,253,161,107,168,211,122,104,206,196, 81, 67, 20, 62,161,131,245, 25,215,119, 58,252,182,171,240, 13,
+208,186,213,118, 57, 52,238,147,207, 93, 63,126,175,175,211,221, 20, 99,113,108,146,177, 8, 10, 10,119,191, 90,162,144,238, 94,
+ 92,246,175, 11,103,184,234,154, 20, 20,166,221,250,173, 42, 14,181,139, 71,172,239,171,239,231, 91,140,134, 47,115, 98,118, 68,
+150,207, 11,250,135,111,216,144,217, 0,144,122,113,199, 99,129,162, 14, 29,248,170, 76,230, 54, 71,219,242,157, 90, 0,154, 87,
+103, 95, 94,137, 21, 28, 87,214, 31, 51, 12,129,193,204, 65, 46, 97,114, 2,115, 23, 60, 22, 87,231,233,135,239,217,232,118, 73,
+101,113, 85,117,163, 8,228, 21,219,160,146,139,224, 36, 23,193, 73, 33, 2, 83,174,176, 8, 33,170,239, 39, 53,237,251,209,192,
+250, 51,230,111,190,183, 97,198,234,216, 11, 0,238, 81, 74, 11,158,197,233,162,105,212, 70,234,234,185,248,131,207,151,168,206,
+221, 51, 64,235, 33, 69, 72, 29, 23,184, 42,165, 72,203, 43,155,211,159,158,107,134,217,234,140, 1, 31,206,113, 57,188, 99,197,
+ 25,119,223,166, 27,243, 83,111,142,171,238,217,119, 29, 60,243,202,163,228,204,110,191,254,180, 80,150,103, 4,146,242,120,228,
+ 21, 91, 96, 97,221, 49,243,139,175,100, 83,167, 78,233,129,210,220,180, 6,117, 60, 50,106, 92, 49,137,113,209,142,221, 71,255,
+ 17,210,162, 61,115,234,228, 73,220,140, 58,187, 67,127,123, 79,141,134, 7,107,215,174,109, 95,190,124,185,235,210,165, 75, 59,
+184,187,187,167,228,231,231,199,150,167,165,175, 87,157,144,220,125,135, 78,186,180,105, 26, 38, 82,200,196,112,119,146,192,223,
+ 91,137, 59,215, 78, 89, 24,144,223, 29,176, 80,231,163,174, 5,142, 2,250,156, 60,116,239, 20, 14,169,152, 69, 70, 70, 38, 2,
+ 3,234,249,116,239,244,154, 15, 15,130,149,107,215,126, 12, 96,253, 51,243, 29, 12, 88,150, 64, 41, 19,225,198,209, 53,133,165,
+198, 34, 43, 41, 31, 34,228, 41,151,246,220, 77, 13, 79,222,137,220,187,153,201, 40,176,227,126,102, 41, 73,205, 53,128, 1,133,
+151,171, 8, 60, 39, 66, 81, 65, 54,217,186,109, 43,174, 71, 93, 98, 8, 97,222, 3,240,181, 67, 47, 81, 12, 32,151,178,144, 75,
+ 89, 40, 36, 44, 74, 74,203,180,179, 58,100,192,102, 10, 20,138, 88, 81, 73,198,141,157,211, 29,170,223, 74,183, 38,155,214, 44,
+192,209,179,209,237, 78,197,111,108,174, 9,110,178,170,118,200,219, 75, 1,192,106,231, 97, 44, 41,132,202,150,132,118,117,115,
+ 80, 75,201,225, 94,190, 22, 55, 83, 69,170,234,134,179,242,163,119, 20,105,130,250, 77,184,113,238,208,118, 81,199, 65, 40, 48,
+112, 72,146, 89,160,148,137,202, 63, 44,238,220,188,140,204, 34,254,156,179, 69,217, 47, 41,254,112,141, 92,164, 37, 89,177, 39,
+ 1,248,254,203, 67, 92,223, 51, 99,229,103,107,135, 76,252,190, 75,171,238,239,147,251, 87,127,255, 28,192,169,106, 61, 88,110,
+ 30,162,135, 89, 28, 18, 18, 31,241,173,219,132,137, 46,157, 59, 17,250,251,201, 11, 27, 55,111,217, 82,218,235,245,247,228,157,
+219, 54, 99, 83,114, 45, 88,190,235, 14,141,201,160, 68,170,170, 37,118,192, 99,197,120,213,111,245,211,134, 13, 91, 7, 7, 5,
+248, 33,171,192,134,244,124, 43,206, 68, 63,192,198, 53, 83, 11, 11,178, 31,142,132,165,196,192,131, 43, 60,126,116,223,222, 49,
+227,167, 34, 40, 36,180, 78, 73,186,193, 25,192, 31,231, 30,242,252,136,175,191,254,206, 67, 84, 73,147,169, 0, 0, 32, 0, 73,
+ 68, 65, 84,165, 82,253,233,119,244, 89,233, 48,148, 24, 32, 85,186, 64,233, 82, 11,118, 59, 7, 27, 71, 81, 92, 92, 44,157, 54,
+254,157, 15, 29,121,126, 1, 2,106,224,137,117, 68,135,120, 17, 66, 14, 80, 74,251, 0,232, 2, 64, 90,233, 26,132,144, 3,229,
+194,239, 15,215, 83,167, 78,157, 62,111,222,188,152,138,176, 21,247, 43,194, 62,235,126,165,248,181,166, 77,155, 22, 50,127,254,
+252,111,194,194,194,182, 95,184,112,225,145, 67, 2,171,242,195,144, 74,111,247,127, 26, 54,105,214,183, 37,120, 17,235,235,229,
+132, 87,234,250,193, 77, 57, 92,161,109,254,166, 94, 36, 98,153,159,151, 78,147, 39, 22, 72, 32, 98, 68,198,154,136, 43, 25,235,
+114,116,213,218,141, 78,109,154,188, 34, 91,180, 59, 53, 33, 53,175,212,194,219,109,140,217, 88, 34,201,207,188, 47, 46,202, 78,
+116,118,241,110,200,154,139,244, 51, 1, 84, 41,176,164, 82, 41,179,108,193,151, 65,167, 78,159,223,176,223,201,165,208, 39,244,
+157,197,172,204,186,177, 66, 88, 17,242, 37,163,105,118,111,160, 84,174,156,210,176, 73, 7, 31,109, 64,107,215,203,135, 55,196,
+ 59, 32,207,217, 41,211,231, 60, 22, 87, 54, 83, 30,190, 91,179,191,184,179,199,233, 69, 21,226,106,155,126,232,219,221,219, 7,
+104, 14,239,151,228, 85, 91,128, 96, 79, 27,246,193, 39, 18,194, 0, 12, 72,217, 60, 46,202,103, 19, 66,148,203, 63,105,214,103,
+236,235,254, 51,191,221,114,111,227,244,213, 49, 21,226,170,218,204, 43,102, 21,183, 93, 74, 77, 89,137,241,183,235,140,239,213,
+ 86, 84,199,219, 21, 10,169, 8, 5, 6, 59, 10,140, 28, 82,245,102, 60,204, 52,224,246, 67, 61, 56, 83, 17,222, 25,251, 79,230,
+231,239,198,119,115, 36,127, 14,158,136,238,250,221, 55,211,101,121, 6, 32,167,132, 67,122,158, 25,105, 57, 38,164,230,152,160,
+144, 0, 97, 93,223,146,157, 59,244,115,247, 6,117, 60,126,170,105,101,202,186,117,212,168, 14, 25,112, 57, 45, 67, 31, 86, 63,
+ 32, 8,204,161,189,141,106, 53, 29,162,205,189,185, 35,221, 81,142,195,135, 15,231,248,250,250,170, 87,173, 90,165, 95,188,120,
+113, 72,237,218,181, 27,165,164,164,236,243,244,244, 28,254,253,130, 89,199,190, 88,240,147,167,197, 90,234, 18, 28, 26,206,138,
+196, 4, 49, 87,142,149, 30,217,245, 99, 6, 45, 50,206,172,142, 91, 42,147,213,146,203,197,176,217,120,176, 44, 11, 95, 31, 53,
+108, 28, 69,137,193,128,129,189,187, 33,230,238,125,156,191, 20,101,231,108,246,229,213, 55, 28,128,136, 97,160,148,137, 80,106,
+ 44,178, 38, 93,218, 88,247, 37,181, 73,148,167, 20,209, 15,141, 48,150,218, 97,181,241,240,215, 72,145,151,157,140,117,223,111,
+196,205,107, 87,209,174,115, 31, 44, 88,185, 5,227, 63, 28,226,240,170, 79,134,144,114,113, 37,130, 92,202,162,212, 86,214, 36,
+ 44,155, 55,149, 13, 14,106,140,142,125,134, 57,236,210,114,118, 82,160,216,100,133,202,205, 7,209,199, 55, 42, 15, 30,191, 50,
+249,187,229, 63,125, 82, 90, 76,145,122,239, 34,194,220,115, 81,223,211,130, 43,201,206, 56,154, 92, 7, 1,254,245,192,136,246,
+ 56, 86,134, 98,247,237, 87, 55, 27,184,175,168,113,104, 63,119,255, 64,200, 36, 44,100, 18, 6, 82, 9,131,135,247, 98,240,203,
+230, 13,119,237,114,229,144,248, 91,123, 44, 47,154,208, 37,153,241, 57,114, 77,224,164, 7,215,142,198,182,237,247, 49,220,188,
+235, 52,169, 73,252,121,115,103,148,114,118,155,237,237,225, 99,148,125,123,190, 38, 10,107, 27,174,138,186,151,143,111,127, 62,
+201,157,139,220,156, 33,145,185, 42,116,225,163, 61, 28, 17, 87, 30,117, 66,215,110,218,252,235,224,122,181,189,241,251,149, 4,
+ 92,139, 47,128,139,179, 43, 68, 42, 31, 4,118, 24,225,122, 59,114,233, 0, 99, 78,201, 86,177, 88,254, 94,203, 54, 17,160,148,
+226,126,108,108,126, 65,129,211,159,218,102, 70,196,172,157, 53,243, 31,221,213, 94,154,202,111,238,240,175, 31,128, 94,253, 6,
+227,248,169, 29,120, 20,127, 31, 60,165,224, 41, 64, 41, 69,110,142, 62, 15, 12,243,179, 32, 9, 4,252, 85, 34,235, 89, 58,164,
+ 66, 56, 61, 41,136,158, 20, 90, 21,223, 43,194,205,155, 55,175,207, 19,222,183, 62, 79,241,202,253, 41, 92, 69,252,249,243,231,
+127, 83,233,239, 14,105, 29, 81, 57, 9,121,214,195,169,155,245, 15,147,138,157,246,253,176,240, 19, 38,187,208, 6,133,148,133,
+170,118, 61, 52, 24,249,137,242,237,118, 94, 72, 47,117,199,254, 3, 63, 21,219,168,253,176,163,226, 74,202, 56, 29, 89,180,226,
+ 39, 73,253,186, 90, 50,103, 91, 98,188,217, 86, 54, 77,194, 82,106, 22, 37,221,140, 84,166,198, 30, 55,195,110,219,196, 74,101,
+ 45, 64,121,245,179,248,234,120,187, 33,188, 67, 23,101,135, 14, 29,148, 71, 79,158,159,123,240,224,193,143, 81,190, 67,189, 79,
+139,132,227, 45,218,246, 10,210,250, 55, 81, 22, 91, 8,164, 98,198,209,220,230,190,251,102, 14,106,171,229, 48, 89,120,252,115,
+245,161,226, 14, 78,191,127, 83, 89, 92,105,124, 27,248, 74,100,170, 63, 12,245, 61, 13,105, 87,183,118,170,162,160, 40,151,124,
+ 18,210,119,220, 16,255,153,223,109,185,183,105,218,170,152,243, 0,226, 28, 17, 87, 0, 64,211,163, 77,174,181, 67, 58,236,219,
+176,112,230,161,109,203, 58, 50,160, 30,141, 2, 3, 68, 93,187,118,147, 53,107, 21, 46,211, 23, 82,220, 73,208,195, 92,146,143,
+206, 97,141, 16,185,123, 51,151,149,153,226,208, 28, 15,125,126,145,119, 29,157, 6, 9, 57, 60,146,245,101,194, 42, 85,111, 68,
+ 90,174, 9,249, 37, 22,180,170,167,129,193, 96,241,126,238,202, 68,201,129,139, 23, 47,134,189,218,190, 43, 94,127,123,116,208,
+129, 93,155,175,104,130, 7,125,150, 21,179,235, 87, 71,226,239,216,177,131,211,106,181,241, 89, 89, 89, 17, 11, 22, 44,208, 7,
+ 6, 6,250,205,153, 51,103,186, 86,171,245, 24,242,250,235, 41,125,122,247,222,242,209,167,179, 59,172,252,242,167, 87,192,176,
+ 89,224,237,135,244, 38,110, 46,213,199,154,170,227,118, 82,202, 60,196, 44, 3,134, 16,184, 57,171, 32,147,138,192,218,121,240,
+ 28, 7, 55, 23, 37, 98, 98,239, 34,251,206,249,209, 5,143,142,236, 0, 22, 86, 43, 88, 88, 22, 80,201, 69,143,203,137,186,233,
+235,137,168, 98, 50, 57, 0, 16,150,213,103,221,248,173,174, 3, 9,200,219, 57, 10,179,149, 67,169,149,131,152,165, 40, 46,204,
+198, 23,211, 38,225,181, 30, 3, 49,119,216,120, 20,154, 89, 92, 79,182,192,110,179, 17, 71,243, 37, 45,207,130,158,205, 61,144,
+ 83,108, 71,190,129,131, 68, 84, 86, 95, 14, 94,203, 69,188,161,102, 11,222,120,158,194,211,195, 21,202, 92,160,215,167,187,241,
+ 90,115, 95,156,220,187, 70,116,254,202, 45,252,243,219,239,161,238,255, 42,214,223,168, 15,153,139, 31,100,174, 50,216,104,205,
+182,229,163, 54,209,167,215, 79,239,238, 84,223,127,138, 74, 42,150,148,121, 25, 83, 30, 97,243,134, 31,211,236, 98,244,205,187,
+188,165,248,101, 53,254, 98,134,213,185,122,120, 65, 38,102, 64,237, 22, 67, 77,227,103,166,103, 53, 89, 48,119,202,240,179,151,
+ 6, 78,111,221,115,140,244,212,238,101,165,177, 87, 14,140, 53,100, 56,237,242,143,240,140, 2,224, 81, 77,167, 66, 92,125, 66,
+126, 92,189,126,203,155, 62,222,106,236, 62,126, 19, 27,214,253, 0, 93,112,119,196, 95, 59, 10,191, 22,253,225, 84,175, 19,196,
+206, 59, 70,170, 24,113,240,168,137, 51,250, 55,111, 25,142,139,231, 78, 32, 91,159,186,142,210,184, 63,173, 70,206,185,119,250,
+ 20,105,209, 66,237,246, 48,237,241, 28, 44,134,181,250,240, 60,162, 59, 91, 41, 30,197,223,199,205,107,151, 90,240,156,228,177,
+151,186,192,173,192, 68, 31, 8,115,176, 4,188,124, 84,167, 67,170,243, 58,213, 80,204, 29,168, 74,100, 61,121,159, 16,114, 96,
+234,212,169,211, 1,208,169, 83,167, 78,175,184,158, 55,111,158, 9, 64,181, 14, 1, 81,229,135,171, 42,128,186, 89,255, 48,169,
+ 72,185,111,195,242, 25,138,109, 87, 56, 44, 56, 28,141,208, 64, 13,196, 98, 22, 42,185, 55,142,199, 20,226,194,153,125, 37,209,
+ 81,151,205,172,152,155,237,136,184,146, 16,197,161,249, 75, 87, 21, 4, 5,248, 73, 87, 28,202,188, 97,182,241,132, 82, 34, 38,
+148,176,148,242, 46,105,177, 39, 26, 23,145,156, 48,154,230,200, 10, 56,194, 91,237, 20,137,217, 22, 16, 2,180,141,232, 32, 63,
+122,244,119,197,191, 58, 44,177,123,237,134, 45,148,119,146, 13,144,136, 24,168,221,164,112,116, 57,141,151,155, 20,243,118, 38,
+ 66, 44, 98,244, 29,156,126, 95, 92, 89, 92,121,251, 54,240,117,118,113, 1,207, 19, 16, 66,158, 39,131,149,139, 39,132,244,153,
+ 56, 36, 96,230,226,109, 15, 54, 79, 93, 25,115,206, 81,207, 85,101, 20, 38,223, 46, 0,240, 89,197,181,107,237, 16,183,171, 81,
+151,187,184,186,171, 23,180,127, 99,102,173,146, 66, 11,186,132,151,137,171,155,103,127,125,203,152,121, 55,210, 81,110,171,157,
+ 71, 82,150, 17, 9,153,198,199,222,171,212, 28, 19, 20, 82, 22,102, 11,247, 66,149,201,169,180,244,199,200, 67,123,123,218, 56,
+ 68, 52,110,209, 1,175,143,156,226,118,108,239,134,159, 52, 65,253,204, 89,177,251,246, 59,194,145,158,158,110,242,240,240,184,
+ 84, 84, 84,212,119,203,150, 45,249,173, 90,181, 98,221,220,220,242, 0,200,174, 95,187, 38, 59,180,243,231,172,162,162,162,241,
+ 86,171, 53,186,218,188,246, 10, 82,149,138,109,111, 82, 59, 59, 76, 19,210, 83,148, 95, 80, 54,154,146,152,154, 1,147,193, 8,
+ 27,199, 35, 61, 35, 27,165,165,102, 20, 22, 21,161, 93,235,186,223,159,182, 4,207,112,214, 52,156, 94,156, 21,119,224, 89, 30,
+ 44, 67, 41, 7,165, 76,244,175,114,194,115, 94,171, 86,175,134,135, 83,217,136, 16,203, 18,228,149,216,144,145,103,197,156,169,
+227, 29, 29, 98,167,118, 59, 69,169,149,131,217,202,161,208,198,193,203,183, 22,190, 91,249, 11, 18,245,102,236,141, 42,196,195,
+ 12, 35, 66,235, 59, 3,188, 99, 5,148,101,197,250,129,111,188,247,167,223,151, 43,157,204, 18, 86, 4,149,188, 76, 0,169, 27,
+247, 31, 77, 8, 83,196,138,197,165,233, 55,126,221,251,116, 11, 1,169, 84, 10, 95,111, 15, 88,109, 28,142, 92, 78, 66,239,206,
+173,241,106,235, 22, 32, 34, 9,162,138, 66, 33,115,113, 2,101, 9,236, 60,133,197, 86,179, 50,165,143,221,145,229, 29, 50, 96,
+202,141,139, 71,127,232,214,123, 16,242,115, 50,176,105,237,138, 34, 27,199,245,206,185,177, 43,243,101, 53,252, 78,154, 38, 94,
+ 74, 23,215,239, 90,132,119,133,169, 48, 19,250,180,132,189, 53,229, 48,100,221, 40, 0,176,202,110,181, 76,103, 24, 2, 98,183,
+192,144,241, 96, 15, 0, 30, 8,173, 54,190,202, 59,112,212,215, 75, 86, 13,245,243,243, 67,228,185, 59,152, 55, 99,204, 13,165,
+210,185,174,198,195,213,149, 15,108,134,132,219,191,195,163,110, 1, 92, 53, 1,186,222, 93, 70,234,122,244, 26,136,152,155,209,
+ 88,190,240,171,203, 6, 70,185,224,169, 89, 84, 54, 97,253,241,208,161,135,127,135,175,194,218,119,133,197,102, 71,235,182, 93,
+112, 35,234,242,152,252, 71,199, 38, 10,221,191,128,127,151,200,114, 48, 92,159, 23,252,157, 62, 40,155,171,229,229,168, 7,107,
+222,188,121, 49,243,230,205,171,210, 35, 86,173,192,122,150,184,250,121,217,116,197,150,203,118,220, 77, 44, 64,183,150, 62,200,
+ 72, 79,195,129,109,223,243,160,128, 84, 46,205,178,219,249,163,165, 12,102,228, 95,217, 93, 84,157,184, 18, 83,217,254,185, 11,
+150,222, 9,109, 28,192,174,140,204,190, 96,180,112,148,130,136, 8, 32,230, 41, 17,129,145,171,120,222,214, 16,156,135,163,174,
+ 38,106,231,105,121, 98, 0, 86,142,130,130,255, 67, 38,217,236, 60, 56, 30,224, 41, 80, 17,182,122, 1, 84,182,210, 75, 33, 97,
+115, 2,243,202,230, 92,237,172, 16, 87,126, 13,124,157,157, 93, 32,151,176,160,229, 97,107, 40,174, 20,139,199,134,244,249,228,
+205,128, 89, 75,126,185,191,101,242,138,219,231,188, 2,123,169, 69,114, 55, 15,109,232,176,242,222, 14, 0,199,155,210,175,111,
+ 61, 94, 19,238,114,193,181, 67,229, 29, 88, 55, 35, 62,106,118,215, 94,111,225,240,238, 77, 21,226,234,144,163, 60,158,238, 46,
+153, 81, 49,137,245,173,212, 13,137,153, 6,164,230,152,144, 85, 80,166,119,189, 92, 37, 72, 77, 73,130, 74, 37,117,184, 19,243,
+ 14, 25, 56,150, 18,140, 0,197,214,172,219,187,151,196,199, 31,182,144, 22,163,251, 28, 63,188,107,254,163,135,247,199,180,233,
+ 60, 4,161, 29, 95, 71,228,150, 5, 83, 1,236,119,148, 55, 47, 47,175,216,221,221,253,236,103,159,125,214,111,253,250,245,121,
+ 0, 68, 69, 69, 69,202,129, 3, 7,250,230,230,230, 78,162,148, 38, 57, 36, 38, 69,248,121,236,152,177, 29, 7,246,239, 75,108,
+ 68, 98,217,251,251, 37,145,141,227,200,252,127,188,193, 69, 93,187,194,216, 56,142,124, 48,184, 29,127,229,210,121,102,218,168,
+ 62,220,107,175, 6, 35,250,110,162,247,200,161,131,230, 2,120,250, 91, 20,229,211,222, 30, 57,177,172,140,240,252,227, 57, 87,
+ 30, 78, 98,140, 93,125, 23,170,199,243,134, 68,232, 18,234, 81,163, 54,194,198,241, 48, 91, 56,152, 45, 28,140, 22, 59, 78,221,
+206, 71,124,122, 9, 10,140, 54,148, 90,203,196,138,213,202, 3,112,172,209,170,188, 21,131,186,201,128, 77, 43,230, 77,103, 15,
+ 92,203,133,132,101,225,172,148,240,114,105,153, 32, 92,185,120,166, 40,176, 81, 99,116,234,241,182,236,217, 30, 44, 30,103,174,
+222,199,247, 59,111, 96,233,244, 33, 16, 49, 4,227,230,254,138,119,186, 55, 4,207, 83,100,220,143,130, 79,195, 87, 33,147,202,
+203,188,215, 86,222,145,186,211, 10,229, 43,107, 41,165,209,153,183,247,108,240,109,216,254,219, 71,215, 15,168,204,102, 43,111,
+ 21,169,250,233,111,236,143, 47, 15, 27, 4, 64, 2,160,148, 82,122,183,166,141,176,139,111,144, 59,207,217,135,212,246, 15,250,
+252,253,137, 95,169,149,174,158,248,109,227,114, 10, 49,179,173, 70, 25,197, 89, 25,148,205,233, 42,228,203,219, 31,194, 16,148,
+219,230,193,115, 86,182, 58,239,149, 95, 72,167, 73, 13, 27, 5,225, 82, 76, 42,190,157,245,209, 13,115,118,194, 8,139,179,251,
+ 72,107, 73,198,132,198, 33,161,208,104, 60,145,149,145,129, 14,125,187,163, 91,247, 30,136,185, 25,141,175,191,248,236, 50, 99,
+ 44,237,231,136,215, 22, 0,220, 27,182, 15,110, 18,218,114,100,253, 70, 77,161,207,205, 67,189,192, 38, 8, 12, 9, 29,233,222,
+176,253,186,252,184, 51, 49, 16, 32,224, 63, 7, 7, 1,244,126, 82, 8, 61, 41,146, 42,121,160,170,194,213,202, 28, 21,225,159,
+ 38,224, 42,207,201, 2,224,208,246, 71,162, 39, 21, 99,197,181,186, 89,255, 48,137, 88,177,239,167, 37,211, 20,155, 47,219,113,
+ 47,169, 16,221, 90,249, 32, 39, 39, 23, 71,118,174, 53, 16,198,222, 59,243,198,254, 40, 71, 83, 67,225, 27,160, 21,113,226,221,
+ 51,190,250, 42,178, 93,155,150,182, 85, 71, 50,206, 20,219,192,243, 34,145,152, 45,229, 69,132,165, 34,202, 80,177, 76,161, 20,
+121,189,210,218, 21, 15, 47,237, 85,169,131, 39, 27,245,181,238, 82,122,234,153,155,109,218, 43,189,248,114, 28, 69,101, 23, 21,
+ 5, 96,231, 40,104,197,178, 99,187, 99, 2,139, 33,192,166,227, 25,250,224,162,133,143,197,213,150,156, 50,113,229,226,236, 2,
+153,164,108, 34, 48,117,120, 45,216,191,196,213,130,177, 33,125, 63,121, 59, 96,214,178, 29,241, 91, 62, 91,126,251, 44,128,251,
+ 34,185,155,199, 79,235, 22,203,180,181,228, 96, 0, 20, 24, 56,188, 53,252,249, 94, 28,157, 52, 1,111,180,104,215,103,102,167,
+222, 67,112,232,183,159,184, 91,231,119,213, 72, 92, 1, 64,159, 78, 45,126,159,247,221, 50,223,207,166,207,150, 73,197, 20,197,
+ 38, 27,100, 18, 6,106, 87, 41, 60,148, 12,206, 70,238, 42,109, 23,164, 62,226, 8,151, 71,155,119,156,253,107,215,158, 55,109,
+198, 52,246,167,181,107,255,169,109,210,239,112,250,173,125,247,105,244,143, 54, 0,159,169, 67, 6, 61,208,249, 94, 93, 92, 59,
+184, 61,220, 60,117, 77, 60, 3,251, 57,229,220,219, 87,226,168,173,249,249,249, 41,117,235,214,125,176, 98,197,138, 70,227,198,
+141, 43, 29, 55,110,156,175,201,100,218,225,168,184, 2,128, 86, 45,154,134, 78, 24, 55, 90, 44, 21, 49, 16,139, 25,212,243,237,
+109,183,218,202,246,254,105,211,164,193,227, 18,246, 58,128,219,143,178, 49,245,251,227, 40, 40, 41,133, 72,196, 74,158,197,155,
+124,249, 41,251, 92, 17,252, 65, 92, 57,201, 69, 48,149,214,100,171, 33, 66,173,118, 30, 54, 59,143, 82, 43,135, 82,139, 29, 38,
+ 11, 15,147,133,127, 92,252, 89,134,192, 86, 86,222,107,236, 98,165, 20, 69,245, 26, 54, 68,253,146, 66, 40,229, 12, 20, 82, 49,
+ 20,210,178,119,158, 35,215,242,144,104, 41,168,150,131,231,121, 88,203,189, 82,165, 86, 14, 42, 89,217,251,156,197, 86,182, 42,
+ 55,237,238,169,173, 89,241, 87,222,244, 14,108,205,250, 6,134,163, 84,230,144,153,110,148,210,163,132,144, 46,132,144,206, 0,
+104,237,198,109,249,189,187,119,161, 79,239, 62,198,148,155, 7, 20,132,144,118,229, 85, 31,148,210,115,132,144,106,247,192,114,
+246,105, 28,193, 83,108, 34,128, 2,148,191,163,241,169,173,108,255, 90,223,134, 17,157,122,177,117,253, 3, 97,177,113,216,188,
+110, 41,189,116,114,215,100, 67,198,189,155, 53, 73, 75,109,157,134,200, 72, 73, 26,199, 67,244, 29,202,132, 21,104,217, 41,101,
+ 6, 39,239, 6,157, 21,238,126,207,244, 90,186,185, 53,119,110,210,170,163,111, 82,142, 21,135, 15, 31,134,177, 40,251, 43,139,
+165,216,136, 82,186,225,196,158, 31,223,123, 99,244,151,206,173, 91,182,128,155,139, 10,181,220, 92,112, 45,234, 2, 22,204,157,
+126,153, 49,150,246,211,235, 99, 29, 30,206,100, 40,243,207,190, 67, 70, 50,121,185,249, 88,242,205,231, 24, 51,249, 27,116,233,
+247, 46,115,255,238,141,127, 2,232, 47,244,233, 2,254, 93,158,171,167,120,178,244,149, 60, 79,127,186,174, 36,138,170,186, 38,
+229,215,150,167,112, 88,158, 16, 85,150, 39,238, 91,158,224,187,241, 66, 30, 44, 22,226,253,235, 23, 79,149,239,185,205,226, 81,
+ 90, 62,186,181,242, 65,182, 94,143,131, 91, 87, 24,108,188,121, 64,118, 13,196, 21, 0,136,108,232, 89,219,215,123,202,199,111,
+246, 35, 59,110,229, 70,167, 51, 74, 78, 38, 23, 49,172,168,132, 21,203,141, 76,137, 73,202,138, 40,203, 80,171,149,109,214,101,
+210,165,107, 54, 67,211,220,228,216, 25, 78,154,156,186, 46, 62,141,182, 21,101,220, 93, 90, 21, 47,199,217,145,149,147, 7, 31,
+119, 37,178, 10,108,176,113,180,138, 48, 20,132, 16, 40,101, 44,140,134, 34,240, 92,245, 83, 8,148,206,154, 3,193, 69, 11, 19,
+ 42,196,213,214,156,178, 97,193,202,226, 74, 46, 97,193, 16,226,176, 7,139, 16,162,248,110, 92, 80,159,207,134,150,137,171, 73,
+ 75,111,158, 3,112,159, 82,154,171, 13, 29, 6, 79,103, 9,198,126, 31, 11,149, 74, 2,119,165, 4,162,231, 56,200,200, 73, 19,
+240, 70,243,118,125,214,117, 25, 56,134,217,187,225, 59,251,221,155,231,135,214, 68, 92,113, 28, 71,108, 54, 27, 58,181,109,146,
+118, 45, 54,241,204,220, 47,102,181,111,221,229, 77, 89,187,134,222, 48, 90,236, 72, 75, 78,193,217, 35, 59, 74,125,220,197,167,
+ 27,212,241,200,176,217,108,213,118,224,249,126, 86, 99,105,129,217, 44, 18, 73, 84,131, 7,246, 34, 81,209,209, 91, 52,193, 3,
+118, 3, 36, 6,132, 15, 2, 65,255,102, 65,254,200, 7,133,165,212,100, 86,139,164, 53,158,152,156,148,148,116, 98,249,242,229,
+193, 98,177, 88, 19, 25, 25,201, 27, 12,134,223,106, 18,223,110,183, 83,134, 16, 18, 29, 95, 98,117,115, 18,147,122, 26,153, 72,
+161, 98, 96,178,208,199, 66,235,246,163,108,108, 59, 28,131,248,212, 2,104, 60,228,140,143, 59, 3,187,157,203,127,158, 6,133,
+101, 24, 40,101, 98,168,228, 44, 84, 50, 17, 20, 50, 17, 44, 54,199, 55, 10, 39,160, 9,103, 47, 94, 11,106,215, 40, 8,209, 15,
+ 13,184,147, 98,129,217,202,129,130,130,148,123, 25, 93, 21, 98,100,103, 36,129,167, 92, 82, 77,237, 19,177,162,146,238,253,254,
+ 60,161, 93,169,114,178, 73,101, 12, 84, 18, 73,181, 28, 54,142, 67,219, 22, 13,224,174,169,141,169, 11,119, 1, 0, 86,204,124,
+ 3,106, 23, 22,219,126,166,200,190,189,119,148, 58,120,192,183, 41,183, 79, 77, 77,189,121,252,141,206,109,188, 89,141, 60,223,
+129,106, 68, 6, 0,224, 1, 28,162,148,218,253, 26,133, 63,236,209,189,135,206,206,115, 25,148,210, 51,229,129,164, 0,218, 19,
+ 66,186,162,154,125,228,202, 26, 99,242, 83,244,213, 43, 94, 86, 59,197,241,243, 55, 90, 71,188, 26, 10,139,141,194, 80,106,197,
+181,232, 27,216,251,219,102,227,221,219, 87, 71, 24, 51,239, 57, 92,151,178, 82, 18,143,165, 38,222,239, 61,108,204,116, 89,243,
+176,206, 31,238,219,190,234, 13, 90,238,194, 34, 4,168,251,234,176, 43,222, 77, 6, 52, 20, 57,121, 51,176, 22, 80, 67,118,194,
+197,170,120, 10, 10,156,140,247, 98,175, 23, 60,202,180,184,137,220, 26, 64, 44,113,122,159,184,250,254,192,202,148,211,117,175,
+190,231,124,234,252, 37,196, 94, 63, 7,173,167, 10, 9, 15,239, 27, 99,111, 70,173, 53, 64,242, 13,213,199, 58,188,232,200, 43,
+168,163, 38,160, 97,147, 78,206,110, 94,216,181,109, 45, 10,243,115,151,156,136,220, 53,169,115,223,225,240,243, 15,234,228, 21,
+212, 81,163,143, 61,149, 5, 1, 2,254,255,112,181,154,235,151,193,249, 82, 33,122,122, 71,107,151,123,122,215,193,111, 31, 15,
+199,236,121,223,227, 86, 92, 18, 14,111,255,161, 92, 92,237,189,232,160,160,120,124,218,118,113,214,253,199,123, 89,141, 12,175,
+133,145,143,223, 41, 61,171,142, 60, 99,115, 58,128, 67,207,226, 4,128, 82, 67,209,219,147, 62,255,114,101,219, 87, 91,233,218,
+117,238,238,108,231,228,160, 79, 12,137, 80, 0, 94, 42,138, 71, 55,143, 21,232, 83,239,222,227, 77,249, 99,159,197, 73, 8,145,
+205, 30, 25,120,126,206,192,224, 57, 59,207, 91,118,156,230, 62,120,175,115,120, 3,141, 88,230, 84,222,125,145,178,255, 24, 2,
+169,148,173, 82, 93, 84,197, 57,127,108, 80,239,201, 67, 27,206, 94,190, 51,126,107,185,184,186, 71, 41,205,173, 8, 35, 97, 89,
+184,168, 36,112, 81, 74,224,174, 18, 87,203,249,167,206,207,187, 81,207,150, 21,226,106,163, 99,226,170, 10, 59,163, 6, 14, 28,
+ 24,250,209, 71, 31, 73, 63,251,176,207,233,211,151, 98, 31,254, 18,249,107,215,188,220, 34,111,142,227,160, 82, 73, 51,195, 27,
+121,254, 30, 80,199, 35,237,214,173, 91,252,241,227,199, 75, 57,142,187,246, 44, 78,186, 99, 7,231,217,100,192,174,168,235,183,
+134, 55,111, 22,140,149,223, 47,106,116,255, 97, 98,163,248, 71,201,208,233,116,208,233,116, 40,178, 43,241,240,242,109, 24,139,
+115,247, 39,198,238,181,214,244,217,199,142, 29,251, 90, 65, 65,129,100,229,202,149, 61, 59,116,232,176, 71,171,213,190, 54,122,
+244,232,139, 63,254,248,163,201,145,103,143,190, 30,179,243,167,141, 91,198,188,241,122,127,137,217,206,112, 87,239, 23,219,228,
+108, 41,241,247,117, 97, 47, 68, 39,240, 27, 14,222, 70,129,153,133,191,206,133,105,228, 3,114,237,194, 46,254,244,189,155,151,
+121, 17,153, 94, 19, 59, 31,139,206,146,178, 45, 59, 84,229,251, 77,169,100, 34, 88, 57,199,242, 8, 0,196, 86,229,152,137, 99,
+ 63,124, 20, 28,210, 98,236, 27,239,141,145,180, 14,168,139,171, 15,138,224,225, 36,134,183,187, 20, 57,250, 92, 68,237, 89,108,
+ 47, 72,189,181,150, 17, 99, 94, 77,211,179,242, 86, 12,234,198, 3,199,172, 92, 60,157, 61,114, 45, 15, 82, 25, 3,149, 84,198,
+ 43,149,108,181,118,230, 23, 20, 95, 92,184,124,109,216,187,111,245, 71,207,176,186, 56,123, 51, 13, 60, 45, 27,170,231,248, 50,
+111,157, 62,118,175,101,194, 91,245,206,143,238, 23,160, 46, 52,233, 27,204, 78,180, 94, 38,132, 48, 21, 59,135,255,169, 44, 81,
+122,132, 16,194, 2,104, 13,160, 43, 33,228, 44,165, 52,226, 9, 59,252, 0, 4, 3, 72, 40,127,129,225, 29,120,118, 98,181, 83,
+ 36,100,153,112,225,194,121,152,141, 69,136,143,127,128,223, 15,239,137, 42, 46,204,221, 32,183,211, 93,198,156,123, 37,142,214,
+ 35, 0, 48,241, 37,159, 45,156, 57,138,111,209,190,123,247, 94,131, 70, 74,167,124,189,206, 45, 62,254, 1,199,243,128,202,191,
+167, 84,231,175,106,204, 80, 43,205,189,187,207,146,124,109,255, 49,142, 97, 38, 87,197, 73,233, 41,187,147,119,195,181,231,207,
+159,254, 92,174,109,129, 70,189,167,247, 78,187,177,175,183,119, 80,119,120,214, 15, 71,250,141,189,184,121, 97,219,145,107, 28,
+ 55, 75,206, 33,165, 68, 31,103,168,137,157, 0,192,151,114,131,131,155, 71, 48, 38,179, 5, 49,215, 46,166, 20, 60, 58, 59,251,
+142,202,121,208,171,221,134,250,213,111,252, 42,147,114,239,214, 96, 0,223,215,132,243, 69, 32,112,254,111,114,254,221, 32,122,
+250, 27,172,184,244,234,205,123,178, 94,239,127,131,232,152, 4, 28,251,109, 85,141,196,213,191, 11,185,177,187,162, 0,180,212,
+132,188,217,239,210,213,232,121, 77,154,183,241,224,249,127, 45, 71,162, 60,207,222,188,122,206,144,155, 24,157,110, 55, 27, 62,
+203,188,249,107,181,251,183,140, 30, 80,175,195,156,247,203,118,104,159,178, 91, 23, 98,231,182,177,145, 98,137,158,128,160,252,
+127, 16, 66,192, 48,101,223,109,118,155, 35,203,171,188, 63, 25, 28, 56, 98,197,174,248,173,159, 44,185,121,182,194,115,245,135,
+ 78,215,104,133,139, 82, 2, 23,149, 24, 42, 23, 9,216, 26,166,133, 84, 44,255,176, 83,223,247, 29, 22, 87, 85, 65,175,215,223,
+ 32,132,220, 93,180,104, 81,171, 53,107,214,212,159, 60,121,114,210,218,175, 71,255, 4, 0, 71,142,148,141, 8,222,187,119, 15,
+ 43, 86,108, 55,151,150,150, 62, 48, 24, 12,151, 41,165,213,122,156, 56,177,120,218,198,181,171, 27,101,246,121,189,101, 29,255,
+134,112,243,110,136, 48, 93, 67, 20, 24,109,136, 73,201,195,195, 7,215,113,251,226,129, 91, 82, 94, 50,185, 38,246, 14, 25, 50,
+132, 85,171,213,109, 8, 33,225,205,155, 55,111,220,191,127,255,188,180,180,180,144,132,132, 4, 94, 34,145, 20,205,153, 51,231,
+218,156, 57,115,170, 29,123, 43,206,186, 51,205,201, 39, 36,114,201,210, 31,166,126,248,193,123,109,134, 12, 30, 32,182, 51,206,
+252,141, 4,179,125,233,206, 88, 18,226,175,102, 66,164, 70,114,241,212, 94, 62,246,198,229, 75, 28,143,111, 75, 50, 99,207, 62,
+111,185,205,200,183,160, 75, 51, 15,152, 74, 57,148,218, 40,172, 28, 30, 15,161, 57,130,242,243, 20,103, 42,116, 77, 86,199, 76,
+250,112,118, 72,171,136,183,218,245,124,135, 81,212,114,198,233, 3,235,105,194,245,200, 93, 34,194,127,105,200,190,159,240,226,
+ 13, 41, 10,235, 7, 52, 70,162,165, 0, 46, 50, 9,148,114, 22, 42,185,184,250,178,228, 81,216,227,196,137, 51,239,252,126,252,
+204, 87, 93, 94,139,240,152, 61,178, 63,118, 28, 60, 15, 39,133, 4,148,231,240,230,107,117, 6,222,217,214,173,151,159,151, 82,
+187,235,116,202,185,113, 75,111, 79, 51, 24,172, 15,170, 59,150,165,124, 7,255,139,132,144, 70, 0,250, 18, 66,236, 0, 20, 0,
+ 12, 40,219,155, 70, 1,224, 66,117,251,200,253,241, 25,233,136,176,176,214,155, 9,168, 20, 20,235,142,239,197, 33, 30,226,132,
+146,172, 91,250,231, 77, 55, 99,202,189, 12, 0,111, 59,251, 52,142,184,121,241,196,156,246, 61, 6,135,182,239, 61, 76,156,152,
+ 99, 3, 47,114,130,225,225, 57,107, 98,212, 47,183,236, 22,243,156,146,204,184,211,207,226, 50, 48,202, 5,215, 15, 44,104, 23,
+208,105, 66,155, 90,245,195,225, 94,167, 5, 0,160, 48, 53, 6, 41, 87,127, 59, 80,148, 46, 30, 70,233,173,231, 94,221, 39,146,
+203,135, 54,104,220, 28,113,177, 55, 96, 50, 22,255, 66, 41,229, 61,234,183,255,229, 97,220,205,207,181,254,161, 96,164,242,161,
+ 79, 19, 88, 2, 4, 8,120, 74,187,242,180, 61,253,212,205,250,135, 49, 84,188,143,231,237, 10,150, 21,153, 56,216,250,213, 84,
+ 92,253,187, 85, 51, 25, 50,132,213, 36, 72, 71,137, 68,162, 78,169,151,127,126, 29, 0,188, 91,189,247, 51,203,217,206,164, 95,
+223,182,241,105, 27, 24, 62,201,217, 63, 66,219,185, 67,104,173, 58,147,150,223,190, 3, 32,182,186, 77, 68, 29,244, 12, 73, 1,
+ 4, 0,112, 2,240,128, 82,154, 83, 57,188, 54,244,237,206, 44, 43, 86, 84, 12, 11,178, 0,120, 80,211,163, 75, 27,143, 59,154,
+158, 78,222, 13,219,179,172,232, 35,187,141, 91,111,200,190,123,236,133,211,147, 16,165, 84, 42, 13,243,246,246,214,206,156, 57,
+ 83,113,245,234, 85,209,225,195,135,205,197,197,197,105,197,197,197,103, 41,165,198,154,112,146,142, 29, 69,234, 92,247, 65, 96,
+105, 87, 15, 47,109, 39, 15, 79,111,207,188,156,140,188, 92,125,230, 9,194,115,199,178, 37,234,157,229,243,178,106, 92,150,198,
+141, 27,215,149, 16, 18, 72, 41,173, 67, 8,121,200, 48,204,131,210,210, 82,135, 61, 88,127, 72, 71,159,144,118, 42,133,116,218,
+187,195,222,110,221,175, 95, 95,230,226,141, 36,156, 62,113,136,187,114,225,212,149, 82,139,125,126, 73,198,237,179, 47, 82,230,
+ 53,205, 94, 79,164, 92,213,219, 52,136,196, 98,125,250,181, 63,158,251,231, 8,167,147,119,227,198, 32,152,206, 80,136,237,132,
+255,214,152, 17,119,237,101,213, 77,109,179, 55,250,115, 54,219,159, 38,180, 75,100,226,210,148,232,127,173, 34,124, 86,190,107,
+242, 92,223,225, 40,190, 10,239,216,203,163,206, 43,245, 17,115,108, 57, 14,253,131, 92,252,253, 90,118,244,103, 75,175,237,141,
+ 79, 51,223,174,124,106,129,163,118, 18, 66, 52, 0,122, 82, 74,127, 34,132,140, 4,112, 13, 64,204,179, 68,218,255,199,219, 60,
+ 33,132,168, 52,254,131, 84, 78,234,111, 35,122,189,227,113,242,192,207,197, 22,115,225, 63, 12, 25, 15,118, 62,205,214, 63,181,
+ 33,154, 38, 74, 21,108, 83, 61,234,181, 30,165,240,240, 83, 25,114, 18,243,243,147,162,150, 26,179, 52,203,170,155,167, 90,157,
+157,193,157, 71,166, 13, 31, 55,215,109,247,150,101,136,191,115,173, 89, 78,220,241, 7,158, 13, 59, 55,240,245,111,114,163, 93,
+191,143,112,120,211,215,246,248,115, 27, 92,171,106, 67, 5, 47,142,192, 41,224,233,111,131,127,217, 7, 64,200,127, 35, 39,202,
+ 28, 83, 94, 0,156, 94,182,157, 0, 36,255,109,233, 9,192, 77,161, 80,244,112,117,117,237,135,178, 73,198, 47,197, 78,247,214,
+111, 59,255, 39, 63,187,202, 59,184,157,119,189,150,187,213,175, 52,223,173,242, 14,110,247,119, 46,243,255, 14, 78,116,232, 32,
+210, 4,247,127,207, 51,184, 95,226, 27, 3, 59,196, 70,132,168, 59, 85, 87,199, 28, 44,159, 67, 0,140, 4, 48,228, 63, 61, 61,
+129, 14, 34,165,182, 89, 19,248,248, 40,158,187, 13,105,220, 88,162,244, 10, 82, 3, 29, 68, 47,203, 78,247,122,237, 38, 7, 68,
+188,155,233,230,223, 97,126,229,251,110,254,237,167,215,107, 59, 44,213,189, 94,187,201, 66,153, 23, 56,255,106,206,191,219, 71,
+ 36, 72,204, 42, 69, 39,197,191, 86, 25,188,108,110,235,127, 97,122, 20, 0,136,124,217,188, 47,115, 35,200,191, 2,229,158,170,
+179, 66,141,120, 73,229,232,212, 41, 59,128, 13, 0, 54, 84,158,103,245, 18,202,231,142,255,158,186,116,202, 14,224,214, 11,113,
+196,198, 90, 1,100,191,212,186,248,240,204, 66, 84,177,107,110,126,252,233,111, 0,124, 35,148, 94, 1, 2,106, 14, 70, 72, 2,
+ 1, 2, 4,252, 63,136,118, 94, 72, 5, 1, 2, 4,252,157, 65, 80,126,164, 76, 21, 13,160,195, 99,171,132,144,144,231,104, 96,
+111, 11,156, 2,167,192, 41,112, 10,156, 2,167,192,249,191,197, 89, 29,247,223,101,110, 23,169,230,224,250, 23, 35, 23, 38, 0,
+ 10,156, 2,167,192, 41,112, 10,156, 2,167,192,249, 63, 8, 97,136, 80,128,128,234, 27, 18, 53, 33, 68, 45,164,132, 0, 1, 2,
+ 4, 8,248,143, 21, 88,142,118, 86, 47,210,169, 9, 29,226, 95,146,111, 34, 66,200,167,238,238,238,151,234,213,171,151,237,234,
+234,122,137, 16,242, 25, 33, 68,252,188,156, 58,157,174,141, 86,171, 93,225,237,237,189, 74,171,213,134,255,133,182,107, 9, 33,
+218,231,140,251, 21, 33,120, 88,246, 33, 95, 9, 37, 65,128, 0, 1, 2, 4, 56,130,167,174, 34,108,215,174,221, 57,145, 72,164,
+ 19,137, 68,142,158, 99, 70,109, 54, 91,218,169, 83,167, 34,170,233,172, 38,149,127, 95, 66, 41,157,253, 34,225, 28,136,187,130,
+ 82, 58,237,121, 58,100, 0,160,148,166, 3,128,175,175,175, 63,207,243,237,197, 98,113, 67,155,205, 22,199, 48,204,153,212,212,
+212,135,255, 97, 2,136,109,220,184,254, 48,150,144,182, 0,220, 0, 20,216,121,122,193,203, 75,187,249,212, 41,199,246,200,169,
+ 16, 82, 0, 38,168, 84,170,193, 74,165,242,149,146,146,146, 71, 38,147,105,143, 84, 42,237,180,124,249,114, 93, 88, 88,152,179,
+ 94,175, 39, 12,195,168, 15, 28, 56,240,246,242,229,203,187, 16, 66,122, 83, 74,237, 53,181,153,227,184, 97,251,246,237, 11, 6,
+128, 94,189,122,141, 32,132, 92,162,148,242, 79,166,127, 21, 54, 18, 31, 31,159,112, 0,200,200,200,184, 64, 41,165, 90,173,182,
+173, 76, 38, 27, 1, 0,165,165,165, 63,167,167,167,159,127, 9,101, 73, 77, 8, 38, 85,108, 92,203, 48,228, 83,103,103,231,173,
+197,197,197,247, 43,254, 94,110,103,182,208,148, 8, 16, 32, 64,128, 0,135, 4, 22,195, 48,186,117,235,214,121, 41, 20, 10,144,
+242,195,246, 72,165, 67,247, 8, 33,143,175,109, 54, 27, 76, 38, 19,198,142, 29,107,175, 65,103,245, 89,215,174, 93,187,201,229,
+242, 63,108, 44,105, 54,155,197,132, 32,168,226,212,121,134, 33,147, 8, 33, 63, 56,210,137, 85,252,134,197, 82,202,136,197, 82,
+176, 44, 51,161, 89,179,102,161,122,189,254, 20,128,117,233,233,233,185, 14,112,252, 2,160, 15, 33, 4, 78, 78, 78, 87,253,253,
+253,115, 63,248,224, 3,239,206,157, 59,163,110,221,186,200,200,200,104,115,242,228,201, 17, 45, 91,182,204,204,204,204, 60, 65,
+ 41, 61,149,158,158,126,255, 5,197,145,151,135,135, 71, 79,137, 68, 34, 97, 24, 38, 63, 61, 61,253, 2,165, 52,179, 38,226, 42,
+ 36, 40, 96,209,168,209, 99, 26, 13, 28, 56,208, 71,161,116,150, 39, 39,199,167,175, 93,179,218,245,220,217,243,205, 8, 33,147,
+202,119,191,118,196, 75,181,255,139, 47,190,208, 70, 68, 68, 56,231,230,230,194,110,183,215,218,179,103,207,168,230,205,155, 59,
+235,116, 58,233,166, 77,155, 80, 82, 82, 2,142,227,220,253,253,253,221,135, 14, 29,106,217,180,105,211, 4, 0,139,107,250,220,
+ 60,207,179,229,255, 18,142,227,196, 0, 88, 66,200,156,234, 4,145, 78,167,107,213,191,127,255,249, 50,153, 12,219,182,109,219,
+ 1, 96, 57,128, 55,143, 29, 59, 22, 0, 0, 17, 17, 17,111, 2, 56,239,230,230,214,140, 16,124,202,243,101, 71, 39,213,164, 44,
+ 85,133,222,189,251,128, 16,178,194,219,219,251,124, 78, 78,142,142, 16,188,249, 60,194, 77,128, 0, 1, 2, 4,252, 15, 11, 44,
+ 0, 80, 40, 20,216,191,127, 63, 40,165, 96, 24, 6, 44,203,150, 31, 17,195, 32,170, 36, 4,102,187, 24, 37, 25, 55, 49,168,185,
+ 24,205,155, 55,255,131, 0,123, 90, 31, 94, 89,160, 77,156, 56, 17, 26,141,230, 15, 1,178,178,178,112,226,196,241, 42,227, 56,
+170, 55, 42, 95,204,157, 59,215, 53, 47, 47,175,247,250,245,235,187,248,248,248,124,153,145,145,113,182, 26,207, 85,159,138,137,
+255,221,186,117,107,245,227,143, 63,222, 41, 46, 46,182, 94,190,124,217,186,122,245,234,244,215, 94,123, 77, 59,120,240, 96,201,
+132, 9, 19,188, 31, 61,122,244,206,254,253,251,223,113,119,119,223,151,159,159,191,224,121, 50, 64,165, 82,133,244,239,223,191,
+203, 79, 63,253, 36, 85, 42,149,120,248,240, 97,173, 97,195,134,105, 8, 33,191, 60,121,148,206,211,208,184,113,253, 97, 31,142,
+ 26, 21, 56,230,163,113, 45,172, 86,139,241,102,244,169, 19, 34, 9,195,142, 29,251,190,107,110,110,150, 7,207,211, 97, 40,219,
+127,168, 58, 76,152, 57,115,166,143,191,191,127,237,173, 91,183,162,164,164, 4, 0,188,234,213,171,135,128,128, 0,238,244,233,
+211, 8, 12, 12,132,179,179, 51, 78,159, 62,141,139, 23, 47,162, 69,139, 22, 78, 18,137,228,245,103, 9, 44,157, 78,215, 68,167,
+211,205,210,128, 73,109, 7, 0, 0, 32, 0, 73, 68, 65, 84,148,103,118, 69,250,134,134,134, 98,226,196,137, 48,155,205,104,208,
+160, 65, 61,133, 66,113,254,244,233, 83,142,136,107,185,167,167, 39,198,140, 25,131,146,146,146, 33, 58,157, 46,129, 82, 42, 42,
+183, 23,148, 82,117, 64, 64,192,230,142, 29, 59, 54,216,183,111, 47,121,222,202, 65, 41,205, 38,132, 44,233,219,183,207,167, 0,
+ 65,167, 78,157,242, 38, 78,156,200,221,185,115,167,221,160, 65, 3, 91,223,187,119,255,165, 8, 55, 1, 2, 4, 8, 16,240, 63,
+ 36,176, 42, 60, 84,199,142, 29,131,197,242,231,163,230,220, 59, 52,199,228, 65,117, 48, 98,252, 70,108,127, 16,143, 38, 77,154,
+224,201, 21,137, 79, 28,210,154,205,178,236, 58,134, 33, 31, 18, 66, 16, 26,218, 60,123,209,162, 69, 85, 29,139, 98, 11, 13,109,
+158,205,178,140,154, 82, 10, 66,152,181, 60,207,101, 87,197,249,180, 14, 81, 42,149, 77, 2, 0, 31, 31,109,246,193,131, 7,109,
+131, 7, 15,198,194,133, 11,165, 83,166, 76,249, 66,167,211, 13, 79, 75, 75, 75,123,154,157,149,225,231,231,135,184,184, 56,204,
+152, 49, 35, 51, 43, 43,107, 93,102,102,102,220,150, 45, 91,234,212,171, 87,111,196,154, 53,107,234,133,135,135, 51, 61,122,244,
+192,129, 3, 7,154, 85, 97, 75,117, 75, 95,197, 0, 94,233,216,177, 99,231,157, 59,119, 74,139,138,138,144,148,148, 4,165, 82,
+137,217,179,103, 59,127,244,209, 71,237, 1,236,114,132,147, 37,164,109,191,254, 3, 52, 22,139,169,196, 98, 49, 23, 39, 36, 69,
+101,164,167,223, 41,104,224,223, 66,221,173,123,152, 71, 92,220,195,182, 79, 19, 88,149, 57,229,114,249,235,109,219,182,117,222,
+186,117, 43, 90,182,108, 9, 87, 87, 87,156, 60,121, 18,183,110,221, 66, 94, 94, 30, 67, 41,133,147,147, 19,230,207,159, 15, 63,
+ 63, 63, 20, 23, 23, 35, 49, 49,177,150, 88, 44,246,124,150,157, 60,207,247,218,184,113,163,198,211,211, 19,118,187, 29,148, 82,
+216,237,118,240, 60,143,140,140, 12,148,148,148, 64,165, 82,193,108, 54,227,204,153,211, 85,138,229,202,156,105,105,105,103,214,
+172, 89,115,166, 97,195,134,237,167, 76,153, 2,137, 68, 50,181,160,160, 0, 11, 23, 46,132, 82,169,196,220,185,115,189, 67, 67,
+ 67, 1,192,102,183,219, 43,202, 18,165, 20,223, 87, 22, 65,142,172,128,241,245,245, 61,150,157,173, 15,127,237,181,215,144,159,
+159,111,155, 61,123, 54, 66, 67, 67,209,160, 65, 0,170, 75,207,151, 5,129, 83,224, 20, 56, 5,206,255, 5,206,191,165,192, 34,
+132, 80, 74,203,134, 81,158,248,142,157, 59,119, 86, 25,241,189,197,177, 16,177,101,253,223,170, 85,171,144,151,151, 87,173,183,
+137,227,184, 79, 52, 26,141,105,234,212,169,157, 26, 52,104, 96, 27, 59,118,236,181,196,196,196,137,149,195,212,173, 91,119,217,
+ 15, 63,252,128, 7, 15, 30,228,204,159, 63,255, 68, 86, 86,214,244, 26,102,250, 44, 66,200, 10, 0, 72, 79, 79,207, 61,112,224,
+ 64,203,211,167, 79,127,182,100,201, 18,239,113,227,198, 73,199,143, 31,255, 33,128, 47,158, 18, 55,157, 16,178, 69,167,211,189,
+ 19, 17, 17,129, 1, 3, 6,228,182,109,219,214,122,229,202, 21,239, 75,151, 46,205, 90,177, 98, 5, 63,124,248,112,166, 93,187,
+118,208,235,245,248,237,183,223,248,228,228,100, 70, 38,147,153, 28,118,175, 17,210,137,101,217, 79, 25,134, 9, 13, 10, 10,186,
+ 59,122,244,232,219,121,121,121, 57,169,169,169, 48, 26,141,176, 90,173, 16,137, 68,144, 72, 36, 53,216, 63,131,184, 42,149, 10,
+201,197,243,123,142,164,167,198,230,100,100,221, 46,100, 64,153,244,244,168,194,192,192, 78, 30, 40,155,147, 85, 45,156,156,156,
+234,233,245,122,148,148,148,192,205,205, 13, 75,150, 44,129, 90,173,134,201,100, 66, 92, 92, 28,245,245,245, 37, 39, 79,158,132,
+ 78,167, 67,126,126, 62, 44, 22, 11,140, 70, 99,150,197, 98,121,230,243,139,197,226,125,195,135, 15,111,175, 86,171,149, 21, 30,
+ 44,158,231, 81,191,126,125,140, 27, 55, 14,219,183,111, 71,124,124, 60, 40,165, 54,157,206, 55,155, 97,136, 26, 0,101, 24,118,
+139,221,110,207,174, 34,159,168,175,175,239,220, 89,179,102,249,174, 94,189,250,149,137, 19, 39,130,227, 56,240, 60, 15,142,227,
+144,157,157,141,125,251,246,225,252,249,243,214,184,184,184,237, 46, 46,174, 49, 38,147, 41,170,180,180,244,145,163, 41,234,235,
+235, 43,231,121,254,131,128,128,128,158, 67,135, 14,181, 73, 36, 18,152, 76, 38, 24,141, 70,220,190,125,219,214,179,103,207,188,
+190,125,251,120, 28, 60,120,144, 82,138, 37,130,247, 74,128, 0, 1, 2,158, 15, 79,211, 32,127, 27, 15,214,211, 30,234,231,159,
+127, 6,165, 20, 44,203,130, 97,152,199, 67,132, 37,233, 60,222, 27,191, 25, 18,150, 71,100,100, 36,154, 53,107,230,208, 15,242,
+ 60,191, 60, 50, 50, 50, 44, 34, 34, 66,212,165, 75,151,230,117,234,212, 9, 77, 74, 74,186, 14, 0,117,234,212, 9,237,218,181,
+107,115,181, 90,141,101,203,150,153,121,158, 95,254,156,202,186,114,103,119,217,207,207,239,203,221,187,119,175, 30, 61,122, 52,
+124,124,124,154, 86, 19,119,116,247,238,221,155,125,254,249,231,152, 49, 99,134,117,221,186,117,246, 49, 99,198,136, 58,118,236,
+136, 77,155, 54, 49,247,238,221,195,186,117,235,248,221,187,119,103, 18, 66,216,238,221,187,107,106, 80,136, 58,104, 52,154, 95,
+118,236,216,193,183,106,213, 74,126,255,254,253, 70,147, 38, 77,210,100,100,100, 28,109,208,160, 65,174,209,104,132,221,110,135,
+193, 96, 0, 0,139,163,188, 12, 75,178, 82, 83, 31,169, 75,173, 5,230, 30, 29,195, 39,233, 19,115,224, 85,183, 63,126, 63,189,
+115,105, 82, 74, 60, 79, 24, 56, 52,212, 88, 82, 82,242,200,110,183,123, 0, 80, 31, 59,118, 12, 94, 94, 94, 40, 46, 46,134,213,
+106,133,201,100,178,186,187,187,203,114,115,115, 81, 90, 90,138,210,210, 82,184,184,184, 32, 58, 58, 58,207,110,183, 31,122, 22,
+111,114,114,242, 29, 0,221,158, 16,210, 50,134, 97,142,219,108, 54, 60,124,248, 16,119,239,222,237,156,152,152, 88, 90,158, 78,
+ 90, 0,176,219,237,233, 79,227, 76, 77, 77, 53,123,121,121,125,254,254,251,239, 79,212,104, 52, 33, 0,224,239,239,239, 50,105,
+210, 36, 44, 88,176, 0, 49, 49, 49,179,196, 98,241,165,180,180,180,210,154,150, 31,141, 70, 19,164, 80, 40, 38, 79,152, 48, 65,
+ 19, 20, 20,132,210,210, 50, 10,103,103,103, 24,141, 70,184,184,184, 32, 44, 44, 44,238,203, 47,191,180, 82,138, 81,148,210, 44,
+161,137, 20, 32, 64,128,128,151, 35,178,254, 86, 30,172,114, 97, 65, 8, 33,244,137, 7, 46,235,192, 25,230, 15,226,138,101, 89,
+ 12,106,201,162,184,129, 63, 24,166,108, 40,209,110,119,108, 17,153, 94,175,207,242,245,245,221, 19, 29, 29, 61,120,200,144, 33,
+ 56,113,226,196,199, 0, 62, 0, 0,150,101, 63, 30, 50,100, 8,162,163,163,113,247,238,221, 61,122,189,254,165,116, 92, 86,171,
+213,104,179,149,141, 70,202,229,114, 73,181,130,133, 97,172, 18, 73, 89,176,251,247,239, 15, 24, 63,126,252,128,238,221,187,143,
+236,221,187, 55,246,237,219,135,141, 27, 55,126, 13,224, 68, 68, 68,196,230,154,216,193,178,236,164,237,219,183,219, 35, 34, 34,
+156, 41,165, 8, 14, 14,118,158, 60,121,178,117,225,194,133,245,134, 15, 31,158,155,154,154,138,162,162, 34,100,102,102, 90,147,
+147,147,227, 29,229,181,115,252,137, 21, 43,126,208,141,250,160,191,102,231,129,245,243,126,219,117,179,233,219,111,102,198,106,
+117, 77,188,150,175, 60, 47,183,219,249,189,142,240,152,205,230,223, 14, 30, 60,248,102,157, 58,117,212,183,110,221,130,217,108,
+ 6,207,243,232,217,179, 39, 0,200, 42,194,197,197,197,153,141, 70, 99,118,108,108,108,113, 82, 82,146, 13,101,147,204, 29,169,
+ 64,143, 87, 7, 90,173,214,119,122,245,234, 5,142,227,208,163, 71, 15,220,184,113,227, 29, 0,235, 42,254,238,104, 89, 2, 48,
+ 13, 0,116, 58,157,135,171,171,235,190, 10,239,152, 70,163, 57, 31, 29, 29,109,243,245,245, 29, 42,145, 72,194, 76, 38,211,206,
+204,204,204, 51,213,113,106,181,218,240, 6, 13, 26,204, 92,184,112, 1,209,104,188,193,113, 54,216,237,118,100,103,231,160,164,
+164, 4, 65, 65, 65,240,243,243,195,252,249,243,193, 48,204,126, 65, 92, 9, 16, 32, 64,192,139,163, 42, 13,242,223, 14,230,201,
+ 7,172, 78, 92, 85,124,151,136, 88,120,214,114,135,103, 45, 15,184,187,187,131,227, 56, 56,170, 62, 25,134,217,180,117,235, 86,
+139,171,171, 43,250,246,237, 27,232,227,227, 19,225,227,227, 19,209,183,111,223, 64, 87, 87, 87,108,221,186,213,194, 48,204,166,
+151,164,138, 25,150,101,135, 69, 68, 68, 32, 43, 43, 11,143, 30, 61,186, 92,147,248, 41, 41, 41,197, 25, 25, 25,219, 13, 6, 3,
+ 68, 34, 17,204,102, 51, 0,156, 2, 80,227,179,212,120,158,111,213,170, 85, 43, 69,197, 92,181,132,132, 4, 56, 59, 59, 59,167,
+164,164,168,141, 70, 35, 44, 22, 11, 10, 10, 10,112,237,218, 53, 35,128,116, 71,121, 99, 98,238,239,137,186, 18, 21, 29,121,244,
+ 44,243,202, 43, 77,189,124,117,202, 34, 79, 47, 95,231, 67,145,183, 20,153, 25,185, 15, 99, 98,226, 29, 61, 12,119,249,238,221,
+187,115,163,163,163,239,250,250,250, 38,187,186,186, 82, 0,200,200,200,248,195,231,234,213,171,178,200,200, 72, 99, 82, 82,210,
+ 62,148, 45, 10,176, 59,144, 15, 95, 17,130,123,132,224, 30,203,178,139,154, 53,107,246,118,120,120, 56, 82, 82, 82, 16, 30, 30,
+142,224,224,224,183, 61, 61, 61,189,107,152,183,222,132, 16,109, 80, 80,144, 74,165, 82, 45, 29, 57,114, 36,236,118, 59,186,116,
+233, 2,131,193,176, 94,171,213,254,163,123,247,238, 31,255,248,227,143, 77, 53, 26,205, 39, 14,210, 14,125,235,173,183,136, 82,
+169,130,205,102,131, 84, 42,133, 74,229,132,122,245,234,161, 83,167, 78,160,148,162, 83,167, 78,252,154, 53,107,246, 41, 20,138,
+205, 66,179, 40, 64,128, 0, 1, 47, 79,100,253, 45, 61, 88, 79,233,192,192,113, 28, 8, 33,184, 84, 24, 2,179, 93,132,194,148,
+ 40, 12,105, 37,125, 44,180, 88,150, 5,203,178,176,217,108,112,244,216,157,228,228,228, 2, 31, 31,159, 95,207,159, 63,255,238,
+192,129, 3,113,228,200,145,209, 0, 48,112,224, 64,156, 63,127, 30, 15, 31, 62,252, 53, 35, 35,163,160,134,157,173, 39, 0,182,
+178, 71, 65,163,209,188, 82,187,118,237,143, 71,141, 26,213,166, 73,147, 38,216,178,101, 11, 0,156,112,216, 51, 84,230,149, 83,
+ 3, 40,121,226,217, 36, 0,156,121,158,175,209, 38,155, 12,195, 92, 61,113,226, 68,171,222,189,123, 59, 39, 37, 37, 33, 61, 61,
+ 29, 59,118,236,200,246,240,240,200,230,121, 30, 30, 30, 30,240,244,244,132,205,102, 83,196,197,197,121, 3,112,120,175, 45,142,
+ 74,215, 30, 61,114,121,117,235, 22, 61,153, 87,234,168, 10, 1, 11,185, 26,157,166, 18, 73, 68,171,106, 80,184,237,132,144,190,
+231,206,157,155,112,241,226,197, 65, 62, 62, 62,228,221,119,223, 69,207,158, 61, 33,149, 74, 97, 50,153,144,159,159,143,131, 7,
+ 15, 18,187,221, 30, 14, 0, 62, 62, 62,181,235,214,173,251, 51, 33, 36, 45, 33, 33,225,221,167,228,205,147, 91,116,140, 30, 48,
+ 96,192,157,140,140, 12,219,164, 73,147,176,104,209, 34,140, 24, 49, 66, 28, 27, 27,251, 1,128,127, 58,152,223, 95, 18,130, 79,
+ 65, 65, 82, 83, 82,238,253,176,114,101,169,143,143, 15,142, 29, 59,134,176,176, 48,212,175, 95,255,149,107,215,174,189,210,174,
+ 93, 59, 92,190,124, 25,185,185,185, 23,171,227,236,216,177,163,136,101,217,122, 90,173, 22,137,137,137,144,203,229,240,246,246,
+134,155,155, 27,188,188,188,176,104,209, 34, 44, 89,178,228,166, 72, 36, 90,151,150,150,246, 80,104, 14, 5, 8, 16, 32, 64,192,
+ 51, 5, 86,101,213,248,164, 23,235,240,225,195,160,148,194, 41,188, 37,166, 14,169,139, 97, 31,111,196,182,135,113,144,201,100,
+255, 34, 17,137,240,209, 71, 31,213,232,135,221,221,221,183,109,219,182,109, 96,219,182,109, 85, 93,186,116,169, 15, 0,114,185,
+220,182,109,219, 54,131,187,187,251,182, 26,138,171, 25,132, 96, 10, 40, 24,153, 84,122,204,163, 86,173,227,206,206,206, 45,186,
+119,239, 94,191, 71,143, 30,240,247,247,199,142, 29, 59,176, 99,199,142, 19, 25, 25, 25, 23, 28,229,173, 87,175, 30,238,220,185,
+ 51, 12,192,122, 0, 20,255,154,196,111, 7,208,214,207,207, 79, 94, 19, 59, 57,142, 91, 50,124,248,240,157, 51,102,204,200, 9,
+ 12, 12, 84,109,223,190, 61,255,216,177, 99,150, 94,189,122, 61,170,232,200, 77, 38, 19, 76, 38,147, 84,167,211, 53,168,137,192,
+138,137,137,201,238,209,189,179,215,202,213,231,235,155, 76,156,117,239,225, 99, 86,155, 69,101,186, 19,247, 48,179, 38, 54, 82,
+ 74,237,190,190,190, 99,120,158,247,178,219,237, 86, 47, 47, 47,201, 47,191,252, 2,185, 92, 14,134, 97, 16, 26, 26, 10,185, 92,
+110,209,106,181,133, 0,160, 86,171,109,139, 23, 47, 22,189,255,254,251,146,154,100,153,183,183, 55, 54,111,222, 12,131,193, 48,
+111,251,246,237,211, 62,250,232, 35, 4, 6, 6,118,212,106,181,139,210,211,211, 77,213,228,183,123,101,193, 70, 8,105, 40,145,
+ 72,238, 44, 95,190,220,114,238,220,185,221,145,145,145, 61, 71,140, 24, 33,143,136,136,192,133, 11, 23,176,118,237,218,203,174,
+174,174,203,170, 51,234,244,233,211,188,143,143,207,227, 97,112,179,217,140,132,132, 4,132,133,133, 97,221,186,117, 88,190,124,
+249,214,204,204, 76,193,107, 37, 64,128, 0, 1,127,145,231,234,239,228,197, 18, 85, 23, 96,251,246,237, 0,128, 15,190,143,131,
+197, 82, 54,143,105,213,170, 85,143,247,175,170, 24, 74, 60,115,230, 12, 80,131, 61,171, 98, 99, 99, 13,190,190,190,155,198,143,
+ 31, 63,247,234,213, 43,106, 0,136,138,138,202,206,204,204,156,153,154,154,106,168,129,184,114, 35, 4, 83,120,158,178,229, 34,
+173,235,164, 73,147,180,109,219,182,181,138,197, 98, 36, 39, 39,227,187,239,190,195,249,243,231,183,103,100,100,172,164, 14,184,
+217, 18, 19, 19, 47,167,164,164,180, 25, 55,110, 28,218,183,111,223,103,237,218,181,221, 42, 63, 91,104,104,232,134, 94,189,122,
+105,100, 50,153,200, 98,177,112,247,239,223,191,238, 96, 33, 58, 77, 8, 25, 58,101,202,148, 9,148,210,102,106,181, 58,185,117,
+235,214,177,109,219,182,205,117,113,113,129, 72, 36, 66,118,118, 54,140, 70, 35, 56,142,115,175, 73, 70,250,249,249, 69, 76,152,
+ 48,161,233,152, 49, 99, 96, 48, 24,176,113,227, 70,172, 92,185, 18,126,126,126, 17, 41, 41, 41,231,106,194,197,243,188,215,254,
+253,251, 43, 60,117, 56,126,252, 56,180, 90, 45, 92, 93, 93, 81, 84, 84,132,119,223,125, 87, 58,107,214, 44, 0,192,181,107,215,
+196, 10,133,162,186,231,206, 38,132, 44, 97, 24, 50, 9, 0,105,213,170,181,222,197,197,197,118,233,210,165,248,180,180,180, 67,
+254,254,254,175, 15, 31, 62,188,126,235,214,173, 37,247,239,223,111, 7,224, 72, 77, 11,114, 94, 94, 30,206,156, 57,115, 38, 35,
+ 35, 99,137, 90,173,222,246,229,151, 95,126,234,237,237,221, 44, 61, 61,253,146, 70,163,153, 27, 29, 29,109,115, 32,127,120, 31,
+ 31,159,148,163, 71,143,250, 13, 30, 60, 24, 82,169, 20,249,249,249,112,113,113,193,226,197,139,169,213,106,221, 35, 52,133, 2,
+ 4, 8, 16, 32,224,165, 8,172,221,187,119,131, 97, 24, 88,178, 45,248,104,202,118, 40,229, 44, 78,158, 60, 9, 15, 15,143, 63,
+204,203,170, 24, 50,124, 66,252, 60,243,180,237,188,188,188,115,233,233,105, 94,149, 54,150,244,146,201,228,231,170, 17, 84,207,
+228, 36,132,192,106,181, 34, 50, 50, 18,103,207,158,181, 62,120,240,224, 52, 33,100,127,122,122,250, 77, 71, 57, 11, 11, 11,191,
+ 29, 61,122,244,148,158, 61,123,182, 25, 54,108, 24,150, 47, 95, 46,185,115,231, 14, 40,165,104,222,188, 57,154, 52,105,162,179,
+217,108, 52, 38, 38,166,100,223,190,125,145,102,179,121,179,163,118, 82, 74,143, 1, 56, 70, 8,145,100,102,102,190, 82, 88, 88,
+216,153,231,121,231,236,236,108, 36, 38, 38, 34, 47, 47, 15, 69, 69, 69,176,219,237,121, 53,121,246,148,148,148,115,173, 90,181,
+ 2,195, 48, 48,153, 76, 72, 77, 77,133,221,110, 71,122,122,122,141,211,147, 97, 24,125,175, 94,189,188, 74, 75, 75,237,111,189,
+245,150, 72,175,215, 35, 48, 48, 16, 0, 80, 92, 92,140,195,135, 15,163, 97,195,134, 21,158, 51, 4, 5, 5, 85,203, 73, 41,157,
+ 77, 8,249,209,199,199,231,203,111,190,249, 38,240,210,165, 75,176,217,108,145, 0, 96,179,217, 34,163,162,162,234,183,104,209,
+ 2, 91,182,108,233, 94,149,192,170,204, 73, 41,205, 47, 23,108,159,130,130, 4, 53,110,156, 27, 24, 24,104, 21,139,197,181, 0,
+ 32, 59, 59, 59, 27,192, 20, 7,196,121, 72, 21,123,118,205,220,181,107,215,251, 23, 47, 94,108,247,233,167,159,146, 78,157, 58,
+ 1, 0, 12, 6, 3,167,215,235, 13,207,195,249,162, 16, 56, 5, 78,129, 83,224,252, 95,224,252,159, 18, 88,133,133,133,104,221,
+186, 53,108, 54, 27, 26, 55,182,161,168,168, 30,108, 54,219,227,201,191, 60,207,195,110,183,131,227, 56, 48, 12,227,240, 28,172,
+ 10,152,205,102,235,147,155,191,155,205,102,107, 13, 93,139, 5,132,144,239, 24,134, 76, 1, 5, 35,149, 74, 47,175, 92,185,114,
+ 35,128, 52, 74,233,229,234,134,155,170, 66,102,102,102, 14,128,201,181,107,215,110,126,242,228,201,113,131, 6, 13,170,223,183,
+111, 95, 36, 39, 39,195,110,183, 35, 62, 62,222,182,111,223,190,152,130,130,130, 31, 41,165,119,158, 39,225, 41,165, 86, 0,247,
+156,157,157,193,243,124,251,176,176, 48, 15,187,221,142,156,156, 28, 92,188,120, 49, 49, 39, 39,231,252,115,120,176, 48,122,244,
+104,148,148,148, 96,251,246,237, 56,114,228,200,115,121,176, 82, 83, 83, 27, 0,128, 86,171,205,114,113,113, 17,141, 28, 57, 18,
+ 54,155, 13, 70,163, 17, 69, 69, 69,200,205,205,181,124,242,201, 39, 82, 0,144, 74,165,182, 30, 61,122,136, 28,124,230,244,240,
+240,112, 87,185, 92,142, 51,103,206,240, 60,207, 31, 47, 23, 53,199,207,157, 59, 55,174, 89,179,102,140,167,167,103, 67, 7,185,
+190, 32,132,172,118,113,113,209, 54, 14, 10, 90, 74, 41,133,151,151,151,223,139, 86,136,172,172, 44, 61,128,121, 58,157,110,215,
+231,159,127,254, 97,155, 54,109,130,191,248,226, 11, 80, 90,230, 33, 21, 32, 64,128, 0, 1, 2, 94, 84, 96, 37,140, 25, 51,198,
+ 90,217, 51,244,132,151,227, 79,158, 35,158,231,211,106, 40, 50,178, 9, 33,139,203,135,142,240,188, 27, 54, 82, 74,231, 18, 66,
+126, 4,192,154, 75, 75, 95,218,178,249,228,228,228,107,132,144,145,155, 54,109,234,178, 99,199,142,201,111,190,249,166, 98,253,
+250,245,150,236,236,236, 69, 0,142, 80, 74,249, 23,253,141,226,226,226,123,132,144,140,184,184,184, 87,165, 82,169,130,227, 56,
+189, 94,175,143,165,148,150,212,132, 39, 37, 37,229,156, 86,171,197,158, 61,123,224,225,225,129,188,188, 60,135, 60, 88,213,188,
+161, 12,216,186,117,235,110,158,231,229, 79,228,125, 81,122,122,122, 3,160,108,146,251,225,195,135,127, 38,132,164, 57,104,231,
+246,177, 99,199,190,171,215,235,127, 75, 75, 75,203, 47, 23,116,249,190,190,190, 75,102,204,152, 49, 52, 39, 39,231,151, 26,228,
+123, 38, 33, 68,255,232,209,163,226,188,188, 60,103,142,227, 94, 90,197, 72, 75, 75,123, 0,224, 31, 58,157,174, 77,143, 30, 61,
+222,161,148,234,133,230, 66,128, 0, 1, 2, 4,188,176,192, 58,121,242,100,167,127,135, 1,229, 67, 71, 63, 84, 8,174, 23,224,
+201,249,139,236,163, 0,126, 39,132,156, 88,182,108, 89, 35,163,209,152, 72, 41, 53,188,228,223, 40, 6,112,244, 69,121,210,211,
+211,149,132,144, 25, 0,166, 3,248,134, 82,250,245, 11,138,140, 75, 0,158,185,117, 66, 70, 70, 70, 50,128,215, 28,229, 76, 77,
+ 77,221,133, 39,142, 0, 42,191,191, 7,192,158,231, 72, 59,206,207,207,111,246,164, 73,147,122, 0,216,255,178,243, 63, 45, 45,
+237, 50,128,203, 66, 83, 33, 64,128, 0, 1,255,239,104, 5,192,171,252,123,197, 75,175,215, 19,223, 45, 0,164,149,226, 84, 92,
+235, 1, 92,173,196, 81,249,126,117,113, 1, 32, 7,192, 77,212,100, 19,240,255,132, 20,163,148,102,255,167, 31, 53, 66, 41,229,
+ 12, 6, 67,204,203, 22, 87,127,129,157, 95, 83, 74,149, 47, 42,174,254,155,144,146,146, 18,157,150,150,246,207,180,180,180, 91,
+ 66,251, 35, 64,128, 0, 1,127, 95,113, 69, 8, 57, 64, 8, 57, 80, 46,136,188,170,248, 46,173, 8, 83,249,186,146, 48,243,170,
+226,254, 51,227, 18, 66, 14, 76,155, 54,237, 53, 0,225, 53, 49,152, 17,242, 76,128, 0, 1, 2, 4, 8, 16,240, 31, 14, 47, 66,
+200, 1, 74,105, 31, 74,105,159,114, 1,244, 52, 71, 67,159,202,255, 62, 11, 85,241, 84,252, 70,229,235,249,243,231,127, 3, 64,
+ 81, 19,131, 69,132,144,144,167, 24,232,240,234,128,167,113, 60,235,111,213,241, 11,156, 2,167,192, 41,112, 10,156, 2,167,192,
+249,247,227,124, 89,241, 95, 6,170, 18,107, 21, 66,174,242,245,212,169, 83,167,163, 6,195,131, 21,228,127,217, 7, 64,136,192,
+ 41,112, 10,156, 2,167,192, 41,112, 10,156, 2,231, 11,126,122,151, 73, 22,218,187,242,247,170,238, 61,235,123,117,113, 29, 8,
+235,176,205, 34, 8, 16, 32, 64,128, 0, 1, 2, 4,252,103, 67, 95,217,219, 84,238, 97,226,166, 78,157, 58,189,226, 94,185,151,
+169, 20,128,172, 10,111, 89,229,120,213,121,214, 28, 14,251, 44, 8, 2, 75,128, 67, 32,132,136, 0, 76,112,115,115, 27,226,230,
+230, 86, 55, 47, 47, 47,161,168,168,232, 55, 0,203, 41,165,182,231,225, 12,110, 64,186,112,118, 76,230,121,176,172, 8,139,238,
+ 60,164,145, 66, 74, 11, 16, 32, 64,128,128, 42,112, 21, 64,171, 74,162, 71, 15,224,214,188,121,243,242,231,205,155, 87,249,222,
+ 13, 0,205,202,195,233,171, 16, 74,150,242,107, 75, 21, 97, 44,142,132,253, 75, 4, 86, 80,109,242, 33,120,204, 0, 1, 5,193,
+ 55,177,201,116,109, 77,226, 55, 9, 36,175, 73, 25,209, 74, 10,202,154,109,220, 52,194,161,202, 61,154, 40,139, 8,185,152,157,
+ 71, 64,120, 11,111,255,232,214, 61,122,210,225, 78,187, 33,233, 42,162,204,122,158,167, 98,158,167, 91, 24,224,176,210,130, 75,
+ 23, 83,169,249,121,115,181,118,109,226, 70,120,244,148,136, 68, 45,173,118,123, 20,101,112, 56, 57,153, 22,252, 39,149,188, 33,
+ 65, 68, 34,242, 83, 44, 84,201,108, 93, 88,150,115,231,120, 54,223,104, 22, 31,183,165,152, 62,219, 17, 75, 29,222,188,149, 16,
+ 34, 6, 48, 65,165, 82,189,174, 84, 42, 95, 41, 41, 41,121,100, 50,153,118, 75,165,210,206,203,151, 47,247, 13, 11, 11,115,210,
+235,245,228,255,216, 59,239,168, 40,174,191,141, 63,119,182,194,178,244,190,244, 38, 34,162, 8,246,138, 6,107, 80, 99,212, 52,
+ 99,138,177,164, 89, 82, 94,211,140, 49, 38,198,196, 88, 98, 18, 19,163, 38,209, 88, 18, 27,198, 18, 59, 26, 75, 44, 96, 71, 84,
+ 80, 1, 97,233, 32,236,194,178,101,102,238,251, 7, 66,208, 8, 44,196, 52,127,247,115,206, 28,216,157,217,103,238,220,153,185,
+243,204,247, 54,142,227, 60,126,254,249,231, 49, 95,124,241, 69, 60, 33,228, 65, 74, 41,223,220, 52, 11, 60, 94, 79,219,254,124,
+119, 0, 8,138,255,234, 45, 66,200,238,230,142, 45,214, 62,148,180, 17, 4, 76,108,106, 59,137, 4, 75,207,102,180,108, 80,216,
+ 54,193,228, 43, 2,132,129, 34, 81,194, 97,253,185,171,108, 76, 44, 6,131,193,248,135, 76,214,157,156,176,114,187,191,157,102,
+ 25, 44, 66, 49,243, 66,250, 13, 39,136,102,180, 13, 15,121, 23, 64,179, 12,150, 66, 34, 89,118,242, 76,190, 39,168, 25,203, 22,
+188,176,210,100, 1,120,222, 12,145,183,128,231, 45,224,121, 51, 4,193, 2,145,175,198,204,133, 7, 0, 94,135,142, 29, 90, 45,
+ 3, 16,108,237, 62,100, 34,183,226,212,209,221,206,132, 47,199,143,223,127,244,124,150, 86,255,252,190, 19,218,146,200, 64,242,
+238,197, 44,252, 96,237, 3, 60, 32,128,120, 81,138,161,254, 26,247,145,211, 39, 61,210,101, 96,223,158,156,127, 64, 16,178,179,
+174,143,223,149,116, 88,236,213,205,227,120,182,182,104, 35, 33,216,154,149, 69,243,255,204, 73,112,119, 34,237, 29,236,108,191,
+146,201, 57, 59,153, 68,146, 94, 84, 86,241,113,126, 9,181,250, 2, 25, 29, 73,228,234, 96,249,177,190, 67,158,114,238,213,239,
+ 25,193, 86,165,214,229, 92, 75, 49,237,220, 58,191,255, 85,121,218,241,209,145,164,139, 53, 38,139, 16, 34, 37,132,108,155, 57,
+115,166, 87,207,158, 61,237, 75, 74, 74,192,243,188,203,166, 77,155, 38,117,234,212, 73,237,227,227,163, 88,181,106, 21,244,122,
+ 61, 4, 65,112, 14, 9, 9,113,126,244,209, 71,249,213,171, 87, 79, 6,176,160, 49,237,192, 64,162,180, 35,112,184,205, 96,137,
+168, 27,192,212,194, 67, 21,162,129,119,219, 32, 98, 1, 0,133, 9,250, 20, 45,109,114, 20,126, 65,192,196,211,201, 73,227,248,
+155, 39, 1,193, 12, 10, 11, 32,154, 1,106, 1, 21,205,128,104, 1,165,102,116,125,232, 59, 0,152,220,146,243, 67, 8, 30,216,
+183,239,164, 87, 65,126, 94,236,194,133,115, 94,139, 12, 34,187, 57, 9,214, 94,184,138,195,247, 98,176, 89, 6,131,241,207,243,
+192, 3, 15,172,208,235,245, 31,159, 56,113, 34,253, 94,105,122,121,121, 69,112, 28,151,213,146, 25, 69,234, 19, 19, 19, 51, 21,
+192,211,183, 62,126,127,234,212,169, 69,127, 54,109, 93,186,116,241,161,148,122,222, 42,251, 11,142, 31, 63,158,203,174,130,127,
+208, 96, 81, 64, 9, 42, 2, 71, 30, 2, 37,176,105,238,206, 40,133, 13,136, 4,176,232, 49, 60, 33, 30,110,174,222,128, 80, 9,
+ 8, 6,128,175, 2,132,154,165,184, 40, 11,224, 43,129,162, 95,192, 83,170,108,246, 81, 89,202,129,194,245, 24,208,205, 31, 78,
+246, 54,152,242, 88,164,235, 55,137,151,151, 44, 79,188,212, 23,192, 83, 77,253,220,215,151, 44,122, 99,210,240,231, 6,244, 79,
+ 32,129, 33, 81, 40, 45,202,193,137,147,191,221, 92,248,205,134,139,253,251,116,108, 51,114,196, 35, 78, 19, 39,189,214, 45,235,
+234,249,110, 7,246,111, 89,224,175, 33,139,179,181,244,205, 22, 69,199,188,229, 19, 7,196,199,207,254,234,155,239, 85,182,106,
+ 87, 84,148,102, 7, 61,249,196,136,104, 47, 23,146,144, 95,106, 93,196, 69,230,103, 59, 63, 62,225, 89,151, 81, 79,127,106,111,
+ 49,235,205,218, 43, 59, 47,218,217,242,220,163,143, 77, 41,255,126,217,187, 94, 87,205,165,243, 1,188,108,133,212,228,153, 51,
+103,122,133,132,132,248,175, 89,179, 6,122,189, 30, 0, 60,194,194,194, 16, 22, 22, 38, 28, 60,120, 16,225,225,225,176,183,183,
+199,129, 3, 7,112,236,216, 49,116,232,208, 65, 37,151,203, 71, 54,102,176,218,132,146,209, 15,245,237,248, 69,112,128,143,170,
+166,241,159, 8, 74, 69,232,245, 70,188, 48, 39, 5,101, 21,213, 24,242, 64, 76,171, 64, 31,251, 43, 28, 68, 80, 10,100,106, 11,
+132,136, 96,242, 88,218, 53,186,163,169,200, 84,135, 78,125,187,159, 73,249, 45,220, 92,184, 13,157,135,124,116, 25, 20, 71,127,
+119, 71,232,158,114,240,187,112,224,187, 22,221, 32,132, 16, 18, 25, 4, 33,251,183,143,225, 27, 51, 94,178,244,187,157,110,229,
+ 37,185, 79,108, 90,255,213, 67, 75,150,126,253, 99, 75, 77, 27,131,193,248,215, 49,208,201,201, 41,174,115,231,206, 3,239,149,
+201,146,201,100,182,130, 32,180,210,104, 52, 87, 90,106,178,166, 76,153,242, 34, 33,228,195,148,148, 20, 0, 64,108,108,236,135,
+177,177,177,119, 29,231,208,193,193,161, 50, 50, 50,242,253,207, 62,251,236,203,198, 52,167, 79,159,238,109,177, 88, 2, 79,157,
+ 58, 85,107,224, 2, 99, 98, 98, 2,239,182,173,157,157,157,208,165, 75,151,172,143, 63,254, 56,143, 93, 34,127,101, 4, 11,184,
+156,127,104,106,180,169,180, 10, 4,184,220,180,161,186,189,171,101,181, 69,248,244,251, 69, 79,205,110, 27,238,140, 10,157, 9,
+123, 14,101,194,194,155, 33,242, 60, 4,193, 2,225,214,223,129,221,220,208,157,159,132,197,235, 46,193,194,139,243, 26,211,252,
+ 67, 68, 3,226,211, 29,250, 60,242,131, 64,169,220,206,134,171, 8,241,119,117,127,237,201,104,110,202, 99,109, 97,168,230, 71,
+182, 9, 36, 7, 47,102,210,239, 26,211,108, 27,228,252,236, 11,227,199, 19, 81,213, 22,201,199,118, 96,242,255,189,157, 81, 92,
+ 82,246, 81, 86, 14, 78,109,221,247,107,128,191,167,235,204, 69,115,222,238, 16, 30, 61, 8,131, 56, 3,126, 61,124,232,105, 0,
+111, 54, 39,157,158,158, 68, 37, 26, 49,164, 75,231,142,239,175, 92,183, 77,197,233, 79, 3,217,171,225,228,212, 13, 75, 23,127,
+236, 49,108,196,232, 5, 0, 6, 88,163,105,167,180,196,247,122,224,105, 88,204,122,179,197,168, 51, 26,202, 82,205, 66, 85,161,
+153,147,113,210, 78,237,219, 20, 22, 20, 36,245,183,230, 28,217,217,217,141,234,222,189,187,122,245,234,213,136,141,141,133,147,
+147, 19,246,239,223,143,179,103,207,162,164,164,132,163,148, 66,173, 86, 99,238,220,185,240,243,243, 67, 69, 69, 5,178,178,178,
+156,101, 50,153, 75, 99,233, 84, 74,165, 99, 63,253,248, 99, 21,199, 1, 16,121,128,254,190,104,243, 11, 81, 89,105,128,147, 90,
+ 14,119, 23,219,186,239,121,139, 73,210,113,240,235,147, 0,236,104,236,216,207,102,208,139,109,131,200, 81, 80, 62,156, 10, 6,
+128,226,232,133,235,180,206,244,180, 15, 37,109, 98,123, 63, 51, 81, 34,193,210,166,174,207,187, 17, 25,132,193,157, 34,212,118,
+182,150,139,200, 73,154,140, 12, 65, 73, 61,219,141,195, 99, 79,188,168, 90,186,108,233, 16, 66,200, 20, 90,111, 18,206,191,162,
+123, 49,211,100,154,247,131,230,232,209,163, 37, 0,176,126,253,122,225,223,152, 78,169, 84,106,254,250,235,175, 61, 38, 77,154,
+180,203, 90,147,213,228,243,168,102,254,174, 43, 0,172, 54, 89,119,106,102,100,100,124,244,209, 71, 31,225,167,159,126, 2, 0,
+172, 89,179, 6,173, 90,181,186,235,111,207,158, 61,107,247,214, 91,111,125, 4,224,203,198, 52,207,159, 63, 31, 52,103,206, 28,
+252,248, 99,205,204,100, 63,252,240, 3, 34, 34, 34,238,170,121,250,244,105,201,219,111,191, 29, 4, 32,239,175, 62, 71,247,173,
+193, 34,132, 80, 74, 41,105, 98,251,107, 94,246,178,104, 88, 44, 0,112,173,185, 59, 75,205,160, 11, 58,132,203,250,239,221,244,
+101, 79, 27, 5,135,247, 22,190,154, 83, 82,162,139,147,112, 16, 1, 64, 16,193, 57,218, 43,146, 62,122, 57,218,175,172,188, 26,
+ 91, 15,230, 30, 78,189, 70,155, 21, 10, 61,119,133,238, 7,224, 93,247,128, 13, 38, 97, 99,223,222,187,242,199,143, 7, 70, 77,
+ 27,211, 30,137, 7, 50, 95, 70, 19,225, 12,181, 74, 46, 33,249, 27, 81, 38,156, 69,151, 46, 67,113,226,196,245,208, 51,199, 18,
+191, 93,183,110,149,240,212, 99, 35, 37,173, 98, 71,161,170, 36, 13, 89,191,205,129, 46,107, 47, 28, 84, 82,153,181,233,115,119,
+ 34,237,109,109,109, 95,244,247, 10, 72,152,254,230,116,105, 66,194,163, 54, 92,229,121,208,188,245, 16,205,122,136,149, 55,224,
+162,238, 12, 66,224,105,245, 91,146, 66,226,164, 86, 59,153,115, 47,172, 73, 51,235,175,153, 97,200, 23,104,149,150, 16,133,140,
+250,122,120, 65,194,241,142,214,232,216,218,218, 6, 21, 22, 22, 66,167,211,193,209,209, 17, 11, 23, 46,132,135,135, 7, 12, 6,
+ 3, 46, 93,186, 68,125,125,125, 73, 82, 82, 18,124,124,124, 80, 86, 86, 6,147,201,132,170,170,170, 2,147,201,212,104,161, 81,
+109,230,191,122,229,181, 87,122, 5,248,122, 74,106, 35, 88,162, 40, 34,186,109, 48,250,245,238,138, 61, 23, 78, 34,241,108, 58,
+ 68, 42,162,118,125,102, 78,113,165, 89, 20,126,176,186,240, 20,249,154, 72,232, 93, 12, 88, 75,162, 76,237,218, 17,149,160,199,
+ 27, 93, 34,237,159,122,243, 73,127,181, 90,201,161,218, 70, 64,181,201, 2, 93,218, 18,184,250,181,135,202,198,134,196,196, 24,
+164, 0, 44,172, 40, 97, 48,254, 72,199,142, 29, 59,169, 84,170,169, 0,250, 24,141, 70,123, 81, 20,209,171, 87, 47, 29,199,113,
+ 7,171,170,170, 22, 37, 39, 39,183,180,173, 76,237,179,138,222,203,244, 6, 4, 4,160,185, 38,171, 41,180, 90,173, 65,163,209,
+ 52,203,100,213,167,168,168, 72, 18, 30, 30, 14,131,193, 0, 81, 20, 81, 89, 89,137,196,196, 68, 84, 84, 84, 64, 20, 69,216,218,
+218, 98,209, 94, 35, 42, 47,172,198,234,111, 62, 69, 81, 81,145,196, 10, 77, 18, 17, 17,129,234,234,106,240, 60, 15,163,209,136,
+221,187,119,195,104, 52,194, 98,177, 64, 38,147, 97,206,150,155, 48,158, 95,141,239,150,125,130,162,162, 34,242, 87, 95, 43, 86,
+122,144,255,158,193,170, 61,176,191,227, 0, 5,145,159,249,205,247,107,147,222,124,249, 49,188, 52,246, 1,223, 89,159,109,238,
+123,225, 26, 93, 3, 0,109,130,201, 19, 79, 62, 24,230,231,100, 39,195,172,165,201, 0,161, 51,255,236,254,206, 94,163,233,237,
+ 90,145,255,219,124, 32,107,215, 91,227, 98, 16,234,235, 16, 26, 26, 74, 20, 25, 25,180,137, 1,195, 40, 94,122,231,115,240,150,
+ 69,150,215, 38, 61, 44,235,210,247, 41, 68,119,223, 41, 41,189,190, 19,201,155,198,225,187,205,191, 85,201,164,176, 25,219, 91,
+102,245,104,248,110,142, 36,166,107,215,110,187,150,126,179,220,198, 83, 19, 74,136,165, 8,168, 56, 8, 62,127, 55,140,134, 98,
+152, 12, 58,152, 69,123,148,103,239,135, 82, 65,173,190,177, 45, 38,177,228,102,241, 85, 91,137,120,147, 68,180,113,233,137,178,
+253,128,243,104,100,158, 62,114,242,122,161,214, 94, 16,165,165,214,232,232,245,250,107, 22,139,197, 21,128,251,190,125,251,224,
+238,238, 14,157, 78, 7,179,217, 12,131,193, 96,113,118,118, 86,148,148,148,192,104, 52,194,104, 52,194,193,193, 1,201,201,201,
+122,158,231, 27,157, 67, 48,237, 26,221, 17,171, 33,158,251, 21, 80,215,126, 39,145,192,149, 55,155, 78,246,235,209, 14, 41,103,
+ 46, 97,253,182,227,157, 4, 1, 37,181,235, 43, 41, 42, 50, 51,169,209,250,215, 83, 30, 84,248,189, 31, 67,109,227,247,150, 52,
+110,143, 12, 38, 29,149, 74,217,252,185,111, 61, 24,209, 39, 82, 80,146,234, 60, 16, 0, 42, 27, 41,140, 38, 1,142,222,161,160,
+ 38, 29, 53, 84, 87,151,159, 63, 15, 30, 12, 6,227, 15,209,170,194,194,194,197,206,206,206, 35,199,142, 29,107,219,167, 79, 31,
+142,227, 56, 44, 92,184, 16,249,249,249, 14, 3, 7, 14, 76, 88,181,106, 85,191,222,189,123,111,244,240,240,152,108, 77, 84,171,
+222, 51, 75, 6,160,214, 68,208,171, 87,175,242,131, 6, 13,194,213,171, 87,185, 91,198, 75, 4, 96,110,105,251,200,127,163,201,
+202,203,203, 67, 81, 81, 17,250, 15, 29,138, 69,115,231,162,119,239,222,136,143,143, 7, 0,236,221,187, 23, 93,212,199,225,146,
+208, 27, 23, 47, 90, 95,212,221,184,113, 3, 37, 37, 37, 24, 50,124, 56,150, 45, 89,130,152,152, 24,180,110,221, 26, 0,144,148,
+148,132,126, 94,233, 80,135,245, 67, 90, 90,218, 95,126,189,252,157, 30,228, 31,137, 96,253, 93,156, 75,167, 39, 34,131,201, 47,
+143, 61,216,121,240,208,126,145, 88,190,110,223,123,145,145,100, 67,141, 1, 81,206, 28,251, 96, 8, 82,175,150, 97,223,113,237,
+ 47,169,215,232,137,123,177, 79,158,135,159,167,171, 26,224, 20,168, 52,241,188,131, 3,172,190,241,206,101, 22,135, 61, 50,229,
+235,241, 83, 31,249,237,173, 41, 79, 68, 97,245,186,211, 88,240, 83,218,235,102, 51, 86,142,236,229,146, 13, 88,223, 22,205, 94,
+101,251,252,210,111,150,219,120,185,202, 9,178, 22, 65, 48,228, 64,168, 46,129,217,120, 19, 21,229, 55,145,147, 87,140,178, 42,
+ 41,178, 10,136, 33, 55,223,180,218, 90,221,242, 42,233,207, 91, 55,204,123,106,212,200,177,174, 87, 78,124,115,108,203,126,131,
+251, 99,253,127,169, 84,216, 5, 56, 29, 60,177,215,185,220, 32,253,214, 26,157,234,234,234,141,191,252,242,203,163, 1, 1, 1,
+238,231,206,157, 67,117,117, 53, 68, 81,196,224,193,131,129,122, 19, 96,166,165,165, 85, 27, 12,134,194, 11, 23, 46,232,179,179,
+179,171, 0, 44,110, 74,251, 86,131,245,186, 66,165, 77, 16, 25, 29, 25,238, 13, 8, 6,180, 9,243,130, 69, 64,223,139,215,233,
+231, 45, 62,201,212, 82, 19,193, 34,232,222, 54,136, 44, 6, 65,247,228,253, 11,195, 59,246,155,134,230, 68,176, 34, 67,201,128,
+168,112,205,210,133,115,222,116,118,113,247,147, 64, 48,128, 89, 13,222, 77, 0, 0, 32, 0, 73, 68, 65, 84,240, 21, 84, 44, 61,
+ 6,105,229, 21, 56,248, 62, 8,193,177, 59,150,126, 57,191, 82, 16,232,250,250,213,131, 12, 6,163,206, 80,188, 19, 30, 30, 62,
+234,243,207, 63, 87,157, 57,115, 6,149,149,149, 56,126,252, 56,230,205,155,135,145, 35, 71,194,215,215,151, 75, 76, 76,180,123,
+249,229,151, 71, 93,190,124,185, 8,192,172, 38, 30,192,110,174,174,174, 78,197,197,197, 90, 0,242, 91, 38,139,100,102,102, 34,
+ 41, 41,137,139,142,142,166,133,133,133,252,148, 41, 83,156,244,122,125,251,207, 62,251,236, 48,128,130,251, 37,146,181,113,227,
+ 70,156, 62,125, 26, 51,163,163, 49,205,219, 27,174,174,174, 56,120,240, 32, 40,165,176,179,179, 67,105,105, 41,126,252,241, 71,
+196,197,197, 89,157,158,159,127,254, 25, 39, 79,158,196,251, 29, 58,224,101, 27, 27, 56, 58, 58, 34, 41,169,166,195,190, 82,169,
+ 68, 78, 78, 14,246,239,223,143,222,189,123,179, 11,186,133, 88, 29,125,137, 35, 68, 74, 8, 60, 45, 22, 3,204, 60, 5, 33,240,
+142,140, 36,242, 22,185, 58, 14,239, 45,254,118, 27, 85, 74,204, 24, 63, 42,214, 27, 6,140,135, 1,227,199, 13, 15,215,168,148,
+ 82,124,182, 46,149, 74, 57,188,119, 47, 14,176, 93, 16,105,229,226, 96,243,238,131,113,109,145, 93, 96,192,181, 27, 21,187, 82,
+ 82,172, 31,183,233,218, 53,148,229,104,177, 72,111,226, 33,145, 72, 81,110,160,200,201,193,183,133,133, 48, 54, 55, 45, 18, 41,
+ 25,224,169, 9, 37,180, 32, 17,198,155,151, 80,121, 51, 7, 37, 37, 57,208,149,151,160,178, 74, 7,157,174, 10,121,185, 90,236,
+252, 77, 91,198, 87, 11,135,173,213,253,105,119,213, 91,167, 78, 29,190,116,226,216,110, 59, 7,247,246,206,145,129, 74,209,206,
+ 94, 99,127,240,120,170,163,182,176, 58,237,167,157, 85,214,230,229,226,141, 27, 55,150,157, 58,117, 42,205,215,215, 55,219,209,
+209,145, 18, 66,144,151,151,119,219,146,156,156,172,220,185,115,103, 85,118,118,246, 22, 0, 9,205, 29,162,161,125, 40,105,211,
+175, 91,171,217, 67,226,162, 0,193,128,132,184, 54,232,221, 41,104,118,251, 80,210,166,197,254,138,214, 84, 17, 30, 93,211, 47,
+252,232,234,158,227,142,172,236, 18,110,202,253,161,217, 58, 68,196,203,211, 30, 13,116,112,177, 53,113, 68,208,131,200, 28, 1,
+ 85, 40,225,124,159, 32,178,152,149, 36,187, 42, 64, 24,245,196, 99, 69,203,126,216,246,149,155,136, 69,172, 8, 97, 48,238,242,
+ 96,225,184,113, 99,198,140, 81,217,218,218,194,198,198, 6,171, 86,173,194,243,207, 63, 15,165,178,166,207,146, 74,165,130,173,
+173, 45,198,140, 25,163, 34,132, 60,107,133,100,105, 69, 69,133,122,196,136, 17,126, 0, 84, 0,236, 76, 38,147,186,184,184,216,
+129,227, 56,199,182,109,219,122,204,156, 57, 51, 92,175,215,183,223,186,117,107, 33,128,226,150,164,187,188,188, 28, 87,175, 94,
+197,142, 29, 59, 48,113,226,196, 74,158,231, 21,106,181,122,250,159,140,206,200, 60, 61, 61, 85, 26,141,198,149, 82,218,154, 82,
+202, 81, 74,253, 91,162, 37, 8, 2, 58,118,236,136,189,191,158,196,210,245, 71, 48,255,203,149,200,206,206, 70, 68, 68, 4, 68,
+177,229, 29,154, 59,117,234,132,253,251, 15, 97,245,150, 19,152,183,240, 43,228,228,228, 52,216, 38,139,209,204, 8, 86, 83,161,
+185,200, 32,210,206, 51, 74,185,252,237, 97, 33, 17,210,182,239,129, 72,109,177,233,187,173,221,222,252,232,235, 83,237,125,201,
+184,179, 57,180, 89,245,232,103, 51,232,197,182,193,100,253,153,212,136, 71,134,245,246,195,178,245,170, 55, 0,224,145,254,193,
+ 56,145, 90,132,227,231, 11,215, 95,184,214,178, 49,139,106,137, 8, 38,161, 28,197, 83,109, 66, 60, 39, 44,156, 49, 74,229,238,
+166,194,156,175,146, 33, 2,171,173,191,152, 1, 0,190, 0,202,127,143, 83,144,218,104,142,147, 32,162, 89,161, 76,142,208,221,
+249, 89,103, 30,117,229, 92,136,190,162, 24,249,218, 27,208, 85,232,225,228, 32,131,163, 74, 2,141,183, 7, 84,142,190, 16,165,
+ 69, 78,151,174,233, 59, 3,176,122,224,205, 10,139,252,133, 35, 71,246, 28,238, 17, 61,161,186, 77,144,140,151,202, 36, 54, 39,
+ 83, 51,149, 58,131,252,101,107, 53, 40,165, 60, 33, 36,225,208,161, 67,147,143, 30, 61, 58,194,219,219,155,140, 29, 59, 22,131,
+ 6, 13,130, 82,169,132,193, 96, 64, 89, 89, 25,182,111,223, 78,120,158,239, 14, 0,222,222,222,254,129,129,129,223, 17, 66,114,
+175, 95,191, 62,214,154,253, 40, 20,138,249,239, 78, 30, 34,227,205,122,204, 90,188, 29,239,190, 20,143,153, 47,197,201, 18, 38,
+230,206, 7, 48,176, 69, 39, 92,228, 33, 10,213,232,254,228,175, 53,189, 8, 9,186,159,220,245, 65, 56,112,218,106,137,216, 88,
+ 34,147, 72, 73,235, 54, 62, 70,153,144,187, 14,196,198,135, 74, 92,251, 0,234,112, 66,213, 81,248,226,179,119, 43,151, 47, 95,
+190,151,114,152,147,154, 73,211, 88,241,193, 96,220,157,202,202,202, 73,239,191,255,254,202,208,208, 80,219,168,168, 40, 44, 89,
+178, 4, 67,134, 12,169, 51, 87,237,218,181,195,141, 27, 55, 48,107,214,172,234,170,170,170,231,173, 40,155, 68, 66,200,197,164,
+164,164,136,132,132, 4,239,222,189,123,147, 54,109,218,200,148, 74,165,104, 52, 26,237,242,242,242,148,105,105,105, 72, 78, 78,
+190, 90, 93, 93,125,142, 82, 42,180, 36,221,179,102,205,170,116,115,115,179,155, 58,117, 42, 62,249,228,147,220, 95,127,253, 53,
+230,207,230,133,183,183,119, 16,199,113, 98,110,110,238,117, 31, 31, 31,239,156,156,156, 22, 53, 14,175, 13,150,159, 61,123, 22,
+135,210, 69, 40,236,156,145,153, 86,129,189, 63,111,193,152, 9, 19,193,243, 45,111,173,112,250,244,105,172,217,157, 6,175,160,
+ 8, 84,167,157,198,198,141, 27,241,252,243,207,255, 41,205,102, 30, 27,185,111,219, 96,213, 30,224,157, 43, 67, 67,137, 66, 97,
+196, 91, 3,187,249, 76, 27,245, 64,168,132,175,202,131, 40,138,144, 0,112,179,231,240,237, 55, 75,131,214,111,254, 37,169,157,
+191,100, 9, 76,226,172,115, 5,180,202,106, 87, 47,197, 7, 11,190, 63,242,240, 15,179,251, 72,159, 31, 29,225, 12, 0,114, 25,
+135,197,107, 47,240, 68,138, 15,154, 25,165,234, 41,149,113,107, 44,148,218, 82,129,102,251,120, 57,219, 61, 60, 32,214,231,161,
+ 1, 29,209,190,141, 63, 68,222,140,247,191, 76,196,250, 29,103,191, 76,187,222,120,183,255,219, 76, 90,144, 19, 78,106, 10, 94,
+227,164,248,128,212,179, 87,158,158,144,203,165,152,218,202,207, 70,129,102, 52,193,209, 85, 25,190,122,115,250,212,248,183, 95,
+ 26,230, 98,214,169,200,149,204, 50, 64,168,134,157,173, 26,106,175, 94,112,114, 8, 67,117, 69, 30,228,210, 20,149,167, 91,206,
+232,230, 24,172,205, 59,116,233, 47,141,109, 45,121,239,243,147,110,166, 42, 80,222,156,194, 85, 85, 19,186,113, 79, 69, 70, 51,
+ 47,116,139,175,175,239, 68, 81, 20,221,121,158, 55,187,187,187,203,127,250,233, 39,216,216,216,128,227, 56, 68, 71, 71,195,198,
+198,198,164,209,104,202, 1,192,195,195,195,178, 96,193, 2,233,184,113,227,172,138,102, 70, 6, 19,191, 17, 3,218,246,112,117,
+144, 96,229,230,163,216,178,247,226,150, 32, 31,187,225,207, 14,111,139,184,206, 62, 61, 34,131,137, 95,234, 53,122,163,249,119,
+168, 5,245,123, 17,182, 15, 37,109, 58, 13,120,231,174,189, 7, 27, 34,232, 20,196,203, 33, 20,132, 72, 64, 65,128,234, 92,240,
+ 57,171, 33, 9,126,153,110, 78,252,192,176,236,155,229, 31,165,102, 82, 22,181, 98, 48,154,224,204,153, 51,191,116,238,220,249,
+141,177, 99,199,206, 29, 59,118,172,226,233,167,159,150, 28, 59,118, 12,162, 40,162, 99,199,142, 88,190,124, 57,191,110,221, 58,
+139,209,104,156,126,230,204,153, 95,172, 44,155,140,132,144, 51,219,183,111,119,185,120,241,162,139, 76, 38,115, 19, 69,209,169,
+170,170,170,216,100, 50,149,148,149,149, 21, 2, 40,107,105,181,125,117,117,181,205,197,139, 23,143,155,205,102,205,212,169, 83,
+ 91,199,199,199,135,199,198,198,118, 78, 73, 73,105,113, 83, 21,142,227,228,162, 40, 26, 40,165,182,181,187,113,119,119,183, 43,
+ 42, 42,170,108,137,158, 68, 34, 65, 89, 89, 25,116,185, 25,168, 42, 46, 70,107, 73, 21, 58,184,184,195,222,222, 30, 22, 75,203,
+251,218,232,245,122, 40,249, 28, 92, 63,121, 29,197,197,153, 8, 11,234, 0, 59, 59, 59, 24,141,198,191,237,154,185,223,204,213,
+109, 6,235, 15, 15, 66,127, 50,222, 89,142, 79,158, 30, 29, 44, 15, 14,244,129,169, 40, 25,167, 51, 42,241,206,138,206,105, 18,
+185,189,241,165,167,250,119,232, 27,239,142, 62,113,157, 72, 96,192, 59, 47,206,157,251,213,196, 72, 63,242, 86,234, 13,250,165,
+ 53, 59, 62,127,133, 94,111, 19, 68,190, 79, 58,153,251,156,175,155, 1, 20, 20, 73,201,121, 56,155, 94,246,253,197,235,244,122,
+179, 46, 58, 57,183,234, 84,202, 57, 23,240, 6,228,103,252, 18,238,229, 21, 8, 80, 11, 44, 38, 3,142,157, 58,143,229, 63, 38,
+241, 39,207,102,254,223,197, 76,106,213,195, 54, 61,251,230,222,140,156,242,248,247, 39,117,198,224, 30,254, 79,127,180, 34,229,
+177,186,206, 42,148, 98, 80, 71,167,139, 99,250,218,171,108,165, 38,240, 80, 32,229, 74,249, 30,107,116,243,138,233, 41,111, 55,
+242,240,217,179,103,158,241,241,114,140, 31,220,201,214,205,221, 1,114,123,183, 64, 40,236, 92, 32,242,122, 84,149, 94, 6, 21,
+170, 65, 32, 6, 55, 39, 15,252,252,252,122, 78,157, 58,213,102,226,196,137,208,235,245, 88,185,114, 37,150, 44, 89, 2, 63, 63,
+191,158, 55,110,220, 56,220, 28, 45, 81, 20,221,183,110,221, 10,212,180,117,192,190,125,251,160,209,104,224,232,232, 8,157, 78,
+135,177, 99,199, 42,102,204,152, 1, 0, 56,117,234,148,204,214,214,182, 25, 55, 17, 70, 15,234, 17, 76, 32, 24,176, 97,231,133,
+ 18,216,224,153, 77,123, 46,245,120,118,104,176,235,224,174,222,100,251,193,235,163, 1,124,218,252,155, 83, 0, 68,195,109, 81,
+ 82, 52,179,247,224,122, 74,133,200, 96,114,117,221,158, 34,187, 81, 67, 98,108,229, 50,142,208,234, 28,136, 68, 78, 22, 45,249,
+ 86,111, 39,197,183, 96, 48, 24, 86,113,226,196,137, 21, 93,187,118,253,237,187,239,190,123,149,227,184, 30, 70,163,209, 29,128,
+184,123,247,238,124, 65, 16, 14, 25, 12,134,197,201,201,201, 87,154,249, 16,166, 0, 74,110, 45, 87,238,101,122,165, 82,233,143,
+ 21, 21, 21,179, 5, 65, 24,181,107,215,174,249, 35, 70,140,192,207, 63,255,252, 44,238, 62, 82,184,181,101,105, 69, 94, 94,222,
+117, 95, 95, 95,183,128,128, 0,183,202,202,202, 2,165, 82,233, 5, 32,163, 37,122, 74,165, 18,135, 14, 29,194,224,158,189,112,
+102,111, 22, 34, 60,253,208,119,204, 83, 72, 76, 74,130, 68, 34,105,233,113,227,208,161, 67,120,120, 72, 95,108,218,180, 9, 65,
+ 49, 81,120,233,165,151,176,123,247,110, 72,165,108, 54,189,191,196, 96, 17, 17, 51,246,252, 56, 71, 14,209,130, 13,107, 62,193,
+222,147, 85,166,180, 28,188,215, 58, 23, 95,110,128, 78, 44, 40,217,248, 92,151,131, 87, 63,124,246,233, 4, 85,191, 62,253,209,
+175,119, 95,105,219,232, 62,111,160,222,248, 27,132,144,168,198,198,202,160, 34,230, 46,219,152, 54,110,221,142,203, 4,188, 14,
+143, 13,235, 68,169,136,185,141, 70,190, 26,210,228, 13, 64,249,113,108,219,123, 20, 26,207, 92, 92,185,150,133, 77, 59,142,223,
+ 40,215, 85,253, 64, 8, 86, 95,204,108, 56, 42,114,167,102,137,206,244,226,160,151,183,125,241, 72,255,144,254,211, 30,111,143,
+ 45, 11, 30, 84, 92,211,150, 67, 16,120,244,111, 79, 65, 34, 20, 42, 17, 2,142,102, 72,233,178,109,185,137,122,147, 48,205,218,
+116,230, 21,211, 20, 0, 41,193,206,196,225, 66, 58, 6,143,232,229,241, 97,215, 24,193, 67, 95,144,130,188,236,116,220, 52,216,
+ 32,167,132, 0, 20, 87,173, 62,118, 0, 55,110,220, 56,220,169, 83, 39, 0,128,193, 96, 64, 78, 78, 14,120,158,135, 86,171, 61,
+220,220,252,228, 56,174,104,200,144, 33,238, 70,163,145,127,252,241,199,165,197,197,197, 8, 15, 15,175,137,194,233,116,248,229,
+151, 95,234,122,155, 92,184,112, 1,145,145,145, 86,167,211,221,201,118, 76,199, 72, 23, 92,184,156,141, 44,109,197,218,212,107,
+212, 28, 25, 76,214,158,189, 84, 48,185,123, 7, 15,184, 56, 40,198,220,205, 96, 53,164,217, 62,148,180, 1, 65,119,136,150,154,
+ 94,132, 4,221,219,135,146, 54,214,244, 28,188,155,166, 84,138,103,231,255,152, 57,125,253,193,162,132,255,123,174,151,125,143,
+110,131, 21, 16, 45, 84, 95,101,180, 92,184, 70,117, 45,209,252,179, 48, 77,166,249, 95,213, 60,118,236,216, 37, 0,207,253, 23,
+142,125,255,254,253, 83, 1, 32, 54, 54,118,221,166, 77,155,230,172, 92,185, 82,161, 86,171, 59,253, 25, 77,173, 86,123,249,214,
+118, 69, 26,141,166, 77, 73, 73,201,121, 95, 95, 95, 69,115, 52,101, 50, 89, 81,251,246,237,221, 31,122,232, 33,240, 60,143,244,
+244,116,100,101,101, 97,232,179,207,192,217,217, 25,199, 83, 83,145,158,158,142,119,223,125, 23, 70,163, 17,215,175, 95, 47,106,
+ 74, 83, 46,151,155,163,162,162,228,195,134, 13, 3,207,243,200,200,200,192,141, 27, 55,240,242,203, 47,195,209,209, 17,151, 46,
+ 93, 66, 70, 70, 6,102,204,152, 1,163,209,136,172,172, 44,243,223,113,142,254,103, 12, 22, 37, 16, 32, 90, 80,126,114, 38,190,
+222, 6,179, 69, 64,204,133, 28,154, 89,111,147,101, 29,252,200,142,179,231,211, 82, 83,142,247, 83,160,226, 28, 40,208,172,122,
+239,180, 44,154,223, 41, 66,170, 7,175,179, 71,209, 47,184,166,213, 85,166,181, 96,218, 25,193, 44,142,237,208,185,235, 90, 17,
+ 84, 46, 10,116, 61, 15,236,151, 82, 92,187,112, 29,169, 45, 9, 23,231,228, 80, 45,128,135, 2,125, 73,239,173,135, 50,231,142,
+ 27, 26, 17,245,252,168,182,168,170,212, 65, 70,171,113, 62, 95,129, 47,126, 46, 56, 89,162, 51,189,126,227, 6, 77,105, 73,198,
+ 95, 43,163, 21, 0,214, 69, 4, 74,169,206,112,225,237,135,251, 6, 4, 17,184,161,160,168, 28, 27,147,242,142,105, 75, 27,239,
+ 85,211, 64, 4, 11,147, 38, 77,130, 78,167,195,186,117,235,176,107,215,174, 22, 69,176,114,114,114,194, 0, 64,163,209, 20,216,
+219,219, 75,159,121,230,153,218,161, 26, 80, 81, 81,129,146,146, 18,211,212,169, 83, 21, 0,160, 80, 40, 44,131, 6, 13,178,250,
+ 53, 39, 44,192,209, 71, 10, 35, 18,247, 93, 6,164,248,241,214, 85,248,227,150, 3, 89,147,219,183,114, 65,152,191, 67, 72,172,
+134,216, 90, 51, 77, 14, 80, 51, 85,206,201,157,179,194,171,175,204, 0,165, 22, 28, 90,226, 28,222,235,249,178,137,104,225, 8,
+235,103,175, 80, 45,128,201,145, 65,100,197,148, 15,119,190,209, 49, 42,181,251,107,147,134,219, 83,194, 38, 70,103, 48,254, 23,
+ 72, 73, 73,169,136,142,142,126,166, 95,191,126,211,244,122,253,130,123,161, 73, 41,229,189,188,188,242,188,188,188,194,205,102,
+115,179,230, 50, 53,155,205, 47,127,241,197, 23,159, 91, 44, 22,247,218,239,140, 70, 35,214,172, 89, 3,179,217, 12,185, 92, 14,
+149, 74,133,140,140, 12, 72, 36,146, 34,158,231,155,108,119, 43,138,226,213, 47,191,252, 50,196,108, 54,215, 53,237,224,121, 30,
+171, 87,175,134,209,104,132, 82,169,132, 90,173, 70,122,122, 58,228,114,185, 89, 20,197,171,236,202,104,129,169,111,200,127, 68,
+250,147,241,160,120, 11, 20, 4, 28, 62,108,104, 98,231,186,237, 0,220, 57, 1,180, 53, 14,183, 93, 56,233,171,144, 72, 86, 2,
+ 64,181, 40,140,187,112,137,238,249, 55,189,217, 16, 66, 72,128, 47, 70,123,187,217, 45,126,109, 76,180,221, 39, 63,156,169,204,
+ 43,173, 28,151,157, 77,183,223,171,116,250,123,146, 32, 31,103,188,161, 84,192,137,231,145,154, 89,132,213, 55, 10,233,181,230,
+106,106, 52,154,170,128,128, 0,184,184,184,160,180,180, 20, 89, 89, 89,208,106,181,170,150,166,211,199,199,167, 43, 33,100,179,
+ 40,138, 54,119, 70,184,106, 77,152,183,183,183,191, 66,161,184,173,145,123, 99,154,109, 67,201,156,168, 80,231, 73, 23,174,150,
+175, 62,159, 46,212,153,160,200, 32,242,126, 76, 27,183, 23,206,165,151, 46, 59,123, 69,120,179, 57, 17,172, 59, 39,123,182,118,
+236, 43,171,174,207, 96,210, 79,164,152, 2,130,188, 11,215,232, 36, 22,201, 96,154, 76,147,105, 50, 77, 22,193,178,214, 89,255,
+101, 11,128,168,251, 69, 19,128, 52, 48, 16,173, 0, 40,254,229,233,124, 27, 64, 21,128,183,255,173,233,140,137,129,236,127,249,
+ 90, 98,154, 76,147,105, 50, 77,166,121,255, 47,172,218,163, 25, 33, 94,220,227, 70,149,127, 81, 58, 63, 4,240,225,191, 59, 4,
+ 79,217,212, 50, 12, 6,131,193,184,175,225, 88, 22, 48, 24, 12, 6,131,193, 96,220, 91, 8,128,168,187,173,104, 78,221, 42, 33,
+ 36,170,185, 59,110, 74,159,105, 50, 77,166,201, 52,153, 38,211,100,154,247,159,102, 83,218,247, 75,219, 46,242, 87, 78,165,198,
+ 26, 0, 50, 77,166,201, 52,153, 38,211,100,154, 76,243,127, 17, 86, 69,200, 96, 48, 24, 12, 6,131,193, 12, 22,131,193, 96, 48,
+ 24, 12, 6, 51, 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,152,193, 98, 48, 24, 12, 6,131,193,248,
+215,240,151,246, 34,100, 48, 24, 12, 6,131,193,248, 95,132, 3, 0, 66, 8,189,181,244, 97, 89,194, 96, 48, 24, 12, 6,227,239,
+226,126,245, 32,117, 83,229, 80, 74, 9, 33,132,162,102,240, 81, 6,131,193, 96, 48, 24,140,191,133,251,209,131,112,245, 29, 36,
+128, 56,118,154, 25, 12, 6,131,193, 96,252,157,220,143, 30,228,182, 8, 22, 59,197, 12, 6,131,193, 96, 48,254,110,238, 71, 15,
+194,122, 17, 50, 24, 12, 6,131,193, 96,220, 99, 88, 47, 66, 6,131,193, 96, 48, 24,140,123, 12,139, 96, 49, 24, 12, 6,131,193,
+ 96,252,151, 12, 22, 33, 36,138,105, 50, 77,166,201, 52,153, 38,211,100,154, 76,147, 25, 44, 6,131,193, 96, 48, 24, 12, 6, 51,
+ 88, 12, 6,131,193, 96, 48, 24,204, 96, 49, 24, 12, 6,131,193, 96, 48,131,197, 96, 48, 24, 12, 6,131,193, 96, 6,139,193, 96,
+ 48, 24, 12, 6,227, 31,130, 0,184,107, 79, 0, 74,233,121,171, 69, 90,208,155,160, 41,125,166,201, 52,153, 38,211,100,154, 76,
+147,105,222,127,154, 77,105, 55,199,127,252,171, 13,214, 95, 57,208, 40, 33, 36,234, 94,103, 20,211,100,154, 76,147,105, 50, 77,
+166,201, 52,239, 63,205,251, 13, 86, 69,200, 96, 48,254,215, 8, 99, 89,192, 96, 48,254,106,164,255,212,142, 9, 33, 92, 61,131,
+ 39, 2,160,244, 79,134,211,254, 10,205,127, 43, 4,224,218,204,154, 37, 85,230,229, 53,235, 28, 26,189,189,249,139, 51,103,242,
+180, 38,127, 24,140,255, 28,233,229,135,234,254,111,229,212,155,212,220, 14, 0, 0,122,229,230,175, 13,222,239, 97,142,189, 88,
+230, 49, 24, 13,144,156,156, 92, 21, 16, 16,128,118,237,218, 93,201,207,207,255,138, 82,186,140,229,202,191,200, 96,181,241,180,
+237, 28,224,235, 54,104, 71,114,246,123,141,109, 23, 27, 27, 43, 75, 72, 72, 88, 6, 96, 84,253,239,135, 14, 29,122,219,118, 50,
+153,172,164,172,172, 44,248,192,129, 3,124, 83,251,142,141,141,149, 37, 12, 29,250, 71,205, 97,195,254,160,153,237,226, 18,114,
+106,233, 82,190,222,151,132, 0,132, 2, 20, 0,194,195,195, 15,115, 28,231, 67, 8,105,200,200,213,253,207,113, 53,126, 78, 20,
+197,220,212,212,212,158, 77,165, 83,163,209,196, 3,120,213,138,236,156,175,213,106,247, 54,182,129,195,158, 61, 25,148, 82, 39,
+137, 68, 98,213,249, 17, 4, 1,242, 11, 23,110, 98,230,204, 64,118,233, 51,254,235,180,114,234,205, 13, 29, 58,180, 31,128,186,
+235,249,245,167,230,255, 97, 59,137, 68, 98, 76, 76, 76, 92, 77, 41,101, 47, 21, 12, 70, 3,236,217,179, 7, 19, 38, 76,192,185,
+115,231, 90,237,216,177, 99,145, 70,163,153,152,151,151, 55,136, 82, 90,204,114,231, 31, 54, 88,225, 26,251, 86, 30,174,174, 27,
+ 63,250,224,125, 0,120,175, 49, 35,228,237,237,189,204,207,207,111,208,130, 5, 11,176,109,219, 54, 4, 5, 5, 65, 46,151, 67,
+ 34,145, 64, 34,145,128,227, 56, 72, 36, 18, 76,157, 58,213,233, 86, 26,249,166,204,149,183,183,247, 50, 95, 63,191, 65,243,231,
+207,199,142, 29, 59, 16, 16, 16,112, 87,205,105,211,166, 57, 1,144, 1, 16,234, 4,228,242,218,183, 96,122,203, 52,249,156, 58,
+117,202,221,198,198,166,230,181,152, 82,136,162,120,219, 66, 41,173, 91, 4, 65, 64,175, 94, 86,191, 29,191,154,150,150,214,179,
+178,178,242, 54,141,218,125,212,254,127, 75,175, 81,131,101, 50,153, 92,147, 79, 28, 6, 49, 95, 3,132, 82, 80,206, 5, 80, 4,
+ 3,156,242,174,219,151,150,150, 98,224,192,129,174,236,178,103,220, 15,230, 42, 33, 33,225,129,176,176, 48,205,156, 57,115,144,
+145,145,129,240,240,112, 8,130, 0, 81, 20,111,251, 59,118,236, 88,197,168, 81,163, 8,203, 53, 6,227,118,252, 71, 44, 91, 68,
+ 5,203,248,154, 79, 78, 0,190,129, 78,167,195,115,207, 61,135, 45, 91,182,180,238,218,181,235,108, 0,147, 88, 78,253,131, 6,
+171,149,175,173, 70,165,176,219,186,244,235, 47,136, 69,151,239,212,208,118,132, 16,110,200,144, 33, 95,249,250,250,246, 95,176,
+ 96,129,157, 92, 46,199,165,113,227,112,179,186, 26,166, 79, 62,129,147,155, 27,194, 39, 78,132, 43,207,131, 63,115,198,170,125,
+215,215,156, 63,127,190,157, 92, 46, 71, 78, 78, 14, 76, 38, 19, 60, 60, 60, 96,107,107, 11,133, 66, 81,183, 88,169, 9, 27, 27,
+ 27,236,217,179, 7, 82,169,180,110,145, 72, 36,119,253,236,233,233,217,156,236,154,223,186,117,235,118,233,233,233,246,165,165,
+165,232,218,181,171,142, 16,114,174,118, 37,165,180,221,185,115,231,236,173, 21, 35,230,107,168,204,254, 26, 98,217, 70,192,233,
+ 97, 8, 14,143,162, 26,193,119,125,208,136, 34,123,129,103,220, 23,230,138, 12, 25, 50,164,111,104,104,168,247,156, 57,115,100,
+ 50,153, 12,167, 79,159, 70, 97, 97, 33, 92, 93, 93, 97,107,107, 11,153, 76, 6,137, 68, 2,153, 76,198, 50,140,193,104, 0, 42,
+ 88,198, 71,119,236, 94,247,121,229,158,197, 48, 58,198, 32,247,189,247,176,104,209, 34,180,106,213,170, 35,203,165,127,208, 96,
+ 69, 7, 58, 57, 42,168,124,235,138, 37, 11, 20, 48,235,157, 46,157, 60,130,182,131, 39,214,154,133,243,245, 76, 11, 1,192,201,
+100,178, 71,230,205,155,199,201,229,114, 0, 64, 71, 65,128,198,108, 70,121,100, 36,108,157,156,224,111, 54, 3,102, 51,140,183,
+214,255,225,130,176, 66, 83, 34,145, 64, 46,151, 67, 42,149, 66, 38,147, 65, 46,151, 55,110,176, 42, 43,239,218, 19,162,214, 68,
+237,217,179, 7, 22,139, 5,163, 70,141,186,171,217,106, 42,157,245,209,106,181,123, 53, 26,205, 57, 81, 20,123,138,162, 8, 66,
+200, 57,173, 86, 59,176,118,189, 70,163,137,111,223,190,253,171, 0,230, 91,165, 41,148, 66, 44, 93, 11,251,110,197,168,248,205,
+ 13,196, 46, 30, 2, 2,112,244,108, 22, 14,166,100,161,168,180, 2, 81,193,110,120,100, 96,212, 93, 13,214, 95,209, 11,132,105,
+ 50,205,191, 88,147,200,229,242,192, 57,115,230,144, 90, 3, 85, 27,161,174, 53, 86,181,255,215, 86,225,223,161,185,145,229, 39,
+211,100,154, 0,145,200,150,157, 73, 62, 58, 30, 0, 42, 46,110,194,148,199,187, 67,167, 75,199,164, 73, 51,144,155,155,139, 43,
+ 87,174,156,254, 59,211,121,223, 26, 44, 66, 8,165,148, 54, 43,140,238,235, 75,108,236,121,213,198, 47, 23,125,228, 96,111,175,
+114, 75,222,157,136,172,172,252, 70,127, 35,138, 34,253,229,151, 95,112,121,252,120,116,224,121,148,205,155, 7,162,209,160,237,
+240,225,144,155,205,168, 56,113, 2,114,181, 26, 10,181, 26, 13,181,129,106, 72, 51, 71,171,133, 84, 42,133, 90,173,134,157,157,
+ 29,148, 74,101,157,177,146,203,229,144,203,229, 86,107, 82, 74, 33,149, 74,113,254,252,121,100,101,101,193,201,201, 9, 71,142,
+ 28, 65,124,124,252,109,230, 74, 34,145,128, 16, 98,181,110,125,125, 65, 16,238,106,192,208, 68,213,224,237,103,208, 21,112,121,
+ 18,186, 99, 26,192,121, 12, 44,212, 9, 34, 21,145,124,169, 0, 95,207,122, 18, 0, 16, 51, 98, 22, 70,245,143,100, 17, 44,198,
+125,131, 32, 8,184,124,249, 50, 46, 94,188, 8,137, 68, 2, 7, 7, 7,216,217,217, 65, 38,147,213, 45, 28,199,177, 8, 22,131,
+209, 8,217,155,199, 79, 37,132,204,245,247,247,223,245,213,156, 57,161,241,241,241, 0,128,189,123,247,226,187, 39,158,192,123,
+192,227,139, 9,201,159, 76,233,187,127,117, 90, 90,226, 65,254, 19, 6,171,246,192,154,115,128,132, 16, 18,234,233,240,195,172,
+183, 95, 12, 12, 8, 14,241, 60,190,253, 39, 92,187,150,139,130,130,178,134, 12, 5, 37,132,136, 0,104, 96, 96, 32,202,170,171,
+161, 49,153, 32,209,104,160,118,117,133,244, 86,228, 74,102,103, 7,185, 90, 13,121, 3, 17,172,198, 52,171, 77, 38, 40, 20, 10,
+168,213,106,168,213,106, 40,149, 74,200,235,153, 43,107, 52,235,153, 54, 72,165, 82,156, 61,123, 22, 61,123,246,132,159,159, 31,
+126,252,241, 71, 12, 28, 56,240, 15, 81,172,230,154,171,187, 25,172,122,141,223,155,108,220,126, 27,138, 80,240,246,143,128, 83,
+ 61, 0, 51,117,128,145,122,215, 84, 9,242, 34, 62,221,116, 13,151,179,139, 33, 8, 98, 93, 53, 33,131,113, 31, 64, 9, 33, 52,
+ 34, 34,130,148,148,148, 64, 38,147,213,153,171,214,173, 91, 35, 55, 55,183,206, 92,213, 70,180, 24, 12,198,221,145, 72, 36,179,
+ 19, 19, 19, 67,109,108,108,240,225,135, 31,194,222,222, 30,199,102,207,198,183,114, 57,108, 1,124,101, 54,191, 10,224, 47, 53,
+ 88, 45,241, 32,255,169, 8, 86,115,241,241,241,249,168,107,207,174, 61,131,219,116, 82, 30,223,185, 9,233, 87,178, 80, 92, 92,
+ 14, 74, 97,104,172, 96, 4, 0,153, 76,134,170,247,223, 71, 89,187,118,136, 26, 57, 18, 82,179, 25, 21,199,142, 65,174, 86, 67,
+ 21, 19, 3, 98, 50, 65, 86, 80, 96,117, 97, 91,171,233,238,238, 14,185, 92, 14,165, 82, 9, 27, 27,155,154, 8, 86, 61,115,213,
+ 92,131, 85, 81, 81,129,235,215,175, 99,194,132, 9, 80,169, 84, 32,132,160,176,176, 16,254,254,254,144, 72, 36,200,205,205,197,
+254,253,251, 17, 20, 20, 4,133, 66,209,172,139,162, 94,227,246,118, 26,141,102, 23,165,180,221,169, 83,167,236, 99, 99, 99,209,
+172, 8, 22,145,195,136, 0, 8,240,133, 72,127, 55, 82,150,122,102,138, 82,214, 6,139,113,255,112,229,230,175,244,255,158, 94,
+ 0, 0,112,119,119,175, 51, 82, 33, 33, 33,183, 69,174,152,185, 98, 48,154,166, 85,171, 86, 29,124,124,124, 48,117,234, 84, 84,
+175, 93, 11, 61,128, 4, 0,137,102, 51, 0, 64, 13,188,201,114,233,111, 52, 88,126,126,126,147,162,163,163,159, 89,246,253,106,
+187,185, 51, 94,215,149,167,158,231,140,213, 38,187,106,139,197,116, 77, 91,250, 85, 99, 17,167, 97,195,134, 65, 34,145, 64,237,
+236, 12, 91, 71, 71,200,107, 35, 87, 42, 21,228,106, 53,136,201, 4,106, 50, 65,110,101,104,191,190,166,141,141, 13, 20, 10,197,
+ 93,141, 85,115, 13,214,205,155, 55,241,211, 79, 63,161,115,231,206, 80,169, 84,144, 72, 36,104,223,190, 61, 82, 83, 83, 17, 28,
+ 28, 12, 0, 72, 76, 76,196,195, 15, 63,140,244,244,116,180,105,211,198,174,185, 6, 75, 16, 4,236,217,179,199,158, 82,218,147,
+ 82,138,162,162,162, 22,157, 68, 65, 16, 80, 90, 90,138, 45, 91,182,160,160,160, 0,238,238,238,168,208, 57,162,182, 87,186, 40,
+254,222, 11,146,193,184, 95, 16, 69, 17,182,182,182, 72, 73, 73,193,163,143, 62, 10, 0,176, 88, 44,112,115,115, 67,112,112, 48,
+ 6, 13, 26,132,129, 3, 7,178,140, 98, 48, 26,123, 97,185,114, 37, 57, 43, 43, 43,124,198,140, 25,248,206,199, 7,246,246,246,
+120,101,230,204,227, 60,207,247, 99,185,115, 15, 12, 86,115, 66,115,126,126,126,195,188,188,188,102,175, 94,189,218, 86,171,213,
+194,167, 85,148,253,182, 13,235,141, 30,106,185, 33,183,236,230,132,179, 57,186,196,166, 52, 56,142, 67,235,105,211, 16,100, 54,
+163,228,232, 81, 40,212,106,168, 59,117, 2, 49,153,160,200,204,132, 92,173,134,196,214,182, 89, 7,194,113, 92, 77,149, 96,173,
+153,170, 87, 53, 88,107,182,238,214,224,245,110,152,205,102,199,248,248,120, 60,240,192, 3, 24, 57,114,100, 93, 85, 96,135, 14,
+ 29,176,110,221, 58,140, 24, 49, 2,103,206,156,129, 70,163, 65,235,214,173,209,186,117,107, 36, 37, 37, 53, 43,189,181,195, 50,
+ 12, 24, 48, 64, 71, 8, 57, 71, 41,109,119,242,228, 73,251,150,156, 68, 81, 20,177,101,203, 22, 60,246,216, 99,104,213,170, 21,
+142, 29, 59,134,233, 51, 62,132,163, 71, 0,120,206, 29, 0,101, 85,132,140,251, 14, 65, 16, 26,108,200, 94, 91, 38, 48, 24,140,
+ 38,239,163, 25,195,135, 15,143,253,240,195, 15, 91,191,242,202, 43, 0, 0,141, 70,211, 69,163,209,164,252, 93,227, 96,221,143,
+213,131,117, 6,203,154, 3,236,211,167,207,151,130, 32, 12, 85,169, 84, 78,207, 61,247,156,185,184,184, 24,155, 55,111,198,183,
+223,126, 91, 85,105,225, 78,151,151, 10,207,101,228,234,114,173, 53, 67, 54, 60, 15,152,205,144,223,106,115, 5,163, 17,212,108,
+134, 76,173,134, 84,165,106,246,129,112, 28,119,215,136,149, 82,161,128,236,214,120, 88,214,162, 80, 40,202, 15, 31, 62,236,158,
+147,147,115, 91,131,246,160,160, 32, 0,192,137, 19, 39,112,236,216, 49, 60,246,216, 99,144, 74,165,144,203,229, 56,123,246,172,
+190,185,166, 72, 16,132,186, 94,132, 26,141, 38,190,115,231,206,119,237, 61,104,141, 86, 78, 78, 14, 90,181,106, 5,163,209, 8,
+123,123,123, 20,231, 93,199,213, 43,233,168, 48,164,194,223, 93,133,194,194, 66, 40,149, 74, 86,154, 48,238, 43, 36, 18, 9,122,
+247,238,141,226,226, 98,184,185,185, 65,169, 84,162,188,188,252, 54,227,181, 98,197, 10,150, 81, 12,198, 93,240, 31,177,108,145,
+239,208, 47,199, 3,192,171,159,237,195,219,179, 23, 98,204,200,129,120,230,153,103,254,246,113,176,238,251, 54, 88, 13, 29, 88,
+ 92, 92,220, 24, 23, 23,151,209,207, 62,251,172,237,137, 19, 39,240,193, 7, 31, 72,247,236,217, 99, 62,121,242, 36, 47,138,226,
+155, 57, 57, 90,171, 75, 48, 66, 8, 56,142,131,126,251,118,232,188,188,224,208,177, 35,136,217, 92, 19,185,178,183, 71,165,143,
+ 15, 96, 52,194,177,188, 28,205,213,172, 29,146,161,254,176, 12,178, 91,195, 53,180,164,224,190,219,184, 87,147, 38, 77,194,178,
+101,203,208,173, 91, 55,132,133,133, 65, 42,149,130,227,184, 22,245, 34,172, 95,101,215,236,222,131,119,188,201,251,249,249, 33,
+ 37, 37, 5, 78, 78, 78,248,246,219,111,225,225,238,142, 73,195,195, 97, 50,153, 96,177, 88, 80, 89, 89, 9, 65, 16,112,159,206,
+ 28,196,248, 31, 68, 20,197,219,218, 92, 21, 23, 23,195,215,215,183,209,168, 22,131,193,168,247, 28,170, 63, 14, 86,199,238, 56,
+178,105, 30,214, 93,246, 71,238,236,217,255,200, 56, 88,247, 91, 4,171,201, 82,168, 71,143, 30,234,178,178,178, 79,159,122,234,
+ 41,219,202,202, 74, 20, 23, 23,163,184,184, 24,199,143, 31,223,111, 50,153, 58,229,228,228,172,104,196,248, 68, 53,100, 94, 92,
+ 60, 60,160,176,183, 7,169,215,123, 80,166, 82,213, 68,178, 76, 38,160, 1, 35,208,152,102,125,115, 85, 91, 69,104,149,185,178,
+179,187, 77,147,227,184,186, 97, 26,238,236, 49,232,231,231,135, 57,115,230, 96,248,240,225,183, 13,211, 96,109, 58, 53, 26, 77,
+ 60,165,180, 93,237, 3,226, 86, 35,247,120, 43,141,100, 84, 67, 6,107,240,224,193,216,182,109, 27, 94,123,237, 53,100,102,102,
+ 98,196,136, 17, 32,132,192,209,209, 17, 94, 94, 94,112,118,118,134,141,141,205, 31,210,218,144,230,159,129,105, 50,205,191, 75,
+179,126,131,118,181, 90,141,170,170,170, 38,205, 21, 33,100, 36,203, 79,166,201, 52,235,198,193,194,153,228,163, 56,248,253, 43,
+120, 49, 33, 8, 35, 2,211, 49, 99, 70,211,227, 96,253, 21,233,188,223,104,210,125, 84, 84, 84,188,219,186,117,107,249,197,139,
+ 23,145,145,145,129,203,151, 47, 67, 16,132,171, 57, 57, 57, 45, 46,164, 56,142,131,163,163, 35, 20, 10, 5,164,185,185, 53,109,
+164,212,106, 0,168,137, 92, 81, 10,210,204,234, 44,142,227, 32,149, 74,127, 31,243,234, 86,161,219, 82, 4, 65,168, 27,161,189,
+118,156,171,218,133,227,184,186,165, 5, 67, 52,188,122,252,248,113,251,172,172, 44, 80, 74,177,121,243,102,251,135, 31,126,248,
+213,150, 70,175, 10, 11, 11, 97, 54,155, 33,147,201, 48,120,240, 96,116,239,222, 29,122,189,190, 46, 90, 69, 8,129, 84, 42,101,
+189, 8, 25,247, 29,181,109,176,234,143,218,206, 34, 87, 12,134,245,100,111, 30, 63, 21,192, 84, 66,200,232,153, 51,103,126,247,
+194, 11, 47, 64, 20, 69, 36, 37, 37, 97,201, 27,111,224, 61, 65,120,124, 49, 33, 85,147, 41,157,202,114,235, 30, 26,172,174, 93,
+187, 6,232,116,186,101, 60,207,183, 23, 4, 65,113,240,224, 65, 84, 87, 87, 35, 53, 53,213, 32,138,226,230, 22,239, 80, 42,205,
+159, 60,121,178,175, 53,219,202,229,242,155,104, 98, 30,194,250,154,212, 10,179, 35,151,203,111, 26,189,189, 27,213, 20, 69, 49,
+183,254,220,130,181, 38,234, 46,209,159,250,133,125,174,149, 89, 48,191,107,215,174,127,248,174, 37,121,169, 80, 40,114, 18, 18,
+ 18,188,154,243, 27,185, 92,158,207, 46,123,198,127, 29,185, 92,110, 24, 59,118,172, 85, 61,119, 37, 18,137,105,195,134, 13,172,
+110,156,193,104, 0, 27,185,252,241, 23, 95,124, 17, 63,252,240, 3, 54, 47, 90,132,129, 57, 57, 88, 39,151,195, 86, 46,199, 87,
+102,243,120, 0,204, 96,221, 75,131, 85, 94, 94,254, 94,105,105,105,231,138,138, 10,254,234,213,171, 6, 66,136,192,113,156, 65,
+ 20,197,143, 4, 65, 88,222,210, 29,110,220,184, 49,252, 94, 31, 68,173, 38,177,162,202,211, 26, 82, 83, 83,123,254, 85, 25,254,
+103,218, 90,221,201,111, 71,143, 70,176, 75,152,241,191, 70,152, 99, 47,172, 95,223,107, 45,203, 9, 6,227,222,112,250,220,185,
+120, 0, 24, 60,120, 48, 12,175,190, 10, 0, 88,121,107, 28, 44,123, 96,217,191, 36,153,157, 0,184,223,250,191, 24,192, 37, 0,
+177, 0,108, 1, 24, 1,232, 1,184,213,219,190,228,214,186,218,245,191, 2,176,252,157, 9,110,208,144, 92,186,116,233,233,162,
+162, 34,123,147,201,228, 44, 8,130, 27,207,243,158,102,179, 57,136,231,249,101,148,181,148,254,199,161,128,248,103, 22,150,131,
+ 12, 6,131,193, 0,128,240,240,112,149,155,155,155, 42, 60, 60, 92,245, 14,165,183, 45,255,162,234, 65,119, 66,200, 54, 66,200,
+182, 55,223,124,179, 47,128,238,111,190,249,102,231, 91,159, 59, 2,112,171, 93, 79, 8,217, 6,192,245,142,245,209,127,119,130,
+239,183, 6, 11,180, 69,139,217, 92,251, 63,131,193, 96, 48, 24,140,127,235, 67,158,210,132,185,115,231,206, 1, 32,153, 59,119,
+238,156,122,159, 65, 41, 77,168,255,247,142,245,238,127,119, 90, 9,128,168, 6, 14,194,234,153,178, 91,210,155,160, 41,125,166,
+201, 52,153, 38,211,188,131,176, 59, 52, 55, 54,161,217, 88, 71,156,116,150,159, 76,147,105,254, 51,154, 77,105, 55,240,251, 7,
+ 9, 33,219, 40,165, 9,245,255,214, 55, 94,183, 52,183,213,255,255,142,245,219,255,110, 55,248,151, 45, 0,162,152, 38,211,100,
+154, 76,243, 95,166, 57,146,229, 39,211,100,154,255, 62,205, 38,150, 7,107, 44, 75,195,127, 27,250,191,222,119,127,103,122, 27,
+ 25,166, 97,195, 6,201,141,112, 91,123,165,157, 32, 7, 0, 99,165,196,236,119,217,160,195,168, 81,108,190, 21, 6,131,193, 96,
+ 48, 24,127, 59,132,144,109,111,188,241,198, 91,255,133,180, 74, 27, 50, 87, 69,177, 10, 87, 27,203,205, 48,158, 71,107, 0,176,
+ 81,224, 82, 81,172,125,186,251,134, 13, 37,247,218,100, 13, 27, 54, 76,173, 80, 40,100,235,215,175, 47,251, 55,102, 82,187, 80,
+226, 35, 88, 48, 20, 18, 12, 2, 0, 8,216, 41,145, 97,235,185, 12,154,219,204, 11,195,227, 86,212,176,240, 94,108,119,175,127,
+203,184, 63,208,104, 52,182, 0, 18,164, 82,233, 24,103,103,231,142, 37, 37, 37, 31,230,228,228,124,222,194,194, 76, 10, 96,178,
+147,147,211,104, 39, 39,167,192,210,210,210,235, 21, 21, 21, 27, 1, 44,166,148, 54,171, 71, 78,239, 14,100,186, 66, 46,123,182,
+218,108,249,248,240,105,250,109, 92, 44,113,229, 69,204,181,145, 75,123, 25, 77,252, 39,135,206,208,229,205,216, 83,195, 58, 0,
+ 0, 32, 0, 73, 68, 65, 84, 76, 27, 23, 21, 21,101, 35, 8, 2, 81, 42,149,162, 92, 46,167, 10,133,226,206,182,148,252,129, 3,
+ 7,238, 28,150, 37,253,159, 56, 47,241,241,241,107, 40,165,195,121,158,135, 68, 34, 57,184,127,255,254, 33,127, 86, 51, 46, 46,
+ 78, 9, 0, 7, 14, 28, 48,254,199, 30,146, 92, 80, 80,144,250,250,245,235,122, 90, 59, 43, 61,163, 73,186,117,235,150,105, 54,
+155, 27,109, 75, 36,151,203,139,126,251,237,183,192,251,240,240,139,107,171,254, 0, 20, 2,144,220,250,108,186,245,183,160,222,
+119, 5, 13,172,255,231, 13,214,141,112, 91,123, 27,203,205,176,194,252,212, 81,133,218,211, 35, 1,192, 67,211, 97,163,135, 87,
+228,134, 27,225, 78,230,174,145,163,213, 18, 91,178, 72,202,201,218, 87, 27,141,174, 50,153,172,196,196,243,103,165, 22, 50, 85,
+155,186,254, 70,115, 19, 65, 41,253,137, 16,226, 61,116,232,208, 93,162, 40,174,220,190,125,251,165, 22,221,180,113,113, 82,207,
+ 50,215,199, 57,153,116, 8, 64,163, 40, 5, 40,145,158,135,217,188,179,192,165,120, 53,253, 99, 65,219, 32,177,177,196,182,186,
+ 2,241, 16, 49,180, 85,144,103,151,169, 19, 71,186,118,238, 62,208,182,178,202,130, 95,247,111,235,180,124,205,214, 23,219, 6,
+147, 19, 2,193, 86, 91, 71,236, 73, 73,161,134, 38, 10,148,247, 9,193,180, 91,255, 47,164,148,190,251,103,182,179,226,183, 95,
+ 80, 74,223,188,199,133, 98, 91,103,103,231, 47,148, 74,165,157, 68, 34, 73,207,201,201,249,148, 82,122,170,185, 58,126,126,126,
+145, 60,207, 15,151,201,100,177, 22,139, 37, 69, 42,149,110,185,113,227, 70,234,159, 72,151,164, 77,155,208, 39, 37,132,244, 0,
+224, 4,224,166, 64,233,145,139, 23, 51,126,160,148,182,232,101, 32, 46, 46, 78,106,168,172,124, 92, 42,145, 12,166,148, 70,129,
+ 82, 2, 66,206,243, 60,191, 83,101,111,191,250,128,149,215, 82,247,238,221, 47, 91, 44,150,102,141, 85, 38,149, 74,139,124,124,
+124,194,215,175, 95,223,236,180,251,250,250, 62,236,227,227,243, 85,215,174, 93, 85, 29, 58,116,128, 92, 46,199, 39,159,124, 50,
+ 25,192,231,214, 24, 41, 59, 59,187, 81, 42,149, 42, 72,175,215, 95, 51, 24, 12,137, 10,133,162,223,226,197,139,125,186,117,235,
+102, 95, 84, 84, 68, 56,142,243,216,186,117,235, 19,159,127,254,121, 60, 33,228, 65, 74,169,117,249,208,129,116,109, 29,228,253,
+238, 75, 79,244,197,107,115,127,124,169,103, 59, 82,108,107, 39,255,106,100,207, 80,167,200, 16, 39,188,191,244,183,201, 0,172,
+ 54, 88,145,145,145,242,132,132,132, 85,132,144, 7, 9, 33, 13, 62,160, 57,142,211,199,197,197,249, 55,118,190,130,186, 58, 31,
+150, 74,164, 62, 13,173,231, 5, 62,247,250,177,178, 63, 61,116,139, 32, 8,131,150, 47, 95, 14,169, 84,138, 49, 99,198,244,137,
+141,141,181, 77, 73, 73, 49, 88, 87, 30,197,186, 2,120, 5, 0,167, 80, 40, 22, 28, 61,122,180, 40, 54, 54,118,187, 92, 46,143,
+187,181,254, 64, 74, 74,202,131,119,156, 83,242,103,122,124,199,197,197,189, 35,138,226, 68,133, 66,113,163,172,172,108, 92, 74,
+ 74,202,229, 63,155, 7,177,177,177,178,130,130,130,201,237,219,183,127,190, 83,167, 78, 94,169,169,169, 5, 62, 62, 62, 75, 60,
+ 61, 61, 23,167,164,164, 52,105,216, 59,116,232,224,205,113,220,147, 0, 30,191,245, 0,221, 64, 8, 89,157,146,146,114,237,127,
+193, 96,153,205,102,247,148, 25, 51, 0,137, 4,134,190,125, 65, 41,133,106,214, 44,160,184, 24,101,243,231,131,231,121, 12, 30,
+ 60,216,253, 62, 61,252, 19,255,181, 4,223,213, 96, 41,237, 4, 57,207,163,117,161,246,244,200, 46,131, 22, 59, 0,192,241,157,
+147, 71,186,120, 71,166, 42,237,132,116,133, 90,190,246,225,161,241,237, 71, 37,244, 33,190,222, 30,200,201, 43,244, 88,177,110,
+ 87,255,109, 59,147,214, 2,232, 97,101,212,234, 9,139,197, 18,192,113,220, 58,142,227,188, 23, 45, 90, 20,146,145,145, 49,110,
+221,186,117,195,134, 14, 29,122, 68, 20,197,239,182,111,223,254,155,181, 7,226,213, 97,120,132, 23,188,214, 12, 31, 49,196,255,
+193,254,238,138, 0, 47,119,136,162, 18,151,174, 89,252,246, 28, 58,213,127,199, 47,187,167,122, 70, 13,127,178,224,252,150, 11,
+ 77,105, 69,132,144, 71, 85, 74,249, 43,111,188,240,160,215,224, 65, 9,246, 46,190, 49, 82,144,154,201,162, 21, 14,192,136, 39,
+ 95,181, 27,254,196, 20,187,107, 23, 14,251,108,223,177,181,255,234,196, 3,121, 17, 33,100, 65,218, 85,250, 99, 67, 81, 37, 66,
+ 48, 77, 20, 41, 87, 83,232,147, 87,251,247,239, 63,192,198,198,230,182, 2,165,186,186, 90, 70, 8, 34, 69,145,222,122, 56,144,
+105,132,144, 47,173,137, 70,213,238,195,100, 50,114, 50,153, 2, 18, 9, 55, 57, 58, 58,186, 67, 81, 81,209, 1, 0,203,181, 90,
+109,201,159,185, 80, 84, 42,213,179,195,135, 15,159,179,114,229, 74,181,173,173, 45,180, 90,109,248,163,143, 62,218,158, 16,242,
+ 16,165,180,201,130, 87,163,209, 68, 3,120,200,205,205,237,225,113,227,198, 5, 60,240,192, 3, 8, 12, 12,132, 86,171,141, 79,
+ 74, 74,122, 51, 38, 38, 38,187,160,160, 96, 35,128, 68,173, 86,123,166, 57,230, 42, 42,178,213,252, 9, 19, 39, 69,140, 24, 49,
+194, 91,105, 99, 43,205,201,201, 44,250,230,235, 37,142, 18,194,181, 39,132,188,218, 92,147,213,165, 75,151, 8, 34,138,107,159,
+127,246,217,192,142,221,187, 75, 61,189,189, 81, 93, 94,142,140, 75,151,252, 78,158, 56, 17,191,101,239,222,105,177,177,177, 99,
+ 82, 82, 82,154,188,150, 76, 38,147,239,161, 15, 63,132,196,205, 13,212, 98, 1,223,166, 13, 68, 81,172,153, 71,239,240, 97,192,
+ 98, 1,181, 88, 96,233,223,191,110,126,202, 97,195,134,121, 20, 23, 23,203, 0, 52, 43,221,126,126,126,222, 97, 97, 97,203,223,
+124,243, 77,185,209,104,196,233,211,167,113,244,232, 81,177,168,168,104,126, 83,230,138, 16,178,117,230,204,153,154,158, 61,123,
+218,151,148,148,128,231,121,215,196,196,196, 9,177,177,177,246, 62, 62, 62,138, 85,171, 86,213,206, 16,224, 28, 18, 18,226,252,
+248,227,143,155, 86,173, 90, 53, 25,192, 2,171, 10, 26,130,217,143, 14,235, 15,131,133,131,197,194,187,123,187,219,255, 48,121,
+108, 31, 25,168, 9, 43,127, 62, 5, 11, 47,126,219, 28,115, 21, 28, 28,188, 50, 56, 56,184,239,220,185,115, 73, 70, 70,134,164,
+205,173,124,229,121, 30,130, 32, 64, 16,106,178,110,204,152, 49,234, 91,229, 92,131, 6, 75, 42,145,250, 28,222,116,193, 93,165,
+ 82,213,253,182,118, 50,246,202,202, 74, 12,122,170,107, 75,162, 85,126,148, 82,255, 59, 12, 22, 87,219, 54,195,100, 50,193,198,
+198,166,215, 3, 15, 60, 80,117,203, 84,151,237,218,181,235, 98, 35,146,207, 63,247,220,115, 83,212,106, 53, 22, 45, 90,212, 47,
+ 50, 50, 50, 78,169, 84,198,237,219,183, 15, 0,208,171, 87,175,184,206,157, 59,187,240, 60, 63,148, 16, 50,194,193,193,161,103,
+ 76, 76,204,225,232,232,232, 39,207,156, 57, 83,222,220,244,119,236,216,241,225,168,168,168,151,231,205,155,103,119,225,194, 5,
+231,247,223,127,127, 45,128, 14,127,166, 12,137,140,140,148, 87, 86, 86,174,121,239,189,247, 6,215, 78, 53, 38,138,162,231,175,
+191,254,250,254,107,175,189,214, 53, 54, 54,246,177,134, 76, 86,167, 78,157,218, 83, 74,103,132,132,132,196, 63,245,212, 83,146,
+ 30, 61,122, 64,175,215, 99,247,238,221,255,183,105,211,166,255,139,137,137, 57, 70, 41,125,255,244,233,211,135,238,213,195, 49,
+ 54, 54,246, 18, 0,191,218,184, 67, 74, 74, 74,235,127,197, 83,219,222, 30,232,219, 23, 21,121,121, 53,101,243,188,121, 53,101,
+205,156, 57, 44,196,247, 95, 48, 88, 77, 81, 85, 85, 21,253,230,228,177,224,184,154,145,204,195,130,253,241,209, 91, 19,200,150,
+109,187,172, 30,103,162,180,180,116,198,227,143, 63,238,189,101,203,150,231, 56,142,179, 41, 44, 44, 36, 85, 85, 85,182,211,166,
+ 77,243,213,233,116, 35, 18, 19, 19,123, 15, 27, 54,236, 28,165,244,147,173, 91,183, 38, 55,166,229, 30, 61, 50,212,195,205, 99,
+247,167,179, 39, 56, 71, 5,135,192,100,177, 32,167, 48, 23, 20, 74,120,121,168, 49,230,161,104,121,143,142,178,208,249, 95,236,
+219,229,213,126,104,255,252,179, 91, 27, 43,200, 32,161,120,253,248,137,212, 86, 28, 95, 66,136,204,161,129, 55, 99, 41, 66,219,
+197, 73,159, 15,142,114, 26, 50, 96,144,195,195, 79, 79,123, 29,192,143,141, 61,199,234, 61,208, 48,101,202,148,186,169,120,106,
+ 41, 40, 40,192,254,253,251,238,250, 27,107,253, 70,253, 15, 31,124,240,129, 99,105,105,233,131, 43, 86,172,136,247,246,246,158,
+149,151,151,215,236,194,135, 16, 98, 11, 96, 80,191,126,253,102,111,218,180, 73, 93, 59,122,189,167,167, 39, 22, 44, 88,224,247,
+232,163,143,126, 12, 96, 88, 19,230,234,187,177, 99,199,142,238,223,191, 63,194,195,195, 81, 82, 82,130, 99,199,142,153,150, 44,
+ 89,114,253,129, 7, 30, 8, 26, 61,122,180, 98,202,148, 41,254,153,153,153,175, 38, 38, 38,190,234,236,236,252,109, 89, 89,217,
+203,214,164,175, 77,155,208, 39,199,141, 31, 31, 49,233,249,151, 98,205,102, 99,213,217,148,131,251,165,114, 78,242,210,203,227,
+ 29, 75,203,138,220, 40, 21,159, 4,240,125, 51,204, 85,168,143,167,231,158,185, 31,127,236,228,226,238,142,252,252,124,220,200,
+201, 65,222,249,243, 32, 0,250,247,239,175,136,110,223, 62,100,225,210,165, 59, 59,117,234, 52,224,228,201,147, 23,155,210,148,
+184,185, 33, 55, 38, 6, 0, 80,158,146, 82, 27, 89,129,253,208,161,191,191,153,166,165,129,227, 56,120,120,120,180,100,250,165,
+218, 72,112,151,158, 61,123,202, 1,224,181,215, 94,211, 85, 86, 86,206, 35,132,252,148,155,155,171,109,226,167,147,223,121,231,
+ 29,239,144,144, 16,255, 53,107,214, 64,175,215, 3,128,123,112,112, 48,194,194,194,132,131, 7, 15, 34, 60, 60, 28,246,246,246,
+ 56,120,240, 32,142, 29, 59,134,152,152, 24,181, 92, 46, 31,105,141,193,234, 21, 77,134,116,236, 16,213, 53,192,207, 31, 7,142,
+158,128, 92, 33,115,122,225,169, 4,216,171,165,152,183, 98,187,152,157, 83,250,210,161, 51,116,165,149,215, 35,247,224,131, 15,
+ 46, 15, 12, 12,140,155, 59,119,174, 74, 46,151,227,220,185,115,200,207,207,135,187,187, 59,108,108,108, 32,147,201, 32,149, 74,
+155, 53, 85,150, 74,165,130, 86,171,133,249,214,224,138,130, 32, 64,167,211,193,203,171, 38,248, 56,107, 22,225,102,206,180,174,
+ 42,107,192,128, 1,175,123,120,120,204,240,240,240,144,212,255,222,104, 52,226,141, 55,222,128, 94,175,135,143,143, 15,124,124,
+124, 54,213,206,123, 90, 82, 82,130,254,253,251,207,221,179,103,207,236, 6,100, 29,189,189,189, 49,116,232, 80,152, 76,166,136,
+175,190,250,234,123, 74, 41,170,170,170,234, 54,240,240,240,200,236,213,171,151,164,103,207,158, 8, 9, 9,193,210,165, 75,251,
+110,216,176,161, 55,128,159,155,123, 45, 57, 58, 58, 62, 50,106,212, 40, 59,181, 90,141, 46, 93,186,192,100, 50,105,226,226,226,
+148, 45,169,138, 36,132, 72, 53, 26,141,167, 84, 42,253,108,242,228,201, 3,251,244,233,131,180,180, 52,236,220,185, 19,195,134,
+ 13, 67, 92, 92, 28,222,126,251,237, 65,239,190,251,238,100, 52, 48,171,133, 40,138,171, 55,110,220, 24,232,235,235, 11,137,164,
+ 38, 91, 29, 28, 28, 48,110,220, 56,140, 29, 59, 22, 59,118,236,232, 58,103,206,156,181,113,113,113, 1, 7,154, 81, 83,209,212,
+ 59, 75,202,173,251, 53, 54, 54,214,239,223,242,208, 54,117,235,134,178,188, 60,120,122,123, 3, 0,242,180, 90, 80, 74,235, 62,
+227, 86, 89,195,248,151, 26, 44, 99,165,196,108,163,192, 37, 15, 77,135,141,199,119, 78,174,171, 34,148, 82, 92,170,174,148,152,
+ 1, 64,160, 20, 21,122, 30,182, 74, 14,153,121, 58,156,191, 90,116,183, 2,255,182,174,150,253,251,247,223,170,211,233,194, 93,
+ 92, 92, 22,240, 60, 47,233,219,183,175,164,107,215,174,238, 89, 89, 89, 56,112,224, 0,100, 50, 25, 76, 38, 19,113,118,118, 86,
+142, 27, 55, 78, 99, 48, 24, 92,223,122,235, 45, 55, 0,125, 26,210, 36,163, 71, 75,188,101,146, 13,243,102, 63,238, 76, 36,151,
+113, 57,251, 38, 66,125,187,192,213,209, 15,185, 69,122,164,164,238,192,229,140,237, 8,245,245,199,132, 49, 97,142, 11,191, 46,
+222, 72, 98, 39, 70,209,148,165,150,134, 52, 1, 72, 36,170, 80, 98, 74,122, 88,148,184,245, 33, 18,239, 4, 66,108, 52,183,109,
+ 80, 89,146,137, 75,191,173,164,153,231,126,166,254,209, 79, 18, 0,146,134,142,157, 82, 90, 40,145, 72,150,115, 28, 25, 79, 8,
+ 65,135, 14, 49,133,243,231,207,191,219,155,154,165, 67,135,152, 66,137,132,243,168,153, 71,144, 91, 38,138, 66, 97, 35,233,172,
+191,191, 66, 66,200, 66,133, 66, 57, 13, 0,188,189, 53,133,219,183,111,183,140, 26, 53, 10,159,126,250,169, 98,250,244,233, 51,
+125,124,124,158,202,205,205,205,109,236, 28,213, 43, 20,163, 28, 28, 28, 38,182,106,213,106,216,236,217,179, 21,131, 6, 13,178,
+165,148, 66,167,211, 65,167,211,161,170,170, 10,118,118,118,144, 74,165, 94, 77,157,247,192,192,192,135,199,141, 27, 7,119,119,
+119, 28, 63,126, 28,211,167, 79,207, 42, 42, 42,250, 32, 47, 47, 47,101,237,218,181,173, 67, 66, 66,222, 94,186,116,105, 68,207,
+158, 61,185,161, 67,135, 98,235,214,173, 61,154,210,172, 59, 81,132,244,120,232,161, 17,238, 38,147,161,210,104, 52,148, 95,207,
+ 74,206,203,201,185,112, 51, 60,172,147,199,128,129,221, 92, 46, 93,186,218,163, 33,131,117,167,230,232,209,163, 37,156, 32,252,
+248,241,188,121, 78,156, 84, 10,139,197,130,128,128, 0,156, 59,119, 14, 21,101,101, 48,232,245,184,150,154, 10, 77, 80, 16, 38,
+143, 25,227,244,193,146, 37,107, 98, 99, 99, 59,214,127,235,190, 91, 58,169,197,114,103,181,213, 31,230,204,187,219,119,214,156,
+247, 59, 30, 66,153, 90,173, 22, 42,149, 10, 17, 17, 17,118,201,201,201, 71,115,114,114,180, 77,105,218,216,216,140,236,209,163,
+135,253,218,181,107, 17, 27, 27, 11, 39, 39, 39,236,223,191, 31,231,206,157,131,217,108,230,116, 58, 29,212,106, 53,230,206,157,
+ 11,127,127,127, 84, 84, 84, 32, 51, 51,211, 85, 38,147,185, 89,149, 78,130,103, 70,143,120, 8, 18,185, 29, 46,101,228,160, 79,
+215, 24,120,120,120,224,236,197, 12,100,231,150, 22, 16,130,167, 7,245, 80,206, 53, 24, 76,239,252,122,154,174,104, 72,147,212,
+ 56, 79, 78, 42,149, 62, 52,103,206, 28, 78, 46,151,215,229, 93,237,156,132,181,198,170,118,146,246,187,153,213,187,165,147,231,
+121,152,205,102,152,205,102,136,162,136,162,162, 34, 84, 84, 84,192,217,217,185,102,131,153, 0, 1, 33,180,129, 89,232,239,184,
+223,199,126,242,201, 39, 18,239,218, 7, 94, 61,114,114,114, 80, 94, 94, 14,123,123,123, 56, 57, 57,213, 69,220,138,139,139, 49,
+117,234,212,177, 0,102,223, 77, 83, 42,149,126,242,233,167,159, 14,107,221,186,181,215,179,207, 62, 11,169, 84, 58,168,164,164,
+ 4, 43, 87,174,132, 74,165,194,138, 21, 43, 16, 24, 24, 40, 17, 4, 1, 6,131,161,214, 8, 87, 42, 20,138,204,150, 92, 75,101,
+101,101, 63,108,219,182,173,123,183,110,221, 28, 1, 96,248,240,225,220,150, 45, 91,178,251,246,237,123, 67,167,211, 61, 89,191,
+186,176, 33,205,216,216, 88, 89,126,126,254, 43, 99,198,140,153, 18, 31, 31,239, 80, 82, 82, 2,165, 82,137,159,126,250, 9,203,
+151, 47,223,109,177, 88,102,109,220,184,241,189,111,190,249,166,255,240,225,195,241,205, 55,223,188,112,171, 89,132,120, 23, 77,
+111, 63, 63, 63,156, 61,123, 22,206,206,206,112,115,115, 67,121,121, 57,142, 29, 59,134, 19, 39, 78, 32, 34, 34, 2,132, 16,167,
+198,162,149,141,164,179,197,145,170,230, 12,103,116,175, 52, 75, 75, 75, 81, 94, 94, 14, 57,106, 6,111,188,121,243, 38, 0,212,
+125,110,105, 58, 9, 33, 82, 31, 31,159, 4, 71, 71,199,137, 0, 36,101,101,101, 43,108,109,109, 19, 51, 50, 50, 76,127,215,177,
+223,151, 6,139, 16, 82,123, 94,226, 40,165, 7,253, 46, 27,116, 69,177,246,233, 30, 94,145, 27, 92,188, 35, 83, 1, 64, 74,113,
+137,202,236,211,253,206, 25,116, 0, 96, 54, 83, 28,189, 84,134, 51, 87, 10,112,238, 74, 62,212, 54, 77,191,117, 27,141,198,126,
+ 59,119,238,196,134, 13, 27,230,127,254,249,231, 52, 59, 59, 27, 89, 89, 89,112,118,118, 70,159, 62,125, 80, 84, 84,132,147, 39,
+ 79, 34, 52, 52, 20,148, 82,248,249,249, 41, 0, 56, 54,166,233,121, 69, 28,243,212,132, 14, 65,110,142, 4, 91,143,238, 66,215,
+136, 17, 80, 41,165, 40, 42,171, 2, 71, 8, 50,174,239,133, 32,216,225, 76, 90, 54,186, 71,217,161,103, 23, 7,159,202,125,101,
+207, 2, 88,218,244, 19,203, 2,161,112, 47, 21, 10,247, 81,206,185, 35,145,120, 15, 39,101,229,213, 72,251,237, 91,154,119, 41,
+169,174,172, 53,155,116, 77, 74, 9,130, 48,213,211,211,211,240,198, 27,111,244, 11, 11, 11,179,188,248,226,139,167, 50, 51, 51,
+167,220, 97, 68, 62,251,242,203, 47,145,158,158, 94, 60,119,238,220,253, 5, 5, 5,111, 53,243,198,156, 65, 8,249, 2, 0,180,
+ 90,109,201,182,109,219, 58, 30, 60,120,240,213,133, 11, 23,122,189,244,210, 75,138,151, 95,126,121,124,205,163,162,201, 27, 45,
+ 58, 46, 46,110,231, 15, 63,252, 96,231,229,229, 69, 8, 33, 48,155,205, 40, 42, 42, 66, 81, 81, 17,202,203,203, 81, 89, 89, 9,
+189, 94, 15,142,227,154,108, 47,167, 82,169, 36, 21, 21, 21,184,121,243, 38, 58,119,238,140, 19, 39, 78, 4, 28, 57,114,100,249,
+215, 95,127, 45,142, 29, 59,150,196,197,197,145,226,226, 98,108,218,180, 73,204,207,207,231,108,108,108,244, 86,191, 29,115,112,
+ 82,169,108,229,191, 29, 73,220,169,205, 73, 45,206, 43, 56, 95,206,129,114, 90,109,114,121,112, 88, 95, 87,212,180,201,178,138,
+107,215,174, 61, 54,109,210,164, 96, 71,103,103,240, 60, 15, 55, 55, 55,228,228,228,160,170,170, 10, 85, 21, 21, 48,232,245,168,
+174,168, 64,218,190,125,232, 54,100, 8, 6,116,232,224,183,253,212,169,103, 0,124,211,152, 46,223,166, 77, 93,228,202, 49, 54,
+246,247,251, 33, 53,181,206, 88,201,122,244, 0, 81,169, 64,222,106,121,231, 24,173, 86,123, 38, 32, 32, 96,215,160, 65,131, 6,
+ 78,152, 48,129,203,207,207,223,226,229,229,213, 47, 63, 63, 63,173,177,223,169,213,234,224,226,226, 98,232,116, 58, 56, 57, 57,
+ 97,225,194,133,240,240,240,128,193, 96,192,201,147, 39,169,175,175, 47, 73, 74, 74,130,143,143, 15, 74, 75, 75, 97, 50,153, 80,
+ 85, 85, 85, 96, 50,153, 12,214, 93,152,240,241,244,242, 5, 71, 45,208, 22, 20, 99,248,144, 1,144,202,213,200,204, 41, 70,116,
+100,136,247, 19, 67,123,120, 75, 8,143,255,251,120,237, 11, 0, 86, 88, 97, 36,105,122,122, 58, 82,111,229,159,131,131, 3,236,
+236,236,106, 38,121,151,203,235,204,149, 84,106,125,128,190,118,114,244, 90,115, 85, 84, 84,132,140,172,203,216,148,180, 10,102,
+193,226,250, 93, 23,135,235, 33, 50,217,121,119, 61,153, 89,116,150,158,105,226,254, 89, 53,125,250,244,247,220,221,111,111, 10,
+227,231,231,135,137, 19, 39, 98,219,182,109, 72, 79, 79,191,173, 59,119,105,105,169, 8, 96, 85, 67,154,199,143, 31, 47,236,210,
+165,203, 35,175,188,242,202,222, 85,171, 86, 41,198,140, 25, 83, 87,157, 41, 8, 2,244,122, 61,246,237,219,135, 67,135, 14, 33,
+ 57, 57,185,204,108, 54,255, 44,145, 72,150, 28, 63,126, 60,173,185,215, 81,183,110,221,156,213,106,245,135, 47,188,240,130, 61,
+ 0, 84, 87, 87, 99,204,152, 49,182,143, 60,242, 8, 82, 82, 82, 34, 62,255,252,243,149, 0, 58, 55, 85, 29,200,113,220,250,164,
+164,164,248, 86,173, 90,213,188, 61, 90, 44, 56,114,228, 8, 38, 76,152, 80,170, 82,169,198,166,166,166, 86,250,248,248,188,183,
+109,219,182,254,209,209,209,104,215,174,157,103,113,113,177, 26, 64, 69, 3,231, 29,130, 32,212,157,159, 21, 43,126,191, 84,170,
+171,171,107,162, 59, 38, 19,233,220,185,115,224,137, 19, 39, 50,239, 65,164,234, 70,189,207, 55,254, 45, 15,237,170,213,171, 33,
+155, 62, 29,151,143, 28, 1,165, 20,110,145,145, 0,128,203,135, 14,213, 12,159,240,202, 43,205,210,243,241,241,113,161,148, 62,
+ 19, 31, 31,255,210,160, 65,131,220,188,189,189,225,234,234,138,115,231,206,117,219,181,107,215, 2, 31, 31,159,229,148,210,229,
+ 90,173,246, 47,203,131, 59, 61,200,125, 23,193,162,148,146, 91, 7, 73, 48,106,148,224,190, 97, 67,201,141,112, 39,179,210, 78,
+ 72, 7,128,234, 74,137,217,239,220,173, 97, 26,102,175, 5, 5,133, 32, 80, 80, 81,132, 72, 41, 4, 43,130,231,174, 14, 22,112,
+231,157,241,120,215,225, 24, 59, 54,153,236,219,183, 15, 7, 14, 28, 64,116,116, 52, 44, 22, 11, 28, 28, 28, 48,122,244,104, 36,
+ 38, 38, 66,165, 82,161,178,178,178, 73, 77,181, 11, 63,162, 75,187, 48,201,229,236,115,232,216,106, 36, 2,189,123, 34, 35,183,
+ 28,101, 58, 35, 74,202, 13, 8, 15,127, 29, 5,165, 6, 84, 84, 26,112,246,210, 26,248,122, 7,115,156,236,106,127,171, 12, 86,
+189, 39,132, 88,118,146,138,101, 39,233,190, 93,127,108,110,196, 27,173,107,226, 32,138,226,226,157, 59,119,118,235,217,179,167,
+ 52, 62, 62, 62, 38, 32, 32,160, 67, 86, 86,214,105, 0, 8, 8, 8,232,208,191,127,255, 24, 15, 15, 15,124,246,217,103,213,162,
+ 40, 46,110,225,219, 79,253,246, 90,199,253,252,252,102,109,222,188,249,235,137, 19, 39,194,219,219,187,189, 53, 26, 78, 78, 78,
+227, 87,174, 92,105,231,237,237, 77,120,158, 71,117,117, 53,242,243,243,113,243,230, 77,148,149,149, 33, 59, 59, 27,165,165,165,
+200,203,203,171,204,204,204,220,104,109,218,222,121,231, 29,240, 60,111,153, 48, 97,130,172,111,223,190, 88,181,106, 21,119,237,
+218, 53,124,243,205, 55,194,250,245,235,179, 56,142,147,142, 28, 57,210,191,121, 7, 76,138,115,114,174,185, 27,205,101,213,131,
+226,186, 79, 43,202, 44,134,123,224,112,236,253,117,227,103,217,153, 25,148,112,176,186,237,153, 82, 38, 27, 16,219,181,171, 44,
+ 63, 63, 31,161,161,161,200,205,205,197,149, 43, 87, 96, 50,153, 80, 89, 94, 14, 75, 69, 5,132,178, 50,208,138, 10,100,254,250,
+ 43,218,132,134, 42,118,158, 58,213,191, 41,131, 85, 91, 45,220, 80,212,138,227, 56, 16, 59, 59,192,206, 14,148,107,222,228, 10,
+ 26,141, 38,193,193,193,225,149,138,138,138, 93, 90,173,246, 99,179,217,252,202, 71, 31,125, 20,251,254,251,239,187, 78,159, 62,
+221,126,250,244,233,171, 3, 3, 3,187,101,102,102, 54, 88,181,163,215,235,175, 89, 44, 22, 23, 0, 30,123,247,238,133,187,187,
+ 59,116, 58, 29,204,102, 51, 12, 6,131,217,217,217, 89, 89, 82, 82, 2,163,209, 8,163,209, 8, 7, 7, 7,164,164,164,148,242,
+ 60,191,195,154, 52,218,218,216,184, 42,108, 28, 33,242,213,144,202,100,240,247, 11,132, 40, 24, 81, 86, 81,133,167, 31, 25,138,
+ 83,231, 82,177, 35,233, 56,111,177, 52,126,205,211,154, 66, 74, 36,132,208,240,240,112,220,188,121, 19, 18,137, 4,118,118,118,
+ 80,171,213,136,136,136,192,141, 27, 55, 90,108,176,234,155,171,125,191,109, 67,145, 62, 15,203,230,173,133,143,151, 31, 7,192,
+ 45, 55,255, 70,191,103, 95, 29,221, 41,168,167,203,188,235,135, 75, 27,108,215,182,123,247,238,121, 3, 6, 12,216,150,159,159,
+239, 86,239, 92,119,179, 88, 44,239,242, 60,143,204,204, 76, 92,188,120,241, 19, 74,105,210,239, 33,115, 73,238,158, 61,123, 26,
+ 53, 5,199,143, 31, 63, 21, 27, 27,251,236,232,209,163, 23, 4, 6, 6,122, 80, 74, 17, 29, 29,141,199, 31,127, 28,243,230,205,
+195,175,191,254,186, 65, 20,197,239, 28, 28, 28,142, 22, 21, 21, 73, 26,138, 60, 52, 70,231,206,157, 93,148, 74,229,193, 47,191,
+252, 50, 32, 36, 36,132,211,106,181,248,237,183,223,208,173, 91, 55, 16, 66, 16, 22, 22, 6,139,197,226,211,148,185,162,148,254,
+180,121,243,230,248,144,144, 16,164,165,165,225,208,161, 67,112,119,119,135,173,173, 45,134, 14, 29,234,242,211, 79, 63, 77,140,
+140,140,252, 92, 42,149,190, 59,100,200, 16, 8,130,128,228,228,228,252,235,215,175,235, 27, 59, 71,141,188,188,131, 82, 10,139,
+197,242, 9,199,113, 35, 59,117,234, 52,244,228,201,147,201,127,230,225,248,175,105,115, 5,192,223,223,191, 13,199,113, 47,186,
+184,184,160,172,164,228,182,200, 85,109,137, 81,251, 25, 0, 90,181,106,181,169,186,186,122,102, 99,157,135,124,125,125,163,108,
+109,109, 95, 74, 72, 72,120,244,193, 7, 31,148,152,205,102,108,219,182, 13, 95,124,241, 5, 6, 13, 26,132,176,176, 48,188,254,
+250,235, 14, 70,163,241,213, 93,187,118,189, 18, 25, 25,185, 71,167,211,189,251,103, 58, 36, 53,113,127,255,238, 65,238, 55,131,
+117,235,192,226,234,214,140, 26, 37,248, 1, 55,111, 21,226,174, 78, 78, 78, 11, 4, 65,232,131,119,223,133,189,212, 17,153, 25,
+ 87,160, 43, 19, 97, 49, 25, 33,138, 20, 84,108, 58, 79,108, 21, 2, 28,122, 83, 84,252, 74, 32, 35, 4, 67,134, 12,193,192,129,
+ 3,113,234,212, 41,172, 90,181, 10, 61,123,246, 68,121,121, 57, 42, 42, 42,160,215,235,107,219,130, 52,138,220,166,186,109,128,
+103,171,255,103,239,186,227,162,184,246,239,185, 51, 91,129,165,247,166,193, 94,158, 74, 21,187, 24,172,137, 37, 70, 77,177,198,
+ 94, 98, 98, 73, 98, 75, 98,108,209, 20, 77, 49,106,244,197,168,137,229,133,168,137, 37, 22,140,193,130,136, 84, 81, 16, 80, 65,
+ 41, 11, 2,210,151, 93,118,119,102,238,239, 15,202, 67,164, 44,198,252,158, 47,111,206,231,195,103,119,150,153, 51,183,204,204,
+ 61,115,238,247,222,139, 50,109, 79,152,203,229, 40, 44,173, 68, 81, 89, 37, 10,138,117, 56,242,235,235,168,212, 85,128,171,212,
+131, 55,112, 80, 57,143, 69,123,187, 65, 0,189,221,245,105, 22,162,177,178,204,164,145, 58,249,249,249, 15, 60, 60, 60,126,137,
+137,137, 25, 63, 97,194, 4,156, 63,127,126, 62,128,153,213, 15,216,249, 19, 38, 76, 64, 76, 76, 12,110,221,186,245, 75,126,126,
+254, 83, 25, 82,106, 48, 24, 42,140,213, 93, 84, 74,165, 82,102,202, 49, 12,195, 12,113,116,116, 36, 6,131, 1, 15, 31, 62, 68,
+ 65, 65, 1, 30, 62,124, 8,173, 86,139,242,242,114,112, 28, 7,163,209,136,200,200,200, 7, 60,207, 71,182, 36, 61, 73, 73, 73,
+237, 23, 47, 94, 60,115,240,224,193,171, 70,142, 28,137,227,199,143,227,199, 31,127,156, 3,224,112,223,190,125, 99, 90,154, 63,
+158,231,255,216,182,109,187,243,172, 25,163,157,127, 62,177,123,227,225, 35,215,123, 76,124, 53, 55,209,205,189,187,227,254,237,
+225,114,142,163, 39, 76, 38, 19,132,238,246,206,206,184,119,239, 30,162,162,162,160,211,233,106, 69,133,161,168, 8,198,194, 66,
+ 16,141, 6, 10,142,131, 46, 35, 3,109,187,119, 7, 1,186,152, 32,172, 27,237, 22,100, 89, 22,132, 16, 16,149,170, 74,100, 53,
+210,173,213,136,184,242,241,241,241,249, 97,215,174, 93,178, 37, 75,150, 4,180,105,211,230,219,156,156,156, 12, 79, 79,207, 23,
+ 62,255,252,243,139,235,214,173, 83, 76,154, 52,169,195,174, 93,187, 38, 54,229, 12,233,116,186,195, 39, 79,158,124,181,117,235,
+214, 78, 9, 9, 9,208,233,116, 16, 4, 1, 35, 70,140, 0, 0, 69,205,126,201,201,201,186,138,138,138,188,196,196,196,178,251,
+247,239, 27, 1,152,244, 18, 96, 97, 97,105, 39,145, 89, 64, 96, 36,176,182,182,133, 68,110, 1,129,147,128, 23, 0, 75,107, 7,
+ 92,137, 77, 70,210,125,118,206,237, 52,132,152,244,182, 83, 45, 88, 29, 28, 28,106,187, 4,107,186, 11,157,157,157, 81, 82, 82,
+242, 68, 2,171,180,180, 20, 37, 37, 37, 72, 77,191,133,188,178, 28,132, 30,138, 0,207,243,168,172,172,210,166,110,206, 30, 56,
+119,232,154, 42,104,188,255,123, 14, 62,228, 98, 65, 28,141,105, 66,100,165, 0, 72,169,233,218, 12, 14, 14,254,120,240,224,193,
+ 48, 24, 12,232,223,191, 63, 18, 18, 18, 70,216,216,216,172,111,233, 72,209,152,152,152, 95,187,118,237,122,170,172,172,172, 53,
+207,243,175,218,217,217, 45,227, 56,174,198,125, 59,193, 48,204,117,141, 70,115,188, 93,187,118,125,252,253,253,143, 68, 71, 71,
+ 79,111, 70,248,147,128,128,128,113,230,230,230,211, 52, 26,205, 33,165, 82,185,108,219,182,109,173,219,180,105,195,220,191,127,
+ 31, 28,199, 33, 35, 35, 67,136,138,138,170,240,247,247, 87,133,134,134,150, 51, 12,211,168,211,230,231,231, 39, 53, 26,141,255,
+ 58,118,236,216,144,182,109,219,226,226,197,139,216,180,105, 19,218,181,107,135, 61,123,246,160, 79,159, 62,240,242,242,130,173,
+173,237,130,210,210,210,192, 79, 62,249,100,152,175,175, 47,142, 30, 61,138,252,252,252, 29, 77, 77,217,192,113,141,135, 86, 85,
+ 84, 84,128, 82,138,231,159,127,126,250,146, 37, 75, 48,106,212,168,227,129,129,129,253, 35, 35, 35,239,152, 80,172,207,164, 83,
+ 85,219, 55,234,234,186,110,200,144, 33, 75,122,244,232,129,253,251,247, 67, 29, 24, 8,237,143, 63,194,102,228, 72, 80, 0,105,
+ 63,252, 0, 74, 41,108, 70, 87,133,194,122,141, 31,143,101,203,150, 13, 27, 59,118,172, 39, 0,255, 70, 56, 55, 78,153, 50,229,
+173,201,147, 39, 35, 54, 54, 22, 59,119,238, 68, 92, 92, 92,205, 4,162, 48, 26,141, 72, 74, 74, 66, 82, 82, 18, 92, 93, 93,241,
+226,139, 47,146,217,179,103, 15, 29, 49, 98,132, 3,128,126,127, 69, 62, 31,211, 32,127, 91, 7,235,209,135,184,189,181,181,117,
+244,182,109,219,236,122,246,236,201,114, 28,135,223,207,159,199, 59, 11,167, 99,248,200, 5,208, 85,202,193,233, 8,120,153,170,
+217,147,105,245, 44, 74, 47, 18, 8,170, 23,160,215,235, 49,251,160, 12, 54,228, 33,190,156,214, 19, 91,183,110,173,234,138,169,
+168, 64, 89, 89, 25,202,203,203, 81, 86,214,124,215, 91,121,177,202, 96, 48, 10,200,206,187,143,172,156, 27,176, 86,181, 2,101,
+ 60,241,160,176, 2, 4, 78, 48,106,147, 33, 84,223,152,149,218, 44,104, 42, 77, 20,199,212,244, 56, 73,131,190,212,228,125, 25,
+134,249,225,192,129, 3,163,182,108,217, 34, 31, 53,106, 84, 71, 87, 87,215,126, 0,240,202, 43,175,116,180,182,182,198,129, 3,
+ 7,244, 77, 61,192, 90,120,193, 50,174,174,174,147,251,245,235,135, 7, 15, 30, 32, 45, 45, 45,210,196, 52,158,141,143,143,159,
+234,233,233, 73, 50, 50, 50,144,149,149,133,194,194, 66, 88, 91, 91,195,206,206, 14, 46, 46, 46, 16, 4, 1, 90,173,214,249,230,
+205,155, 62, 0,206,154,154,166,188,188,188, 34, 0, 95, 85, 84, 84,172,146, 72, 36, 53,214,254,175,120,194, 5,168,111, 38,221,
+ 9,233,214,173,125, 87, 15, 15,219, 14,126,221,186, 57,122,184,223, 41,117,112,244,176,252,237,116,130, 89,222,131,162,228,155,
+ 55,111, 31,109, 73,145,105, 11, 11,161,190,126,189, 42,230,170,172, 12,186,242,114,112,197,197,112,237,208, 1,208,104,192,232,
+116,144,232,116,144, 10, 2,204,204,205, 97,202,219,150,228,210, 37,168, 70, 86, 77,223,162, 79, 74,170,114,172, 8,129,116,192,
+ 0, 16, 11, 11, 16,115,115, 48, 39, 79, 86, 9, 45, 75, 75, 96,119,179,189,100,112,115,115,179,119,113,113, 9,217,186,117,171,
+172,160,160, 0,137,137,137, 9,105,105,105,165, 14, 14, 14, 42,137, 68, 34, 36, 39, 39,255,145,156,156, 60,194,203,203, 11, 60,
+207,183,109,134,238,235,163, 71,143, 6,247,237,219,151,243,242,242, 50,207,207,207,247, 44, 42, 42, 34, 57,213,163,148,106, 16,
+ 21, 21,165,200,204,204,172,224,121,254, 24,170,230,193,106,244, 38,113,116,116,180,144,203,229,175,242, 60, 63,185,171, 23, 47,
+ 41, 44,211, 2,156, 30,233,247,210, 81,172, 49,128,114, 70,100,100,229, 64, 83, 41,224, 97, 97, 25,252,122,190,176, 85,207, 93,
+ 89,229,230,230,182, 82,173, 86,159,104,202,197, 26, 51,102, 12, 40,165,136,138,138,194,165, 75,151,112,233,210, 37,220,187,247,
+111,243,199,218,218, 26,161,161,161, 24, 52,104,144,233,221, 46, 21, 21,112,118,118,134,181,181, 53,142,134,253,128,239, 62, 63,
+ 88, 27,232, 94,231, 5, 9,230,230,230,216,240,206, 23, 22,211,223, 27,247, 33,128, 81,166,112, 7, 7, 7, 79,110,223,190,189,
+ 79, 96, 96, 32,238,221,187, 7,111,111,111,180,111,223,190,107,106,106,234, 12, 83,220,207,250, 72, 76, 76, 52,248,250,250, 58,
+ 57, 59, 59, 47,158, 58,117, 42, 56,142,195,176, 97,195,144,146,146,242,125,126,126,126,246,140, 25, 51, 90, 15, 28, 56, 16, 31,
+126,248,225, 43, 61,123,246, 92,215, 84,119, 89,191,126,253,222, 29, 63,126,252,123, 47,189,244,146,242,210,165, 75, 61,181, 90,
+ 45,235,225,225,193,220,185,115, 7, 60,207, 35, 60, 60,156, 59,123,246,108,182,193, 96,216,124,227,198,141, 94,229,229,229,199,
+226,226,226, 26,117, 46, 31, 60,120,240,214,209,163, 71,135,118,236,216, 17,167, 79,159,198,188,121,243, 78,171, 84,170, 46, 47,
+190,248,162,167,133,133, 5,226,227,227, 97, 48, 24,224,234,234,234,180,124,249,242, 17,195,134, 13,195,185,115,231,176,118,237,
+218, 83,206,206,206, 95, 55, 39,130, 37,213,177,145,117,193,178, 44,226,226,226,240,252,243,207, 99,217,178,101, 0,128,223,127,
+255,221,114,232,208,161, 81, 65, 65, 65, 46,205, 5,230, 55,230, 84, 61, 43,163, 8, 45, 45, 45, 39,239,217,179, 7,183,111,223,
+198,229,203,151, 81, 84, 84, 4,157, 78, 87,187,152,110, 73,113,113,213,116, 13,173, 91,163,235,202,149,248,246,229,151,145,147,
+147, 3,134, 97,236,155,120,198,191,186,114,229, 74,156, 58,117, 10,155, 54,109, 66,105,105,195,109,152,153,153, 25, 2, 2, 2,
+224,227,227,131,180,180, 52, 0,176,255,171,242,249,183,118,176, 26,131,181,181,245,103, 59,118,236,176,235,211,167, 15,171,209,
+104, 32, 8, 2,122,247,234,133,169,211,166,226,204,209,159,225,218,102, 16, 88,157, 25, 56, 75,243,230, 5,150,209, 10,232, 81,
+ 2, 77, 89, 25,148,213,193,164,215,179,116,160,148,194, 96, 48, 64,163,209,212,198,246,212, 4, 83, 55,235, 30, 25, 20,113, 73,
+119,121,143,210,242, 56, 68,198,252, 8,163, 94, 15,175,142, 43, 80,105,116,128,133,211, 12,104, 13,199, 97, 40,174,114,226,229,
+ 86, 65,120,240,160, 0, 32, 76,179, 22, 39,229, 76, 14, 3,130, 81,103,186,192,202,200,200, 40,118,117,117,253, 41, 60, 60,124,
+202,216,177, 99,113,230,204,153, 57, 0, 48,118,236, 88,132,135,135,227,238,221,187, 63,229,228,228, 20,183, 80, 72, 57,160,106,
+ 78,152, 90,215,203,217,217,217,171, 85,171, 86,243,103,207,158, 29,216,189,123,119,236,223,191, 31, 0,206,155,194, 87, 80, 80,
+240,207,165, 75,151, 14, 89,188,120,177, 11,195, 48, 36, 37, 37, 5,132, 16, 56, 57, 57,193,211,211, 19,118,118,118, 40, 46, 46,
+134,175,175,175,133,167,167,231, 40, 83, 5, 86,181,197,239, 1,160,164,230, 77,169,250, 83, 6,192,154, 82,250, 68,163, 90, 5,
+ 65,182,253,236,233,200,237, 1,190,195, 25,175,214, 22, 37,128,158, 92,139,202,182, 48,242,210,150, 53, 94,132, 36,220, 77, 77,
+245,162,130,128,242,162, 34, 24,202,202, 96, 44, 42, 2, 87, 88, 8,226,234, 10,137, 78, 7,182,178, 18,172, 94, 7,165,210, 28,
+ 37,121,121, 32,140, 9,215, 82,157, 6,161, 70, 92,177, 44, 91,235, 90, 17, 11,139, 90,135,139,101, 89,152, 50,117,145, 66,161,
+216,179,115,231, 78, 23, 87, 87, 87,124,241,197, 23,112,113,113,233, 24, 28, 28, 92,208,191,127,127, 51, 7, 7, 7,116,236,216,
+ 17,254,254,254,248,227,143, 63,192,178,236,221,102, 30,108, 28, 33,100,212,229,203,151,223,138,136,136,120,217,213,213,149, 76,
+153, 50, 5,195,135, 15,135, 66,161,128, 86,171, 69, 81, 81, 17, 78,158, 60, 73, 56,142,235, 83,253, 6,220,234,185,231,158,219,
+ 67, 8,201, 78, 79, 79,159, 82,159, 83, 46,151,239,153, 53,107, 86,208,168, 81,163, 8, 35,232,244,161,103,246, 73,120,158, 35,
+239,172,252,142, 15,187,116,129,225,121,142,140,123,125,169,240,219,249, 4,102,206, 91,159,241, 62,189, 94, 68, 98, 98,162,203,
+172, 89,179,214, 3, 56, 97,202,181, 36,145, 72,106,203,179, 62, 88,150,109,116,208,192, 99,206, 8,207,101,143,152,214,251,223,
+ 47, 76,188,193,222,221,197,147,169,113,174, 0,160,180,180, 20, 25, 25, 25, 48, 26,141,176,183,183,135,209,104, 52,105,125,182,
+ 53,107,214, 48,132,144,247, 26,218,211, 84, 0, 0, 32, 0, 73, 68, 65, 84, 39, 79,158,140,220,220, 92,172, 93,187, 22, 43, 87,
+174,196,248,241,227,177, 97,195,134,149,126,126,126,123, 76,153,255,169, 94, 55, 94,123, 27, 27,155,195,235,215,175,151, 89, 89,
+ 89, 33, 46, 46, 14, 93,186,116,193,231,159,127, 46, 73, 73, 73,105,221,169, 83, 39,220,186,117, 11,217,217,217,105,205,197, 34,
+201,229,242, 57, 11, 22, 44, 80,102,102,102, 98,220,184,113,202,180,180, 52,220,188,121, 19,148, 82,196,198,198,114, 71,143, 30,
+205,214,106,181, 3, 98, 98, 98, 30, 2,248,190,185, 23,186,254,253,251, 47,104,223,190, 61,126,255,253,119,204,159, 63,255,172,
+133,133,197,235,197,197,197, 51,244,122,253,231, 35, 71,142, 68,159, 62,125,144,156,156,140, 81,163, 70, 33, 32, 32, 0,231,207,
+159,199,178,101,203, 78, 91, 88, 88, 76,108,166, 28,238,132,133,133,117,245,247,247,175,237,221,144, 74,165,176,177,177, 65, 82,
+ 82, 18, 58,116,232,128,101,203,150, 97,203,150, 45, 88,178,100,137, 48,116,232, 80, 78,175,215,203,106,156,205, 39,196, 51, 49,
+138,176,188,188,156,230,228,228,192,202,202, 10, 33, 33, 33, 72, 58,117, 10,145,179,102,225,222,154, 53,160,148,194,113,253,122,
+ 4,190,255, 62,186,221,189, 11,181, 90,141,125,251,246,129, 97,152,218, 17,177,141,220,243, 40, 41, 41,129,183,183, 55,162,162,
+162,176,111,223, 62,124,241,197, 23,181,177,108, 82,169, 20, 65, 65, 65, 24, 58,116, 40, 82, 82, 82,176,115,231, 78, 88, 89, 89,
+ 65,196, 19, 8, 44, 74, 41,169,251, 89,175,123, 99,160,191,191, 63, 91, 94, 94, 14,157, 78,135, 7, 15, 30, 32, 61, 61, 29,102,
+102,102,200,206,203, 64,207,118,229,200, 37,122, 36,198,166,242,144, 72,174, 55,247, 80,212,235,245,136,140,140, 68,100,100, 36,
+132,142,155, 32, 8, 66, 77, 55, 69,173,123,149,155,155, 43,120,122,122,162,180,180,148,105,190,241,170, 60,123, 62, 60,126,216,
+148,177,207,203, 67,195,190,131,177,146, 67,185,206, 6, 26,157, 30,101, 90, 41,244,138,161, 32,228, 34, 24, 86,129, 62, 62,237,
+240,199,229, 84,157, 96, 52,132, 54,221,224, 64, 16, 12, 15, 41,227, 49,137, 8, 57, 71, 40,120, 93,195, 59,178, 44, 36,114, 21,
+180, 21,101, 2,165,166, 59, 48,182,182,182, 7, 15, 30, 60, 56,182,111,223,190, 22,131, 7, 15,110, 87,221,125,103, 60,120,240,
+160,198,214,214,246, 96, 11,197,213, 42, 66,176, 12, 20,140, 66, 46, 63,103,103,111,255,187,165,165,165,223,176, 97,195,218, 13,
+ 31, 62, 28,109,219,182, 69, 72, 72, 8, 66, 66, 66,206,231,228,228, 92, 49,241, 77,226, 58, 33,100, 66,122,122,250, 68, 87, 87,
+215,161, 61,122,244,112,105,211,166,141,210,218,218, 26, 44,203, 66,163,209,160,160,160,160,102,196, 85, 27, 83,211,250,220,115,
+207,193,213,213,245, 29,169, 84,186,190,222,155, 10, 7,224, 5, 87, 87, 87,139, 39,185,136, 19, 19, 19, 31, 12, 31, 22,236,180,
+253,219,240,246, 90, 45,111,248,245,212, 57,131, 81,111,161, 77, 74,190,219,162,217,236, 13,130,112, 54, 38, 58,122,120,191, 62,
+125, 20,247, 98, 98, 96, 44, 46, 6, 95, 84, 4,137,193, 0,137, 70, 3,182,178, 18, 68,171, 69, 43, 31,115, 64,112,198,181,180,
+108,206,192,243,231, 76, 22, 88,213,221,129, 53,141,127,141,192, 98,234, 8,172,154,238,175,166,224,236,236,108, 62, 98,196,136,
+ 32, 95, 95, 95, 80, 74,241,217,103,159,193, 96, 48,200, 13, 6, 3,140, 70, 35, 12, 6, 3,202,202,202,112,248,240, 97,252,240,
+195, 15, 17, 86, 86, 86, 63,154, 80,231,156,135,135,199, 92, 65, 16, 28, 57,142, 51, 56, 58, 58,202,126,250,233, 39, 40,149, 74,
+ 48, 12, 3, 31, 31, 31, 40,149, 74,189,155,155, 91, 9, 0, 56, 57, 57, 25,183,108,217, 34,153, 49, 99,134,172,145,183,127,159,
+183,222,122, 75, 90, 35, 26,221, 90,109,224, 12, 6,131, 0, 0,157,123, 12,248,119,183,216, 48,224,246,237,219,216,188,121, 51,
+ 52, 26, 13, 88,150,149,153,120,141, 34, 56, 56, 24, 67,135, 14,173,237, 14,116,114,114,130, 94,175, 7,199,113, 38,139, 43, 0,
+168,153, 68,116,205, 26,194, 96, 53,176, 39,208, 50, 29, 64,109,252, 84, 73, 73, 9, 50, 51, 51,113,255,254,253,218,238, 19,129,
+154,246,150, 29, 30, 30,222,223,203,203,203,205,195,195, 3,187,118,237,130, 86,171,189,251,203, 47,191,180,157, 50,101, 10, 90,
+183,110,237,192,243,124, 48,128,211, 45,185, 78, 57,142,155,178,112,225, 66, 11, 39, 39, 39,236,222,189, 27,199,142, 29,203,235,
+209,163,135,211,244,233,211,209,177, 99, 71, 36, 38, 38,226,171,175,190,122, 40, 8,194,171, 38,112,165, 93,187,118,205,217, 96,
+ 48, 32, 59, 59, 27,130, 32, 32, 57, 57, 25,217,217,217,194,133, 11, 23,178,117, 58, 93,141,184,106, 22, 94, 94, 94, 42, 63, 63,
+ 63,167,148,148, 20, 28, 58,116, 8, 70,163,113, 77, 98, 98,162,193,198,198,230,208,182,109,219, 86,182,105,211,198,118,192,128,
+ 1,232,211,167, 15, 40,165, 56,126,252, 56, 62,250,232,163,211,102,102,102,175, 39, 38, 38, 26,154,113,213, 95, 91,183,110,221,
+ 7,246,246,246,227, 38, 77,154,196,248,249,249, 33, 58, 58, 26, 60,207, 35, 56, 56,184, 86, 92,157, 57,115,230,167,211,167, 79,
+191, 4, 64,166, 82,169,236, 76,153, 86,130, 16,242, 2,128, 26,135,160,130, 82,250,219,179,214, 80,235,116, 58,164,164,164,192,
+217,217, 25, 29,251,246, 69,199,244,116,252, 81, 29,212, 62,104,233, 82,148,107, 52,216,179,103, 15, 98, 98, 98,192,178, 44,218,
+182,109,219,252,243,206, 96,192,157, 59,119, 80, 80, 80,128, 49, 99,198, 96,210,164, 73,248,244,211, 79, 97, 48, 24,176,106,213,
+ 42, 20, 22, 22, 98,215,174, 93, 72, 77, 77,133, 68, 34,129, 74,165,250,203,242,215,148, 6,249, 91, 59, 88, 53,194, 72, 16, 4,
+168,213,106, 68, 69, 69, 33, 45, 45, 13, 42,149, 10, 90, 78, 16,182, 94,141, 23, 24, 34, 85,115, 20, 17,132,151,174,106,174, 66,
+121,158, 71, 68, 68, 4,110,223,190, 13,235, 14,180, 38, 48, 17, 58,157, 14, 26,141,166,198,185,210, 38, 37, 37,229,150,148,148,
+216, 53,151,182, 7, 29,152,253,161,161,231, 22,249,251,116,109, 63,120,224, 71, 56,113,226, 67, 20,151,150, 66, 83, 41, 65,185,
+214, 0,141,142,194,205,178, 45, 2,123,248, 34,255,161, 30, 41, 55, 99,178,243,101,182, 77,190,137, 81,130,111, 38,140, 13, 94,
+252,193,187,179,157,187,116, 92,174,164,121,191,129,150,196, 82,212,204, 87, 73, 24,200, 85, 14,128, 68, 65,163,147, 10,202,255,
+ 72,208, 22, 80,130,111, 90, 32, 8, 52, 30, 30, 30, 63, 44, 92,184,112,125, 84,212, 53, 39, 0,136,142,142,206,203,205,205,125,
+ 63, 43, 43, 75, 99, 42, 15, 33,196,134, 16, 44, 19, 4,202, 86,139,180, 33,139, 23, 47,118,235,219,183,175, 65, 42,149, 34, 35,
+ 35, 3,159,126,250, 41,194,195,195, 15,229,228,228,108,111,201,172,206,148,210,120, 0,241,132,144,181, 9, 9, 9,131,131,131,
+131, 55,116,232,208,193,131,227, 56,148,148,148,160,168,168, 8,169,169,169,168,168,168,104,118,217,145,140,140,140,115,153,153,
+153,131,231,206,157,139,190,125,251, 78,219,187,119,239,107,117,109,224,238,221,187, 95, 29, 61,122,180,135,181,181,181, 76,171,
+213, 26,147,147,147, 47,182,232, 53,211,211,179,223,162, 69,139,122,204,153, 51, 7,229,229,229,216,183,111, 31,182,111,223, 14,
+ 79, 79,207,126,153,153,153,151, 91, 32, 0, 15, 30, 11, 13, 93,220,163, 83,167, 14,173,189,188,144,114,246, 44,100, 6, 3,164,
+ 28, 7,182,162, 2, 82, 99, 37,158,243,183,128, 76,233,128,156,123, 90, 28,186,121,243, 62,165,180,217, 9, 50, 13,193,193, 48,
+ 38, 39,131,101, 89,200,130,130,170, 98,173,204,205,193,252,250,235,191,133,213,234,213,160, 22, 22, 16,130,154, 15, 65,120,240,
+224, 65, 69,251,246,237, 99,111,221,186,229,215,169, 83, 39,172, 89,179, 6,153,153,153,160,148, 34, 47, 47, 79,151,151,151,167,
+ 46, 44, 44,204, 96, 24,230, 88,118,118,246, 30, 83,151, 34, 17, 4,193,241,248,241,227, 53,142, 34,126,255,253,119,184,185,185,
+193,218,218, 26,165,165,165,152, 50,101,138,252,131, 15, 62, 0, 0,196,198,198, 74,205,204,204, 26,119,117,141, 70,202, 48, 12,
+201,204,204, 52,152,155,155, 19, 59, 59, 59,137, 66,161, 64,101,101,101,173,208,186,125,251, 54, 78,156, 56,129,172,172, 44,216,
+217,217, 49,182,182,182,224,121,190,200,196,180,130,101,217,199, 2,218, 91, 42,174,234, 98,245,106, 42, 16, 16,210, 70,194, 94,
+207,206,205, 28,236,230,236,129, 7, 15, 30, 32, 35, 35, 3, 25, 25, 25,200,204,204, 68,251,246,237,145,126,255, 46,228, 50,233,
+117, 19,239,163,215,122,246,236, 9,173, 86,139,216,216, 88, 94, 42,149,190,150,144,144, 16,161,209,104,164, 61,122,244,192,253,
+251,247, 95,105,169,192, 98, 24,198,195,220,220, 28, 90,173, 22,199,143, 31, 47, 84,169, 84,157,227,226,226,198,167,166,166,126,
+234,233,233,105,121,255,254,253, 7, 6,131, 97, 68,116,116,116,170, 9,238,200,204,247,222,123,239,128, 32, 8,109,254,241,143,
+127,176,163, 71,143,182,112,119,119, 71, 84, 84, 84, 69,101,101,229, 39,166,138, 43, 0, 72, 79, 79, 47,191,116,233, 82, 94,215,
+174, 93,157, 92, 93, 93, 33,149, 74,215,185,185,185,125, 98, 97, 97,241,241,200,145, 35,109, 67, 66, 66,240,243,207, 63,195,194,
+194, 2,233,233,233, 57,201,201,201,223, 56, 57, 57,109, 55,197,193,139,138,138, 74, 7,240, 70, 96, 96,224,199, 95,126,249,229,
+ 50, 66,200,107,103,207,158,173,141,189,219,188,121, 51,206,156, 57,243,211,115,207, 61, 55, 43, 36, 36,100,122, 11,171,222,156,
+ 82,122,179,250,153,250,143, 58,191, 63, 43,177, 89, 70,189, 94, 15,123,123,123,228,231,231, 35, 47, 47, 15,173, 90,181, 66,255,
+254,253, 97, 52, 26,241,203,201,147,184, 84, 45,182, 28, 28, 28, 96,101,101,133,248,248,120, 80, 74,111, 53,217,249, 99, 48,212,
+246, 70,196,199,199,195,201,201, 9, 75,150, 44,129, 94,175,199, 79, 63,253,132,184,184, 56, 48, 12, 3, 71, 71, 71, 88, 90, 90,
+214,196,104,221,130,136,167, 39,176,170,215,204, 26,219,163, 71, 15, 73,106,106, 42, 82, 83,171,238,217,138,138, 10, 78,194,226,
+232,131,235,191,188,209,132, 0,232, 86,111,126,152,136,213,171, 87,247,158, 54,109, 26,220,221,221,177,243,154, 1,247, 51,120,
+ 24, 12, 6,228,228,228,224,202,149, 43,124,255,254,253, 89,142,227,202,121,158, 31,149,153,153,249, 58, 33, 36,183, 73,206,144,
+ 16,222,209,123,220,132,109, 59,254,249,199,180,105,211,108, 71,143,217,142,216,196, 27, 40,210, 56, 1, 0,220, 28, 44, 16,216,
+233, 61,228, 61,172,196,153, 83, 39,138,169, 80, 49,145,198, 29, 50, 54,197,153,148, 70,191,239,214,138, 92,152, 60,251,253,183,
+125,186,121, 13,125,103,238, 75,246, 29, 60,198, 40, 80, 28, 73, 21, 86,101,144, 91, 56,226, 86, 90,129,246,183, 8,245,195,130,
+ 18,238,119,194,227,171,164, 12,154,222, 20,103,125, 20, 22, 22, 94, 86,171,179, 29,235,204,218,238,168, 80, 40, 47, 55, 35,168,
+154,228,172,153, 78,225,244,233,211,184,116,233,146,225,246,237,219, 23, 8, 33,199,213,106,245,245, 39,229,164,148,150, 1, 56,
+ 98,105,105, 41,232,116,186, 15, 71,140, 24,209,158, 16,130, 59,119,238,224,252,249,243, 97, 5, 5, 5,159, 52,199, 89, 81, 81,
+177,224,237,183,223,254,102,240,224,193, 67,170, 71, 60,201, 83, 82, 82, 64, 41, 69, 64, 64, 0,250,244,233,211, 70,175,215, 11,
+ 87,175, 94, 45, 60,121,242,228, 33,157, 78,183,165, 37,233,204,204,204,188, 28, 16, 16, 80,213, 13,173,213, 34, 43, 43, 11, 28,
+199, 65,173, 86,183,168, 60, 67, 66, 66,248,192,192,192, 87,190,252,254,251, 63,222, 26, 55,206,182,215,232,209,200,142,136,128,
+ 94,173,134,156,231, 33,151, 41, 97,212, 56,161, 48, 91,135,239,110,222, 44,213,243,252,235,245, 27,135,134,210, 89, 53,167, 25,
+169, 29, 45, 72, 84,170,170,184,171, 58,163, 8,169, 74, 5, 70,165, 2, 35,147, 61,230, 96, 53,196,169,213,106, 39,206,158, 61,
+ 59,242,183,223,126,179,121,253,245,215, 49,122,244,232,248,210,210,210,225, 5, 5, 5, 38,245,109, 55,196,201, 48, 76,254, 11,
+ 47,188,224, 88, 89, 89,201,189,246,218,107,146,130,130, 2,116,236,216, 17, 0, 80, 86, 86,134, 83,167, 78,161, 83,167,170, 48,
+148,155, 55,111,162,107,215,174,141,114,198,199,199,255,188,119,239,222,185,227,199,143,151,241, 60,207, 87, 7,197, 19, 23, 23,
+ 23, 54, 42, 42, 74, 56,118,236, 24,180, 90, 45, 60, 60, 60,152, 86,173, 90,145,168,168, 40,225,238,221,187,145,132,144,149,166,
+212, 59,165,244, 17,113, 37,145, 72, 80, 81, 81, 97,146,184,106,234, 90,162,160,212, 81, 67,214,188,177,100, 66,224,185, 67,145,
+ 42, 11, 11,139,218,152,159,118,237,218, 65, 34,149, 96,247, 47, 91, 53, 37,101, 15,215, 54,199, 25, 20, 20,164,144, 74,165,163,
+125,124,124, 16, 29, 29, 13,189, 94,127,241,220,185,115,183,130,131,131,207,197,199,199,143,232,216,177, 35, 24,134,121, 33, 40,
+ 40,200, 34, 44, 44, 76, 99,106, 58, 41,165,105, 89, 89, 89,240,242,242,130,141,141,141,149,209,104,228,226,226,226,126,236,222,
+189,251,209,212,212, 84, 47,133, 66,113, 63, 58, 58,186,220,148,188,199,196,196,100, 2,232, 23, 20, 20, 36,185,113,227,198,253,
+254,253,251, 67, 46,151,163,125,251,246,170, 59,119,238,188,142, 38,166,142,168,207, 73, 41, 21,220,221,221,183, 93,187,118,109,
+173,143,143, 15, 94,123,237,181,231,163,163,163,159,247,246,246, 70,219,182,109, 17, 30, 30,142,176,176,176, 67,130, 32,188,149,
+147,147,163,107,234,133,175,177,188, 87, 7,173,207,244,243,243,123, 89, 34,145,192,210,210,146,205,206,206,102,207,158, 61, 11,
+ 74,233,155, 77, 13, 26,104,238, 89, 87, 31,166,196, 92,181,148,243, 73,238, 77,134, 97, 62,154, 58,117,234,215,115,230,204, 81,
+246,236,217, 19, 37, 37, 37,181,162,255,183,223,126,131, 32, 8,176,183,183,135,189,189, 61,110,223,190,141,163, 71,143,234,139,
+139,139,183, 41,149,202,207,155,226,156, 50,101,202, 35,156, 53,226,237,196,137, 19,181,131, 72,236,237,237,145,154,154,138, 35,
+ 71,142,232,138,139,139,183,114, 28,183,229,175,204,251,255,156,192, 42, 46, 46,126,119,197,138, 21, 3,103,204,152, 97,167,213,
+106, 89, 7, 7, 7,168,213,106,238,236,217,179, 69,229,229,229,239,182,228,100, 44,203, 14, 87,171,213,147, 22, 45, 90,180,182,
+125,251,246,118,111,188,241, 6, 22, 44,232, 4,189, 94, 15,133, 66, 1,153, 76,246,237,137, 19, 39,198,219,216,216,100, 31, 63,
+126, 60, 19,192, 38, 83,120,243,227, 15,223,113,241, 25, 51,244,235,175,183, 31,240, 13, 8,244,124,206,203, 75,209,207,211, 26,
+ 6, 35,143, 7,121, 15,113,225, 74, 82,101, 74, 98, 92, 22, 56,221,228, 7, 55,142, 39,153,194,121,163, 74, 48,189,221,163, 29,
+241,126,109,254,230, 69,253,123,182,237,245,230,107, 1,182,165, 66, 9, 61,122,236,118, 97, 90,102,249, 53, 9,139, 47,111,166,
+211,248, 39, 41,120,157, 78,103,168,223, 19,164,211,233, 12, 45,180, 85,139, 9, 33,159, 50, 12, 89, 6, 10, 70, 46,151, 71,110,
+223,190,125, 31,128,108, 74,105,164, 90,173,214, 62,173, 11,165,172,172,236, 23, 66, 72,236,157, 59,119, 22, 51, 12, 99,195,243,
+124,210,131, 7, 15,126,162,148, 54, 55, 75, 56,170, 39,187,124,201,195,195, 99,192,229,203,151, 55,141, 28, 57,178,219,139, 47,
+190,136,220,220, 92, 72, 36, 18,196,199,199,235, 79,158, 60, 25, 89, 92, 92,252, 17,165, 52,170,165,105,171,118,176, 48,119,238,
+ 92,148,149,149,225,208,161, 67, 56,115,230, 76,139, 29,172,154, 7,120, 96, 96,224,208,245,123,246, 28,124,161, 83,167, 86,157,
+218,182,149,181,238,218, 21,102,230,230, 40,121,248, 16,241,247,114,248, 31,147,147,211,181, 28, 55, 57, 38, 38,198,164,107,201,
+104, 52,194,214,214, 22,148, 82, 72,151, 47, 7, 8, 1, 37, 4,149,213,179,120,115, 28, 7,105,239,222,160, 44,139, 82,173, 22,
+ 6,131, 1, 74,165,178, 73,206,236,236,236,108, 79, 79,207,215,223,124,243,205,223,246,237,219,199, 4, 5, 5,245, 56,118,236,
+ 24,253, 51,117,156,149,149,213, 30, 0,220,220,220, 30, 88, 89, 89, 73,222,120,227, 13, 24,141, 70, 84, 84, 84,160,180,180, 20,
+ 15, 31, 62,212, 47, 90,180, 72, 14, 0,114,185,220, 56,124,248,240, 70,159, 31,106,181,122,133,167,167,231,233,175,191,254,122,
+249,140, 25, 51, 2,199,143, 31, 47,101, 89, 86,200,206,206,230, 14, 30, 60, 72, 58,116,232,192, 40, 20, 10, 18, 17, 17, 33,220,
+188,121,243, 42,165,244,147,236,236,108,147, 87, 26,168,113,213, 5, 65,168,157,191,170,169, 81,102, 45, 65,254,117, 26,239,213,
+199,230,179, 65, 19, 2,222, 91,191,244, 11, 11, 7, 71, 7,112, 28,135,180,140,187,248,254,232, 55,154,210,202,226, 79, 11,110,
+ 52,191, 6,167, 92, 46, 55,179,179,179, 83, 41,149, 74, 68, 69, 69, 1,192,161,234,134,233, 95,177,177,177, 35, 58,117,234, 4,
+ 27, 27, 27,179,252,252,252,246, 0,226, 90,144,196,187,106,181, 26, 70,163, 17,142,142,142,146,148,148,148, 86, 0,210, 18, 18,
+ 18, 42, 0,220,124,146, 60,135,133,133,113,253,250,245,187,125,227,198,141,128,231,158,123,142, 68, 70, 70,106,116, 58,221,193,
+150,242, 56, 59, 59,127,125,226,196,137,190,148,210, 33,190,190,190,104,221,186,117,141,107,143,139, 23, 47,134,100,103,103,207,
+126, 74,139, 59, 83, 66, 8,202,202,202,216,234, 50, 53,168, 84,170, 39,229,173,168,227, 92, 85, 60,107,141,116, 86, 86,214, 65,
+ 23, 23,151,115,171, 87,175, 94,209,190,125,251,153,179,103,207,102, 59,118,236,136,146,146, 18, 88, 89, 89,193,213,213, 21,217,
+217,217,216,183,111, 31,159,159,159,255, 3,203,178, 31,231,212, 31,161,210, 2, 78, 91, 91, 91,184,186,186, 34, 43, 43, 11,251,
+246,237,227,243,242,242,190,231,121,126, 99, 94, 94, 94, 30, 68,180, 76, 44,155,210,107, 84, 61, 77,195,103, 60,207, 15,172,113,
+181,138,139,139,223,109,110,125,187,198, 20,110, 80, 80,144,196,204,204,108, 82, 65, 65,193, 90, 15, 15, 15,187, 55,222,120, 3,
+171, 86,173, 66, 66, 66,130,249,216,177, 99,237, 36, 18, 9, 23, 18, 18, 82,218,210, 55,134,154,197,158, 33,145,141, 0, 21,186,
+ 1, 32, 96,216,102, 23,123, 54, 69,137,119,111, 75, 6,241, 20,179,170, 14,192,174,196,187, 52,236,207,190,217,212, 93,156,153,
+ 82, 52,187,176,115, 99,156, 13, 5,185, 63,233,219,210, 95,241, 6, 86,239,127,196,213,213,117,130, 92, 46,255,122,194,132, 9,
+ 22,123,247,238,213,229,229,229, 45, 2,112,168,169, 53, 3,155, 75,167,155,155, 91, 69,235,214,173, 97,103,103,135,194,194, 66,
+220,191,127, 31,106,181,218,252, 73,211, 89,119,177,103, 84, 47,246, 76, 77, 88,236,185, 62,103,175, 94,189,238, 25,141,198, 22,
+ 45,190, 42,149, 74, 31, 42, 20,138, 54, 53,231,104, 42,157,238,238,238, 19, 60, 60, 60,214,101,103,103,255,154,149,149,181,236,
+105,212,145,187,187,123, 47, 66,200, 81, 65, 16,148,245, 29,174, 26, 17,230,234,234,218, 74, 46,151, 63, 18,228,222, 24,167,167,
+167,103,127,165, 82,185, 98,210,164, 73, 61, 71,143, 30,205, 68, 70, 70,226,226,197,139,124,100,100,228, 53,163,209,184, 41, 51,
+ 51,243, 82, 75,210, 57, 97,194,132, 4,131,193,208,218,196,178,204, 39,132, 60,178,112,182,169,215,188,131, 15,241,179, 54,179,
+255, 80,111, 48,118,103, 8,168, 84, 42, 77, 40, 41,123,184,182, 33,113,213, 16,103,245,244, 12,191,216,218,218, 14, 46, 42, 42,
+186,193,113, 92, 80, 88, 88, 88,165,159,159,159,212,198,198,230,128,149,149,213, 11,165,165,165,151,251,246,237, 59, 98,245,234,
+213,130,169,117, 20, 24, 24,216,185, 77,155, 54, 81, 43, 86,172, 32,235,214,173, 67,102,102,166,223,213,171, 87,147,255,108,189,
+247,234,213,171, 53,203,178,123,120,158,111, 67, 8,217,123,245,234,213,143, 76, 17, 67,245, 57,187,118,237, 42, 43, 41, 41,153,
+239,225,225,241,150,179,179,179,211,131, 7, 15, 50, 50, 51, 51, 63,207,201,201,217,107,170,184, 50,165,142,252,252,252,138, 0,
+200, 1,192,148,120,171,255,239,103,221, 95,193,233,233,233,217,134,227,184,213, 62, 62, 62, 99,167, 79,159, 78,146,146,146, 16,
+ 26, 26,138,244,244,244, 99, 12,195,172,206,202,202,186,243, 52, 56,207,158, 61, 75,211,211,211,143, 72, 36,146,181,153,153,153,
+105,255, 95,121,255,159, 20, 88,127,213,197, 87, 35,180,138,138,138, 86,169, 84,170,219,161,161,161, 47, 60,107, 23,244, 95,205,
+ 73, 8,113,170,118,163,242,254,151,242, 78, 8,145, 40,149, 74,127,157, 78,119,139, 82, 90,250,148, 56, 87, 1, 88, 9,224, 99,
+ 74,233,134,255,181,107,233, 89,231,172, 22, 90,139, 40,165,168,172,172,252,178, 41, 97,245,119,202,251,224,193,131, 61,207,157,
+ 59,151, 89,255,217,167, 84, 42,109,116, 58, 93,113,216, 19,188,248,249,251,251,127,196,178,236, 4,142,227, 14,197,196,196,172,
+123, 22,243, 78, 8, 33,173, 91,183,150, 55, 53,201,173,120, 31, 61, 25,167,171,171,171, 47,128,229, 64,213, 50, 74,153,153,153,
+209, 79,139,147, 16,194, 3,248, 68,173, 86,199,255,127,231,253,239, 6,201,127,242,228,213, 15,150,189,104,193, 98,188,127, 55,
+152, 34,172,254,166,249,230, 0, 92,125,202,156, 27, 0,108, 16,111,235,103, 19,213,130,234,210,255, 90,190,235,139,171, 58,207,
+190,130, 39,229,140,142,142,254, 8,192, 71,207,248, 61, 78, 1, 84,138, 87,254,211, 71, 78, 78, 78, 44,128,241,207, 58,231,255,
+ 58, 24,177, 8, 68,136, 16, 33, 66,132, 8, 17, 34,158, 46, 8,128,110,141,188,125,152,108,253, 17, 66,186,181,244,196, 38,116,
+247,136,156, 34,167,200, 41,114,138,156, 34,167,200,249, 55,227,108,142,251,239,210,245,248, 31,141,193, 18, 57, 69, 78,145, 83,
+228, 20, 57, 69, 78,145, 83,228,252, 59, 66,236, 34, 20, 33, 66,132, 8, 17, 34, 68,136,120,202, 48, 57,200,189,123, 59,226,206,
+ 27, 49, 10, 44,134, 3, 0,120,156,102,165, 56,158,112,135,102, 63,233,201, 93, 92, 92, 58, 19, 66, 38, 51, 12, 51, 30,128, 32,
+ 8, 66, 8, 33,228, 71,181, 90,157,250,164,156,129,129,129,157, 57,142,123,149, 16,242, 18, 0, 80, 74,127,145, 72, 36,255,138,
+140,140, 52,105, 6, 90, 51, 51,179,123, 58,157,206, 17, 0,148, 74,101,190, 78,167,243, 66,245,172,227,227,199,143, 39, 5, 5,
+ 5, 4, 0, 46, 92,184, 80,179,214, 38,109,110,134,116,133, 66,113, 79,175,215, 63, 54, 84, 95, 42,149, 26,108,108,108,138,237,
+237,237,139, 29, 29, 29,139,100, 50,217,205,130,130,130, 11,241,241,241,209,148,210,220,150,228,123,224,192,129, 31, 40, 20,138,
+133,122,189,126,103, 88, 88,216, 7,127,245,133, 67, 8, 9,240,116,115,217,105, 52, 26,132,220,252,194,143, 40,165, 39, 90,114,
+124,187,118,237,228,238,238,238,164,254,208,234, 47,231, 16, 23,202,128, 89,188,163,249,249,181,154, 73,159,175, 84, 42,157,235,
+236,236, 60, 52, 43, 43, 43, 22,192, 42,113, 22, 98, 17, 34, 68,136, 16,241, 76, 8, 44, 63, 63, 98,166, 43,197, 96, 8, 24,213,
+193,203, 57,112,241,220,241,246,254,189,135,153, 87, 84, 24,232,197,243, 39, 2,190, 59,112,124,193, 63,218,144,107, 60,193,113,
+ 51,107,132,198,196,208, 70, 39,182,252,234, 29,201, 61,158,231, 29, 1, 64,128, 68,243, 69,136,227,157,128,128, 0,239,165, 75,
+151, 34, 48, 48, 16,130, 32,224,194,133, 11,139,191,248,226,139,197,174,174,174,209, 44,203,238,151,201,100, 63,167,165,165, 53,
+ 59,132, 63, 32, 32,192, 67, 16,132,241, 0, 94,233,213,171, 87,215,121,243,230,161,125,251,246,168,172,172, 68,100,100,228,210,
+253,251,247, 47,245,243,243, 75, 4,240, 19,195, 48, 63, 71, 69, 69,101, 53,198,165,211,233, 28,107,244, 18, 33,196,113,246,236,
+217, 26,163,209, 8,189, 94, 15,163,209, 8,149, 74,149,168,211,233,174,247,235,215, 47,218,210,210,242,202,201,147, 39,111, 3,
+224,187, 56,155,245,108,237,225, 48,252,183,232,140,143,234,115,234,245,122, 71, 93,100, 36,192,243,224,238,223,135,110,240, 96,
+ 84,175, 27, 39, 99, 71,140,112,226, 24,198,137,148,151,223,213,253,248,227,142, 78,157, 58,213,206, 99,210, 20,103, 61, 49, 65,
+230,206,157,187,116,249,242,229,210,137, 19, 39,190, 17, 20, 20,180,166,177,161,223,166,114, 54,115, 62, 69, 47,255, 30,167,142,
+ 31, 62,164, 4, 33, 24, 59,118,252, 30, 66,200, 44, 74,233, 47,245,247,245,241,241, 9,150,201,100, 31,113, 28, 23, 43,145, 72,
+ 62,136,140,140, 44,243,247,247, 63,236,224,224, 48, 92,175,215,195,215,215, 55, 34, 54, 54,118, 48, 0,236,152, 73,214,200,129,
+197,224, 65,118,206, 36,219,230,124, 71,151, 63, 97,250,102, 79,155, 54,237,243, 13, 27, 54,176,213,147,240, 13,233,210,165, 75,
+123, 66,136, 63,165, 84, 43,222,246, 34, 68,136, 16, 33,226, 63, 38,176, 58,183, 37,175,154, 43,100, 75,150,207,127,209,101,196,
+240,145,150,118, 30,190, 18, 16,182,202,145,177, 2, 25, 59,121,169,197,152,137,111, 91,164, 39,134,187,159,252,237,196,144, 31,
+143,158,207,233,220,150,108,185,117,151,254,171, 33, 62,158,231, 29,151,204,152, 7, 0,216,178,123,135, 69,114,114,178,183, 74,
+165,122,100, 89,144, 97,195,134, 97,200,144, 33,200,200,200,240, 63,124,248,176,255,158, 61,123, 62,245,240,240, 88,157,149,149,
+181,181,113, 17,232,183,206,221,221,125,241,210,165, 75,137,191,191, 63, 20, 10, 69,237,255, 44, 44, 44, 16, 28, 28,140,224,224,
+ 96,228,230,230,118, 13, 11, 11,235,122,224,192,129,181,126,126,126, 95,196,196,196,152,228,242,188,254,250,235,120,248,240, 33,
+ 30, 62,124,136,210,210,210, 28,141, 70,147,175,211,233,114,148, 74,101,234,160, 65,131,238, 0,224, 59,186, 89,118,112,116,176,
+ 63,188,113,253, 90,160,137,161,211,234, 62,125, 0, 0,218, 27,255,238,182, 54,167,148, 66, 38, 75,145,228,228,252, 90, 87, 92,
+153,202, 89, 45, 48,109,211,210,210, 4,153, 76,134, 78,157, 58, 73, 83, 82, 82,238, 5, 5, 5,125, 23, 22, 22,182,166,238,126,
+ 45,225,108, 6,254, 31,189,187, 64, 86,112, 55, 14,183,174,156,197, 24, 63, 15,101,236,205,148,213, 0, 30, 19, 88, 44,203, 46,
+255,237,183,223,188,175, 93,187,230,189,122,245,234,118,126,126,126,163, 1, 12, 58,125,250, 52,164, 82, 41,130,131,131,123, 7,
+ 5, 5,217,203,184,252, 81,163,219,147,165,243, 23,207, 37, 0,176,235,155, 93,111,110, 95, 64,182,205,223, 70,179, 90, 32,172,
+100, 44,203,126,177,111,223,190,105, 83,166, 76,193,253,251,247,113,249,242,101,168, 84, 42,172, 91,183,174,245,210,165, 75,215,
+ 0,120, 87,188,237, 69,136, 16, 33, 66,196,127, 76, 96,177, 20,239, 70, 94, 75,236,192,112, 15, 9,145, 90, 53,184, 15,195, 72,
+208,182,219, 64,201, 92,175,127,216,140, 24, 50,212,234,229,105,139,223, 5,240, 47, 83, 78,108,105,105,217, 8, 39,131,231,158,
+123, 14,239,188,243, 14,188,189,189,229, 83,167, 78,125, 31,192,214, 38,168, 22,135,132,132, 16,150,101,193,178,108,163, 59,185,
+184,184, 96,200,144, 33,112,113,113, 33,239,190,251,238, 98, 0, 13, 10, 44,165, 82,153, 79, 8,113, 4, 0, 59, 59, 59,236,216,
+177, 3, 70,163, 81,168,168,168,184, 81, 81, 81, 17,111, 48, 24,162, 20, 10,197,213,139, 23, 47,222, 1,128, 14, 30,102,110,230,
+114,243,227,187,118,108,133,177,236,129,109, 99,231,231,179, 30,215, 9,148,210, 18,198,204,236,190, 52, 61,253,176,172,164, 36,
+166,230,119, 83, 57, 1,160, 95,191,126, 54, 22, 22, 22, 23,182,111,223, 46,149,201,100,152, 53,107,150,133, 90,173,198,103,159,
+125, 54, 31,192,154, 39,225,108, 66,192, 88,247,239,227,159,252,245,166, 15, 45,125, 3,251,225,234,207,219, 81, 92,172, 65,121,
+ 89, 5,120,129, 42, 26, 58,134, 82, 90,120,231,206, 29,140, 24, 49, 2, 57, 57, 57, 3,118,238,220,185, 83, 16, 4,162,209,104,
+106, 23,106, 85,169, 84,183, 7,246, 9,146, 51,119,215, 62,241,133, 76, 8,113,180,178,178,250,233,204,153, 51, 1, 1, 1, 1,
+184,122,245, 42,238,222,189,139, 5, 11, 22,232, 23, 44, 88, 32,155, 58,117, 42, 89,178,100,201, 60, 66,200, 47,148,210, 8,241,
+214, 23, 33, 66,132, 8, 17,255, 17,129, 5,128,101,205,219, 17,253, 31, 47, 11,172,195, 64,194,186,142, 36, 68,233,246,200, 14,
+154,135,247,144, 28,177,143,222, 75, 56, 70, 91,121, 79, 38, 0,216,122,141,235,191, 23,151,100,217,130, 45,187,119, 56, 0,128,
+220,204, 30, 33, 33, 33, 24, 60,120, 48, 14,127,221, 21,229, 37, 85,203, 38,169,172, 93, 49,238,173, 68, 36, 39, 39, 35, 60, 60,
+188,102,161, 89,105, 99,156, 53,109, 43,162,163,145,223,183, 47,228,133,133, 48, 55, 55,135, 92, 46,127,100,135,148,148, 20, 92,
+188,120, 17,247,239,223, 71,219,182,109,171,142,105,132, 83,171,213, 62, 55,101,202,148,130,201,147, 39,155,237,221,187, 23,105,
+105,105, 46,145,145,145,101, 13, 21,144,247,115, 54,214, 50, 65,118,124,247,142, 47,164, 48,104,108,147,163,194,241,143, 17,115,
+ 26, 76,167,110,224,192, 90,231,202, 44, 48, 16,140,151,151,129,200,100,169,133,187,118, 13,245,245,245, 53,182,148,179,127,255,
+254, 43,121,158,127, 83, 16, 4,197,238,221,187,165, 14, 14, 14,204,150, 45, 91,140,103,207,158,229, 41,165,140, 76, 38,219,254,
+ 36,233,108, 10, 82,137,228,195,207, 87,191,107,105,206, 24, 17,251,219,143,200,186,159,129,235,183,179,141,255,186,156,196,235,
+141,220,220,134,202, 83, 34,145,188,181, 98,197, 10,159,221,187,119,187,206,156, 57, 19, 50,153,236,149,135, 15, 31,226,208,161,
+ 67, 48, 55, 55,199,142, 29, 59,240,220,115,207,201,121,158, 71,220,137,135,216,241,213, 54,128, 82,232,140,178,131, 75,246,113,
+ 89, 77,212,123, 93,113,213,181,117,235,214,199,255,248,227, 15, 39,119,119,119,132,133,133, 33, 55, 55, 23,174,174,174, 88,176,
+ 96,129,124,211,166, 77, 7, 74, 75, 75,199,110,216,176, 65,153,144,144,176,151, 16,210,129, 86,225,169,143,128, 17, 57, 69, 78,
+145, 83,228, 20, 57,255, 18, 4, 0,112, 4,144, 15, 32,170,222, 54,170,191,163,129,237,130,234, 54,223,190, 14, 87, 1,170, 98,
+168, 29, 1,240, 0,174, 1, 40,250, 75, 4, 22, 33,100, 32,128, 48, 0,107, 40,165, 31, 61,178,135, 96, 4,159,119,142,242,121,
+191, 83,198,214,159,176,174, 99, 72, 81,137, 14,183, 34,190,167, 57,201,127, 80, 84,199, 43, 25,244,101, 77,158,232,171, 35, 30,
+ 29,229,114,121,225,173, 91,183,240,251,239,191, 3, 0,142, 28, 57,130,242,146, 28,212,233, 58,196,231,159,127, 14,142,227,192,
+ 48, 12, 12, 6,211,214, 62,166,149, 85,113,210,122,189, 30,122,189, 30,164,103, 79, 72, 7, 12,192,157, 5, 11,112,238,220, 57,
+228,231,231, 67, 38,147, 65, 38,147,153,180, 32, 44,199,113, 36, 47, 47, 15, 58,157, 78,224, 26, 57,192,195,131, 40, 45, 57,243,
+195, 91,191,216, 96,105,169, 50,119,138, 62,251, 11,238,223,111, 60, 46,221,104, 52,254,219,165,107,219, 86, 11,137, 36, 86, 26,
+ 23,247,175,186,226,170, 37,156, 60,207,191,125,240,224, 65,139,162,162, 34,200,100, 50,124,242,201, 39,198, 75,151, 46,169, 57,
+142, 27, 16, 19, 19,243,240, 73,211,217, 20, 28, 28, 29, 79,191, 60,105,206,156,245, 51,134, 64,171,209,225,232,165, 68,252,158,
+144, 62, 1, 64, 4,165, 84,211,208, 49,145,145,145,121,129,129,129, 47, 47, 90,180,232,252,158, 61,123,204, 38, 77,154, 4,158,
+231,107,255, 42, 42, 42,240,199, 31,127,224,210,165, 75,136,137,185,158, 37,163,157,126,119, 49, 47,251,233,199, 51,166, 45,210,
+ 76, 8,113,245,242,242, 58, 25, 25, 25,233, 96,110,110,142,208,208, 80, 20, 23, 23, 99,254,252,249,181,206, 85,113,113,241,248,
+ 29, 59,118, 76,188,119,239,222,199,225,225,225,133,213, 47, 2, 28, 68,136, 16, 33, 66,196,127, 28, 77,106,144,127,195,145, 16,
+114,130, 82, 58, 18,192, 96, 0,242, 58,219, 32,132,156,168, 22,126,143,108, 47, 95,190,124,229,198,141, 27,111,214,108,215,236,
+179, 98,197,138,127,108,218,180,233,227,222,189,123, 31,186,114,229, 74,218, 95, 38,176, 0,132, 81, 74, 73, 51, 50, 6, 66, 81,
+ 20, 21,138,162,232,239,103, 82, 30, 23, 37,149, 37, 45, 62,185,167,167, 39, 18,147, 30, 19, 55,181,223, 77, 21, 88,232,219, 23,
+200,201, 1, 92, 93,171, 82,154,147, 3, 3,128,111, 87,172,128, 92, 46,175,237,138,170, 22, 38,205,210,233,245,122,146,159,159,
+ 79,117, 58, 93, 66,101,101, 37,215,192,197, 64,218, 57, 91,253,184,122,249,130, 86, 94,109,219,187, 70,158,252, 9,105,105,217,
+120,240,160,225,250, 81,169, 84,229, 70,163, 81, 85, 93,177,241,132, 97, 30,154,197,197,253, 12, 32,241, 73, 57, 9, 33,167, 39,
+ 77,154, 52, 50, 48, 48,144,116,238,220, 89,126,254,252,121,142,231,249, 71,196, 85, 75, 57,155,130,155,155,219,224, 23, 94,120,
+225,200,236,217,179, 49,102,248, 96, 76,236,223,149,102,229, 21,107, 1,156,111,106,145,230,106,145,117,195,207,207,111,226,248,
+241,227,191,106,211,166,141, 39, 0,120,123,123, 99,226,196,137,248,242,203, 47, 17, 26, 26,186, 23,192,238,152,152,152,184, 22,
+222,148,230,182,182,182,191,158, 63,127,222,193,220,220, 28,103,207,158, 69, 69, 69,197, 99,206,213,199, 31,127,172,188,119,239,
+222,150, 51,103,206,116, 6,192, 84, 47,211, 35, 66,132, 8, 17, 34,158, 13,152,160, 65,106,159,251, 39, 40,165, 35,235, 10,166,
+250, 66,171,230,123,205,126, 27, 55,110, 28, 89, 87,124, 1,192,166, 77,155, 62,174,179, 93,241, 87,100,170, 70, 96, 5, 17, 66,
+ 40,128, 32, 74,233,133, 39, 33, 50, 86,150, 61,209,140,165,114, 51,123,108,217,189,163,170,144, 36,143,198,101,153,236, 96,181,
+ 96,178, 84, 83, 28, 44,131,193, 32, 20, 21, 21,221,211,104, 52, 49, 73, 73, 73,143,137, 7,119,119,247,141,189,251,245,234,211,
+190, 71, 79,179,200,211, 71,112, 59,245, 62, 10, 10, 74, 0, 74,117, 13,241,217,217,217, 61,100,230,205, 83,153,231,228, 20, 51,
+130,144,221, 58, 33,225,213, 63,203, 25, 30, 30, 62, 45, 48, 48,208,247,202,149, 43,161, 86, 86, 86, 0, 64,235,138,171, 39,225,
+108, 64, 84,245,150, 72, 36,199, 24,134, 49, 27, 54,108, 24,222,122,235, 45,124,249,229,151, 28,149,153,141,219,113, 42,250,229,
+242, 74,253, 71,205,137,171, 26,196,196,196,132, 78,152, 48,161,107,124,124,188, 27,165,116,184,173,173,237, 22,163,209, 8, 65,
+ 16, 64, 41, 61,206,113, 92,170,191,191,255, 65, 71, 71,199,224,188,188,188,131, 49, 49, 49,139,154,185,201, 24,153, 76,182,247,
+220,185,115, 93,220,220,220, 16, 26, 26,138,138,138,138, 90,231,106,218,180,105,143, 56, 87, 87,174, 92, 41, 20,197,149, 8, 17,
+ 34, 68, 60,147, 48, 89,131,212,136,166,250, 34,171, 37,226, 12,128,118,249,242,229, 43, 9, 33, 39,170, 29, 46, 45, 0,245,211,
+206, 20, 83,157,224, 11,213,234, 49,236,209,156,152,222, 22, 25,244,165, 79,148,128,118, 3, 14,192,119,204, 5,164, 25,230,227,
+ 1, 51,183,190,147,100,154,192, 58,114,164,202,189,202,201,249,183,147, 85,237,102, 61,137,192, 42, 47, 47,191, 81, 88, 88,152,
+ 80, 82, 82,114, 21,128, 80,207,117,155,219,163, 71,143,105,187,246,238,183, 60,126,250,143,138,152,168,155,154, 7,121,197,168,
+ 48, 24, 13, 9, 25, 15,182, 55,196,231,228,228, 84, 68,129, 66,137,209,120, 78,126,227,198,207, 13, 56,121, 45,230,172,118,134,
+ 98, 1,156, 56,125,250,244,109,150,101,191,126, 26,156,117,197,149,189,189,253,175,251,247,239, 55, 59,124,248, 48,166, 79,159,
+142, 79, 63,253, 20,167, 79,159, 30,167, 86,171,207,149,233, 42,231, 82, 74, 31,152, 90,207, 95,206, 33, 46, 3, 29,126,118,149,
+ 72, 36,214,246,246,246,107, 39, 79,158, 12,142,227, 48,104,208, 32, 56, 58, 58, 30,146,201,100, 23,102,204,152, 49,122,243,230,
+205,230, 94, 94, 94,179,252,252,252, 92,154,161, 92,127,224,192,129, 17,222,222,222, 8, 15, 15, 71, 73, 73, 9, 92, 93, 93,241,
+230,155,111,202, 55,109,218,116,240,235,175,191,214,109,220,184, 81, 54,100,200,144, 45,103,206,156,241,169,168,168, 24, 42,138,
+ 43, 17, 34, 68,136,120,246,208,168, 6,105, 66,100, 61,225,121,106,142,147,110,220,184,241, 38,165,116,228,166, 77,155, 62, 6,
+ 96,246,151, 57, 88,213,202, 17, 0,130, 30,213, 87,229,166, 59, 88,186,166, 32,213, 53, 92, 0, 0, 32, 0, 73, 68, 65, 84, 5,
+214,219, 47,103,165, 8, 60,143, 47,151,178,144,155,217,163,221,128, 3,205,186, 82, 45,141,193,106, 64,173, 62,182,109,138,192,
+170,168,168,136,201,203,203,187,155,158,158,126,169,238, 36,162,158,158,158,163,156,157,157,215, 29, 56,112,192, 76,173, 86,195,
+163, 67, 55,171, 29, 63,255,171,210,217, 92,161,203, 44, 46,156,125, 61,171,252,104, 67,124, 74,165,242, 22,189,119, 47, 73,158,
+156,124,134, 0, 55,235, 9,161, 39,226,172, 65, 68, 68,196,180, 6, 4,219,159,226,116,115,115,235,237,224,224,240,235, 55,223,
+124, 99,174, 86,171, 33,147,201,160, 82,169,112,254,252,121,168,213,234,115, 45,189,200,182,207, 34,171,228, 2,222, 3, 15,166,
+175,103,118,229,171,239,125, 99,102,103,103,135,184,184, 56,116,233,210, 5,155, 55,111,150,167,164,164,116,238,212,169, 19, 82,
+ 83, 83,145,147,147,115, 43, 38, 38, 38,183,137,183,144,209,179,103,207,126,123,220,184,113,184,118,237, 26,114,114,114, 48,111,
+222, 60,253,155,111,190, 41,155, 58,117, 42, 41, 41, 41, 25,191,125,251,246,137,233,233,233,162,115, 37, 66,132, 8, 17,207, 56,
+ 26,211, 32, 77,224, 36,128, 23,235,187, 90,245,197, 87,141, 67, 85,119,187,254,254,213,255,215,253, 21,249,146, 84,159,140, 60,
+ 46,112, 32, 8,134,135,148,241,152, 68,132,156, 35, 20,124, 35,231,103, 89, 72,228, 42,104, 43,202, 4, 74, 31,117,123,234, 66,
+224,121,135,186,193,236, 44,203, 54, 26, 15,197,178, 44,172,173,173, 81, 86, 86, 6, 0,198,102,242,192, 27,199,141, 99,229, 47,
+189, 4,131,139, 11,168,193, 80,229, 98, 1,192,202,149,143,236, 40,147,201,106, 92,177, 38,187,181, 74, 75, 75,175,197,196,196,
+ 92,161,148,230, 1,192,192,129, 3,183,241, 60, 63,202,194,194,194,102,214,172, 89,134,130,130, 2, 28, 61,122, 20,223,127,255,
+189, 86, 99, 96, 99,139,245,220,204, 59,217,229,141,206,104, 95, 80, 80,240,187,231,173, 91,135,235,254,246,103, 57, 27,194,211,
+224,116,115,115,235,237,228,228, 84, 43,174, 20, 10, 5, 84, 42, 21,178,179,179, 33,145, 72, 90, 60, 73,231,193,249,196, 6, 20,
+239,204,121,123, 14,195, 48, 12,179,107,219, 63,205,108,204, 41,126,248,225, 7,132,132,132, 36,119,235,214,173,211,140, 25, 51,
+208,177, 99, 71, 36, 39, 39,227,139, 47,190, 80, 27, 12,134, 87,154,188,104, 37,146,105,235,214,173,163,106,181,154,220,189,123,
+183,214,185,218,184,113, 99,109,204, 85, 90, 90,154, 24,115, 37, 66,132, 8, 17,255, 29, 14,150, 41,241, 87, 5,213,226,233, 65,
+ 3,219,108, 29, 97, 85,127, 59,175,222, 54, 0,232,235,253, 63,254, 47, 19, 88, 13,102,152,224,155, 9, 99,131, 23,127,248,238,
+ 28,231,206, 29,151, 43,105,222, 41,208,146, 24,138,154,144, 27,194, 64,174,114, 0, 36, 10, 26,157, 84, 80,254, 71,130,182,128,
+ 18,124, 99,234,137, 59,119,238,140,220,220, 92, 20, 22, 22,214,254,198, 48, 12,236,236,236,160, 84, 42, 17, 29, 29,141,240,240,
+112, 35,128,117,205, 84,204,166,169, 83,167,174,152, 63,127, 62,211,115,250,116, 24, 46, 93,122,100,120, 24, 33, 4, 74,165, 18,
+102,102,102,200,206,206, 70, 74, 74,138, 64, 41,221,212, 20,231,157, 59,119,194, 41,165,249, 0, 16, 20, 20, 52,201,206,206,110,
+194,244,233,211,205,174, 93,187,134,245,235,215, 75, 66, 67, 67, 13, 81, 81, 81,156, 32, 8, 43,178,178,212,223, 53,151,215,164,
+164,164,168,186,219, 79,131,179, 62,158, 6,167,187,187,123, 47, 55, 55,183, 95,191,250,234, 43,243,220,220, 92, 40, 20, 10, 88,
+ 90, 90, 34, 35, 35, 3,235,214,173,211,112, 28,247,210,211,184,232,116, 58, 29, 14, 31, 62,156,211,166, 77,155,158,215,175, 95,
+ 31,180,108,217,178,109,173, 91,183,118,203,200,200,184,199,243,252,139, 81, 81, 81,247,155, 58,222,198,198, 38,208,209,209,145,
+ 68, 68, 68, 96,222,188,121,250,133, 11, 23,138,206,149, 8, 17, 34, 68,252,189,113,173,153,237,103, 14,141, 46,246,156,148, 70,
+191,191,147,146, 57,122,210,236, 85, 7,103,190,185, 34, 59,181,192,190,146, 56,143, 33, 68,225, 6,133,149, 43,172, 92,187, 33,
+ 61, 95,162,221,122, 88,157,117, 34, 82,251,179,182, 28, 99,147,210,232,247,245,108,191,110,117, 92,169,252, 45,187,119, 96,203,
+238, 29,224, 4,169,254,141, 55,222, 64, 65, 65, 1,210, 46, 79, 70,236,175, 3,209, 70,182, 29, 46,116, 39,242,243,243,241,237,
+183,223,210,208,208,208, 35, 70,163,209, 71,173, 86,127,211, 24, 39, 0,196,198,198,126,156,157,157,221,123,229,202,149,161,243,
+203,202,112,107,251,118,200,167, 78, 5,211,189, 59,204,205,205,225,224,224, 0,141, 70,131, 11, 23, 46,224,250,245,235,161,149,
+149,149,189, 99, 99, 99, 63,110,138,179, 70, 92,245,237,219, 87, 85, 92, 92,252,249,212,169, 83,205, 52, 26, 13, 10, 10, 10, 80,
+ 80, 80,128,200,200,200,243,122,189, 62, 32, 43, 43,171, 81,209, 82,151,147, 82,154, 89,243,253,105,113,214,197,211,226, 52, 55,
+ 55, 95,116,244,232, 81,115,134, 97,160, 80, 40, 96,109,109,141,204,204, 76,172, 93,187, 86,163,213,106, 95, 82,171,213, 38, 77,
+208, 89,151,243,245,237,180, 24, 4,159,239,252,106,167,176,253,139, 29,148,218, 13,132,153,181, 59,172,173,173,237,126,254,249,
+103, 33, 62, 62,254,156,155,155, 91,167,212,212,212,110,149,149,149, 1, 87,175, 94,189,223, 28,103, 65, 65,193,197,123,247,238,
+193,194,194, 2, 11, 23, 46,148,127,252,241,199, 7,191,254,250,107,221,199, 31,127,220,162,152,171,198,202,243,207, 64,228, 20,
+ 57, 69, 78,145, 83,228, 20,209,164,131, 5, 0, 55, 50,104, 58,128,183,123,180, 35,222,175,205,223,188,168,127,207,182,189,222,
+124, 45,192,182, 84, 40,161, 71,143,221, 46, 76,203, 44,191, 38, 97,241,229,205, 52,218,172,189,246,246,231,220,115,117,183,183,
+122,120, 4, 76,159, 62,125,253,210, 9,121,125,234,118, 29,238,255,105,255, 37, 66,200,170,156,156, 28,147,135,236,199,196,196,
+220, 4,240,146,175,175,111,191, 37, 75,150,172,123,217,211,211,127, 82, 80, 16,164, 82, 41,162,162,162,240,240,225,195,104, 0,
+ 31,196,198,198, 94,110, 73,225,148,150,150,126,216,177, 99, 71, 89, 82, 82, 18,238,220,185,131,148,148, 20,240, 60,127, 55, 43,
+ 43,107,220,147, 22,248,179,204,169,211,233, 62, 91,191,126,125,240,154, 53,107, 20,150,150,150,136,139,139,195,154, 53,107, 52,
+ 58,157,206,100,113,213, 16,230,255,147,110,248,114, 14,249, 62, 60,173,205,144, 46,238,189,183, 27,141, 70, 56, 57, 57,201,123,
+245,234,229, 10, 64, 29, 18, 18,194, 3, 72,107, 1,229, 7,222,222,222, 29,215,175, 95,223,110,218,180,105, 40, 46, 46, 22,157,
+ 43, 17, 34, 68,136, 16,241,223, 35,176,106,112,253, 14,141, 7, 48,181,123, 91, 50,232, 82,212,221, 89, 85,242, 21,187, 18,211,
+105,216,147,158, 56, 43, 43, 43, 10,192,144, 45,139,201, 35,243, 79,228,228,228, 12,127, 82,206,106, 1, 53,208,219,219,123,244,
+ 81,150,125, 23,105,105,224,121,254,179,248,248,248, 99, 45,225,233,213,171, 87,235,178,178,178,127, 26,141,198, 30, 60,207,203,
+ 47, 92,184, 0,157, 78,135,196,196, 68,173, 32, 8, 71,159, 36,109,255, 13,156,153,153,153, 49,110,110,110, 35, 9, 33, 39,150,
+ 45, 91,166, 88,187,118,237,159, 22, 87, 53, 88,180,147,230,238,247,243, 11, 99, 83, 82,120,163,209,200,114, 28, 7,158,231,101,
+ 79,194, 69, 41,189, 67, 8,233,185,120,241,226, 15,222,121,231,157, 69,155, 54,109,146,137, 49, 87, 34, 68,136, 16, 33,226,191,
+ 78, 96,213, 32,225, 46,253, 3,192, 31, 79, 51, 1,213, 93,135,142, 53,223,159, 6,103,181,160, 58,246,164,199,151,148,148,124,
+ 84, 88, 88,216,179,180,180,148, 75, 75, 75,211, 18, 66,120,134, 97,180,130, 32,108,228,121,254,187,191, 51,167, 90,173,142,112,
+117,117, 29,114,229,202,149,133, 21, 21, 21, 59,213,106,245,213,167, 85,215, 49, 49, 49,153,126,126,126,239,207,154, 53,107, 34,
+199,113,255,138,142,142,190,247,164, 92,148, 82, 61,128,247, 9, 33,191, 38, 36, 36,252,112,229,202,149, 92, 81, 92,137, 16, 33,
+ 66,132,136,255, 74,129,245, 87,160,126,215,225,179,128,228,228,228,105, 0,166,253, 47,114, 2, 64, 78, 78, 78,236, 95,193, 91,
+ 45,178,190, 6,240,245,211,226,163,148,198, 16, 66,186,160,106,148,136, 40,174, 68,136, 16, 33, 66,132, 40,176, 68,136,120, 74,
+ 34,139, 66, 92, 91, 80,132, 8, 17, 34, 68, 60, 67, 32, 0,186, 53,210,104,153,188, 82,246,147,140, 38,104,142, 95,228, 20, 57,
+ 69, 78,145, 83,228, 20, 57, 69,206,191, 31,103,115,220, 45,209, 31,207,180,192,106,201, 58,126, 45, 38, 39,164,219,211, 46, 40,
+145, 83,228, 20, 57, 69, 78,145, 83,228, 20, 57,255,126,156,127, 55, 48, 98, 17,136, 16, 33, 66,132, 8, 17, 34, 68, 60, 93,180,
+ 56, 6, 43, 48, 48,176, 29, 0, 68, 70, 70,222,121, 22, 50,224,227,227,115,161,109,219,182,173,110,223,190,109, 36,132,160,238,
+ 31, 0,200,229,242, 43, 87,174, 92,121, 67,172,234,255, 44, 44, 44, 44, 52, 44,203, 18,134, 97,192,178, 44,234,127, 54,244, 27,
+ 33,196, 41, 49, 49, 81,211, 24,167,155,223, 4, 79, 35,103, 92, 67,136,240, 29,229,153,153,132,173,249,164,255,164, 60,153,193,
+200, 12, 95, 10, 6,217, 34, 41, 85,124,164,190,121, 40, 75,172,133,134,209,173, 91,183,243, 61,123,246,236, 24, 23, 23,103,160,
+148,214,222, 63, 12,195,128, 16, 2, 65, 16,114,162,163,163,251,252,221,203,193,213,213,181, 31,128,205,213,131, 38,234, 34,133,
+ 16,242, 78,118,118,118,152,120,181,136, 16, 33,226,169, 9,172,158, 61,123,182,231,121,190, 63, 33,164, 31,165,180, 95,231,206,
+157,157, 42, 42, 42,224,231,231,151, 71, 8,185, 76, 41,189,204,178,236,165,107,215,174,221,110,142,171, 79,159, 62,209,122,189,
+190,115,139, 18, 40,145,148, 41,149,202,118, 97, 97, 97, 13, 54,180,206,206,206, 94,251,247,239,183, 75, 72, 72,128,133,133,197,
+ 35,127, 18,137, 4,189,122,245, 10,120, 86, 11,191,119,239,222, 6,158,231,165, 13,253,143,101, 89, 99, 68, 68,132,172, 25,177,
+123,143,227, 56,199,150,156, 83, 38,147,229, 71, 68, 68,152, 52,114,179,111,223,190, 42,142,227, 22,179, 44, 59, 80, 16,132, 46,
+213,233, 74,226, 56,238,130, 68, 34,249, 34, 60, 60,220,228,213,192, 89,150, 37, 5, 5, 5, 56,116,232, 16,186,249, 6,130, 82,
+192,187,107,251, 90, 33, 28, 25,155, 4,158,231, 17, 30,118, 26, 75,151, 46,133,175,175, 47, 52, 26, 13,219, 20,167,129, 19, 86,
+125,176, 96,114,208,134,173, 7,253,222, 95,248,186,106,195,214,131,190,239, 47,124,221,114,195,214,131, 62,239, 47,156,104,185,
+126,235,126,223, 85, 11, 39, 89,173,255,230,128, 30,192,252, 39,169,163,153, 93,186, 24, 25,142,107,240, 62, 17, 36, 18,238,187,
+164, 36,233,127,251, 67,128, 97, 24,247,157, 59,119, 90,159, 61,123, 22,102,102,102,181,247,143, 74,165,130,133,133, 5, 94,124,
+241, 69,254,105,157,203,207,207,239, 0,128, 49,213,155, 97, 49, 49, 49, 47, 62, 41, 23, 33,196, 66, 34,145, 44,148,203,229,253,
+ 57,142,235, 84,125,125, 39,235,116,186, 75, 28,199,109,165,148,106, 90,200,247,233,181,107,215, 58, 91, 90, 90,194, 96, 48,212,
+ 46, 12,207,178,108,199,192,192,192, 47, 0,244, 16,155, 12, 17, 34, 68,252,105,129,229,231,231,119, 20, 64,191,206,157, 59,155,
+ 13, 25, 50, 4,190,190,190,104,221,186, 53,148, 74, 37, 0,160,176,176,208, 41, 49, 49,113, 92, 92, 92,220,184,136,136, 8,248,
+249,249,105, 9, 33, 17,209,209,209,163, 27,227, 20, 4,193,227,244,233,211,112,112,112, 48, 41,113,130, 32, 96,196,136, 17,210,
+146,146, 18,115, 0, 13, 62, 44,115,115,115,133, 15, 63,252,176, 36, 60, 60,220,192, 48, 12, 40,165,132, 84,181,218, 4, 0, 56,
+142, 43,252, 79, 23,114,191,126,253,146, 0,184,213,228,137, 16,162, 14, 15, 15,239,194,243,188,244,218,181,107,141, 9,219,102,
+ 27,110,142,227, 28, 47, 95,190, 92, 91, 39,205,129,231,121,244,236,217,211, 36, 65,230,227,227, 51, 64,161, 80,252, 48,111,222,
+ 60,235, 62,125,250, 72, 60, 60, 60, 64, 8, 65,110,110,110,207, 43, 87,174,248,110,223,190,125,134,143,143,207,148,184,184,184,
+139, 38, 10, 44,236,219,183, 15,235,215,175,199,146,247, 63,197,155,211,199,131, 16, 2,133, 66,129,146,146, 18, 4,250,118,193,
+142,125,191,226,208,161, 67,208,106,181, 96, 89, 22, 94, 94, 94, 77,137, 83, 55,149,196, 54, 96,225,204,151,204, 63,219,190,207,
+124,225,204,151,240,249,142, 31,234,124,142,193,103, 59,246, 89,188, 53,115, 12,182,238,220, 19,216,187,119,111,183,136,136, 8,
+181, 41,117, 4, 0,148, 82,117,120,120,120, 23,134,227, 36,187, 82, 83,171,126,252,246, 91,224,193, 3,208,213,171, 1, 0,115,
+ 58,118,108,145, 3,220,189,123,247,203, 44,203,186,155, 80, 79,217, 9, 9, 9,253,254,132,240, 24, 12, 96,105,245,230,102, 74,
+233,185,102,238,179,236,185,115,231, 90,196,198,198, 54,230, 96,229,253, 9, 65,101, 79, 8,217, 10,192,140,101,217,119, 0, 12,
+ 15, 13, 13, 5,195, 48, 24, 58,116,104,144,159,159, 95, 71, 0, 27,205,205,205,169, 94,175,159, 23, 25, 25,153,103, 98, 30,251,
+ 89, 90, 90,254,243,192,129, 3, 54,189,123,247,102, 50, 51, 51,209,173, 91, 55, 20, 20, 20,248,133,133,133,249,204,153, 51,103,
+ 42, 33,100, 22,165,180, 37,171, 55,116,176,176,176,160, 83,167, 78, 37,117, 23,162,223,189,123, 55,124,181,218,182, 51, 91,183,
+ 46,172, 52, 24,202, 46,178,236, 42, 66,200,133,204,204,204, 28,177, 9, 17, 33, 66,196,147, 56, 88, 67, 47, 92,184, 0,163,209,
+ 8, 75, 75, 75,176,236,163,102,130,157,157, 29, 6, 12, 24,128,192,192, 64, 12, 30, 60, 24,201,201,201,102,159,124,242,201,243,
+205,157,208,220,220, 28, 17, 17, 17,224, 56, 14, 49, 49, 49, 40, 43, 43,195,232,209,163, 33,149, 74, 33,149, 74, 33,145, 72,106,
+ 63,157,157,157,161, 84, 42, 73, 73, 73, 73,163,124,214,214,214,109, 79,158, 60,201, 40, 20, 10,170, 82,169,232,133, 11, 23, 40,
+ 0, 90,213, 70, 62, 89, 4,127, 64, 64,128,179, 68, 34, 89,207,243,252, 88,158,231,229, 77,136, 6,163, 76, 38, 59,174,211,233,
+222,143,137,137,201,108,130,210,237,242,229,203, 86,181, 5, 59,116, 40,233,221,187,119, 73, 77,153,250,249,249, 61,178,115, 76,
+ 76,140,201,105, 85, 42,149, 8, 11, 11,131, 68, 34,129,109,255,254, 0, 0, 99,124, 60,164, 82, 41,208,181, 43, 0, 64,149,145,
+ 1,169, 84, 10, 23, 23, 23,147, 56,189,189,189, 7,183,106,213,234,224, 87, 95,125,101,198,178, 44, 82, 83, 83, 65, 8, 1,203,
+178,200,203,203, 67,191,126,253, 36,221,186,117,179, 95,177, 98,197, 97,111,111,239,215,227,227,227,207,153,224,146, 96,234,212,
+169,248,236,179,207,176,112,198,120,212,172,119,168,215,235,107,247,153, 55,117, 12,246,110,223,136, 15, 62,248, 0,167, 78,157,
+106,142,111, 67,231, 14,237,220,247,254,116, 6,125,123,245,196,222,159, 78,163, 79,175, 64,236, 13, 57,131,190,189, 2,241, 67,
+200, 25,244,239,221, 11, 63,132,156, 65,183,206, 29, 60, 30,222, 47,217,128,166,231,246,122,164,142,134, 13, 27, 70,122,247,238,
+ 93,210,141, 97,106, 4, 23,200,188,170, 37,157, 80, 45,176, 90, 10,150,101,221, 99, 99, 99,155, 21,184,190,190,190,127,246,190,
+ 94, 74, 41,237, 87, 45, 68, 0,160,201,250,185,113,227,198,243, 0,240,242,203, 47,159,239,214,173, 91,199, 91,183,110, 25,106,
+142,173,254,115,157, 56,113,226,189, 26,209, 69, 41,205,249,241,199, 31, 77,234, 50, 36,132,108, 62,126,252,248, 40,131,193,128,
+233,211,167,199,180,105,211, 70, 98,109,109,141,221,187,119,195,214,214, 22,122,189,254,218,231,159,127, 46,185,127,255, 62,190,
+249,230,155,157,117,220,173,166, 56, 7,245,239,223,127,223,201,147, 39, 21, 18,137, 4, 37, 37, 37,184,120,241, 34,108,108,108,
+ 96,102,102,134,113,227,198, 49, 3, 6, 12,176,123,254,249,231, 15, 16, 66,166, 81, 74, 77,158, 28, 89,171,213,210, 21, 43, 86,
+192,220,220,252, 17, 55, 92, 9,144,117, 87,175, 42, 54, 6, 5, 41, 86, 45, 90,180,244,219,111,191,237,229,225,225,177, 41, 43,
+ 43, 75, 45, 54, 35, 34, 68,136,104,169,192,130,133,133, 5,162,162,162, 64, 8,129,165,165, 37,172,172,172, 96,109,109,141,210,
+210, 82, 36, 38, 38,226,214,173, 91, 72, 79, 79, 7,195, 48,104,219,182, 45,106, 92,163, 58, 46,192,141, 6, 30,142, 96, 89, 22,
+247,238,221, 67,110,110, 46, 24,134,193,197,139, 23, 49,124,248,240, 71,196,149, 84,218,176,129, 83,159, 51, 44, 44,140,123,103,
+170,203,121,131, 94,227,192,113,250, 43, 97,148,206,243,245,245,189,224,228,228,228,225,237,237,205,215,116, 65, 53, 21,151, 85,
+159,147,101,217,141,243,231,207, 31, 55, 97,194, 4, 70, 34,145, 60,226, 0,233,245,122,232,245,122, 24,141, 70,104,181, 90,233,
+225,195,135, 95, 58,113,226,132, 57,128,151, 27, 75,167, 32, 8,143,228, 97,253,250,245,150, 28,199,225,171,175,190, 2, 0, 68,
+ 71, 71, 63,230,220,153,146,247,218, 74,148, 72, 80, 55,157, 53,101,200,213,219, 54,133, 51, 48, 48,208, 82, 46,151,127,191,101,
+203, 22,179,188,188, 60, 36, 36, 36,160, 71,143, 30, 88,181,106, 21, 52, 26, 13, 54,111,222,140, 59,119,238,192,201,201, 9, 43,
+ 87,174, 52,123,231,157,119,190, 15, 12, 12,236, 18, 25, 25, 89,214, 84, 58, 25,134,193,119,223,125, 7,142,227,192, 84,139,150,
+202,202, 74, 40, 20,138,250,233,193,234,213,171,107,247,105,140,211, 96, 48, 12, 91,177,104, 22,190,250,103, 8,186,182,115,198,
+137,208,171,232,217,173, 53, 78,157,191,134, 94,221,219,224,244,133,104,244,246,110,135,243, 87,111,226,237,249,147,240,238, 91,
+ 23,135, 53,149,247,250,101,190,118,237, 90, 75,158,231,113,106,217, 50,224,155,111, 64, 22, 46, 4,173,222,135, 48, 12,224,238,
+ 14,152,153,153, 92, 71,117,113,235,214, 45, 84, 86, 86, 62,246,187, 66,161, 64,231,206,157, 91,204, 73, 8,233,238,228,228,244,
+109,199,142, 29,187, 1,192,128, 1, 3,154,189,241, 27,185, 55,221,223,127,255,125,235,253,251,247, 67,161, 80,192,204,204, 12,
+230,230,230, 48, 55, 55,127,228,251,170, 85,171,248, 22, 92,159,242,228,228,100, 88, 90, 90, 98,215,174, 93, 18, 59, 59, 59,196,
+196,196, 64, 34,145, 96,242,228,201,232,222,189,187,196,204,204, 12, 23, 46, 92, 64,121,121,121,179,156,132, 16,149,133,133,197,
+183,199,143, 31, 87,240, 60,143,130,130, 2, 0,192,200,145, 35,193,178, 44,110,221,186,133,143, 62,250, 8, 63,255,252, 51,126,
+249,229, 23,165,159,159,223,183,132, 16, 95, 74,105,185, 9,229, 73, 43, 43, 43,169, 82,169,132, 82,169,132, 66,161,128, 66,161,
+128, 76, 38,131,142, 82,124,224,239,175,151,169, 84,124,143, 30, 61,218, 44, 88,176,128, 89,179,102,205, 32, 0, 63,154, 90,239,
+ 45,133,200, 41,114,254,175,113, 54,231,125, 0,168,251,130,170, 7, 80, 99,128, 20, 84,235, 15,251,122,191, 3, 64,205, 10, 49,
+142,141,108, 23, 0, 72, 4,208,165,250, 55, 30,192, 53, 0, 69, 79, 69, 96, 17, 66,104,157, 66, 35, 13, 20, 36, 74, 75, 75, 81,
+ 90, 90,138,204,204, 76,236,216,177,163,182,209,150, 72, 36, 96, 24,166, 54, 94,193, 20, 72,165, 82,100,102,102,194,219,219, 27,
+ 78, 78, 78,216,179,103, 15, 70,142, 28, 89,203, 87,243, 87, 87, 20, 53,133, 62,131, 38,118,126,169, 75,138,229,252, 77,161, 20,
+168,138,203,250,245,215, 95,237, 82, 83, 83,161, 84, 42, 97,102,102, 6, 51, 51, 51, 40,149, 74, 72,165,210,102,227,178, 4, 65,
+ 24, 53,126,252,120, 38, 52, 52, 20, 28,199, 65, 34,145, 64, 38,147, 65, 46,151,131,101, 89,200,100,178,218,191, 81,163, 70, 49,
+ 71,142, 28,121, 62, 40, 40, 72, 18, 22, 22,198, 53,114, 33, 34, 58, 58, 26,145,145,145,224,121, 30, 28,199,129,227, 56,104,181,
+ 90, 0,128,191,191,255, 35,251, 95,189,218,178,213,105,234, 58, 87, 18,137, 4,164,107, 87,112,213,206,149, 68, 34, 65,145,171,
+ 43, 0,192,193, 52, 67,111,209,244,233,211, 45, 21, 10, 5,110,220,184, 1,133, 66, 1,141, 70,131, 49, 99,198,160,188,188, 28,
+ 28,199, 65,161, 80,160,178,178, 18,206,206,206, 24, 60,120,176, 69,104,104,232, 34, 0,107,155,113,111, 48,115,230, 76,108,219,
+182, 13, 95,253,243, 39,188, 61,235,149,199,246,217,190,183,106,249,196, 53,107,214, 32, 44,172,233,120, 98, 65, 16,216, 62,254,
+157, 81, 90, 16, 0,169, 84,138,190,190,237,193,178, 44,250,248,117,128, 68, 34, 65,191,128,142, 96, 89, 22, 3, 3,187,160, 93,
+187,118, 16, 4,129,109,230, 97,209, 96, 29,233,245,122, 32,167,129,158,160,220, 92,160, 77,155, 39,121, 40, 97,217,178,101, 37,
+106,181,218,240,152,133,230,230, 38, 59,114,228,136,117, 75,140, 87, 66, 72,143,206,157, 59,159, 57,127,254,188,202,217,217, 25,
+ 28,199,193,104, 52, 66,163,209,224,149, 87, 94, 1,128,163, 45, 72, 91,246,250,245,235, 45, 26,112,176, 30,233, 54,164,148,154,
+220,101, 40,145, 72,150, 47, 91,182,108,248,152, 49, 99, 36,150,150,150,144, 74,165,144,203,229,144,203,229,144,201,100,184,119,
+239, 30,140, 70, 35, 66, 66, 66, 40,203,178,239,154,192,247,230, 15, 63,252, 96, 37,151,203,145,147,147, 3, 66, 8, 40,165,144,
+201,100, 72, 75, 75,195,151, 95,126,137,233,211,167, 35, 35, 35, 3,174,174,174, 88,178,100,137,106,211,166, 77,111, 2,216,104,
+ 74,131,161,215,235,125,205,204,204,160, 80, 40, 80, 35,180, 0, 32,214,220, 60, 49, 45, 45,173,167,139,139, 75,231, 86, 23, 47,
+238, 12, 10, 10,234,102,111,111, 31, 64, 8,217, 79,255,202,185,110, 68,136,248, 31, 64,115, 26,164, 70, 16, 17, 66, 78,212,217,
+111,100,205,246,242,229,203, 87,110,220,184,241, 38, 33,228, 68,221,223,107,246,171, 62,199,137,134,182,171,143,181, 95,177, 98,
+ 69,183, 77,155, 54,125,220,187,119,239, 67, 87,174, 92, 73,123,106, 2,171, 58,110,137, 54,145,177,199, 92,168,250, 48, 69, 96,
+213, 60,164, 43, 43, 43, 81, 80, 80,128,161, 67,135,194,204,204, 12, 12,195, 32, 51, 51, 19, 29, 58, 84, 53,142,241,241,241,248,
+240,195, 15,209,181,107, 87, 24, 12,134,102,211,116,230,196, 46,237,149,115,188, 86, 16,170, 30,252, 15, 30, 60,160, 27, 55,110,
+ 44, 15, 13, 13,213,255,251,212,181, 52,164,185,184, 44, 74,169, 68, 34,145,192,104, 52, 62, 50,202,141, 16,130, 65,131, 6,225,
+210,165, 75,181,191, 85, 59, 48, 76,117, 89, 54, 90, 8,213,142,215, 35,141,119, 13,106, 28, 44, 74, 41,116, 58, 29,140, 70,227,
+147, 85,102,181,243,199,213,219,110, 9, 24,134, 9,234,223,191,191, 36, 37, 37,165,182, 33, 52, 24, 12, 24, 56,112, 32, 24,134,
+ 65, 70, 70, 70,237,239,148, 82,248,248,248,200, 46, 93,186, 20,212,156,192, 98, 24, 6, 59,118,236,168,205,219, 55,223, 31,193,
+155,211, 95,174,117,114,190,249,254, 72,237,126,239,191,255,254, 99, 14, 86, 99,144,201,100,181,117,193,178, 44, 36, 18, 73,237,
+103,205,119, 83,219,191,198,234,136,110,216, 0,108,216, 80,229, 92, 1,168,208,104,170,196,113,223,190, 45, 22, 87,122,189, 30,
+106,181,218, 16, 31, 31,255,216, 64, 3,111,111,239,123,122,189,222,228,244, 18, 66,156,106,196, 21,165, 20, 47,190,248, 34, 22,
+ 45, 90,132,128,128, 0,148,149,149, 97,233,210,165, 40, 46, 46,254,162,123,247,238,159,220,184,113, 99, 21,165,116,123, 83,124,
+ 71,142, 28,121,172,139,191, 75,151, 46,231,123,245,234,213, 49, 54, 54,182,174,232,114, 13, 8, 8,184, 71, 41,109,114,116, 97,
+ 77, 64,123,247,238,221, 49,103,206, 28, 28, 62,124, 24,123,246,236, 65, 77,124,211,216,177, 99,241,210, 75, 47, 33, 63, 63, 31,
+206,206,206, 36, 59, 59,251,186,159,159, 95,147,129,239,114,185,124, 64,159, 62,125,152,178,178,178,218,231,144, 84, 42, 69, 90,
+ 90, 26, 54,111,222,140,137, 19, 39,162, 93,187,118,224,121, 30, 26,141, 6,131, 6, 13,146,108,221,186,117,128, 41, 2, 75, 34,
+145,188, 27, 28, 28,252, 49,128,174,117,159,133,132,144, 91,132,144, 85, 85,186, 58,247,214,168, 81,163,238, 5, 7, 7,251,180,
+105,211,198, 33, 33, 33,129,133,184,138,128, 8, 17,127,214, 13, 51, 89,131,212, 8,164,250, 66,107,227,198,141, 35,235,255, 86,
+ 87, 76, 53,244,189,238,177,155, 54,109,250,184, 14,119,197,211,200,215, 83, 91, 42,199, 84, 81,160,215,235, 17, 27, 27,139,246,
+237,219,195,204,204, 12, 18,137, 4,190,190,190,136,141,141, 69,151, 46, 93, 32, 8, 2, 86,174, 92,137,213,171, 87, 35, 36, 36,
+ 4,137,137,137, 18,103,103,231, 38, 57,119, 30, 46,123,196, 74,176,180,180,108, 19, 18, 18,242,167,226,178, 8, 33,181, 13,244,
+232,209,163,241,219,111,191, 65, 42,149,214,118,113,250,249,249,225,250,245,235, 38, 9, 1, 74,105,109,227, 93, 94, 94, 14,189,
+ 94, 15,142,227,224,232,232,136, 55,222,120, 3, 28,199,129,231,249,218,134,157,231,121,176, 44,139,158, 61,123, 82,134, 97,140,
+ 87,175, 94,109,114, 52,161, 33, 46,174, 42,109,255,248, 7, 56, 0, 22,247,239, 67, 42,149,162,216,173, 42,102,187, 85,121,121,
+163, 93,132,245,193,243,124, 23,119,119,119,164,164,164, 64,161, 80, 64, 46,151,163, 85,171, 86, 88,184,112, 33, 42, 42, 42,240,
+221,119,223,161,184,184, 24,114,185, 28, 82,169, 20,237,218,181,131, 94,175,239,210, 28, 47,203,178,152, 59,119, 46,190,255,254,
+123,236,216, 92,213, 5,248,237,150,170,207,186,211, 51, 48, 12,131, 13, 27, 54, 96,208,160, 65, 38,187,161, 75,151, 46, 53,107,
+236,255,135, 14, 29,210,154, 82,229,117,235,168,180,180, 20,122,189, 30, 60,207, 67,229,233,137,105,211,166, 85,213,207,171,175,
+130,231,121, 8, 83,167, 86,137, 4,115,115,147,235,168,174,192,106, 44, 61,148,210, 6,187, 14,155,192,208,229,203,151,171, 4,
+ 65,192,160, 65,131, 48,125,250,116,248,251,251, 99,235,214,173, 8, 15, 15,199, 63,255,249, 79, 28, 56,112, 0, 28,199,201,134,
+ 13, 27,182, 8,192,246,150,222,215, 44,203,186,239,220,185,211,250,151, 95,126,129, 74,165,130,141,141, 13,172,172,172, 96, 99,
+ 99,131,113,227,198, 53, 55,186,112,120,104,104, 40,108,109,109, 17, 29, 29, 13,185,188,202,181, 87,169, 84,118, 97, 97, 97,149,
+219,182,109, 43, 53, 51, 51,147,200,229,114,124,248,225,135,144,203,229,152, 57,115,102, 80, 80, 80,144, 34, 44, 44,172,193,130,
+224, 56,174,147,173,173, 45,114,115,115,107, 5,185, 74,165,194,135, 31,124,128, 41, 83,167,214,138, 43,185, 92,142,149, 43, 87,
+ 98,200,144, 33,168,172,172,236,100, 74, 94, 51, 51, 51, 99, 0, 12,105,110, 63, 65, 16, 72,117,125, 81, 0,130,216, 60,138, 16,
+241,255,234,118,157,168, 47,178,254, 12,215,242,229,203, 87, 2,160,203,151, 47, 95, 89,179,189,113,227, 70, 45,128, 63, 29, 95,
+249,212, 4,150, 41, 14, 86,255,254,253,149,219,182,109,131,139,139, 11,124,125,125,107, 29, 22, 63, 63, 63,108,221,186, 21,211,
+167, 79,199,169, 83,167,208,165, 75, 23, 12, 31, 62, 28, 3, 6, 12, 64,247,238,221,155,229,125,103,186,251,101,174,178,204,198,
+160,175,140,218,126,196, 48,189,180,180,244, 82,187,118,237, 92, 51, 50, 50,184,178,178,178,218,160, 97, 66, 8, 2, 2, 2, 32,
+145, 72,174, 69, 68, 68, 76, 52,197, 17, 26, 63,126, 60,126,249,229, 23,140, 29, 59, 22,103,207,158, 5, 0, 4, 4, 4, 32, 41,
+ 41, 9,230,230,230, 38, 59, 68, 53,141,119, 89, 89, 25,182,110,221,106,210, 49, 6,131, 1,193,193,193,205,158,160,166,187,150,
+175,183, 93, 87,220,152, 42,176,106,202, 73, 38,147,129, 97,152,218,174,156,242,242,114,148,148,148,212,118,149,214,252,153,218,
+ 53,204,178, 44,182,110,221, 10,163,209,136,121, 75,215,128,101, 37,152, 55,245, 37,176,108,149, 64,221,177,239, 87,240, 60,143,
+159,246,124,137,229,203,151,155,212, 53, 92,195,187,109,219, 54, 45,195, 48,143,185, 87, 12,195,180,200,193,171, 91, 71,219,182,
+109, 51,233,152,162,162, 34,140, 25, 51,198,228,147,212, 13,234,111,169, 0,107, 0,199,222,123,239,189, 25, 6,131,161,115,207,
+158, 61,205,102,207,158,141,204,204, 76,108,217,178, 69, 87, 84, 84,180,125,200,144, 33, 51, 84, 42,149,181, 70,163,209,164,167,
+167,127,254, 36,247,181, 32, 8,217,115,230,204,177,168,153, 35,171,102,100, 33,203,178, 38,141, 46,228,121, 30,187,118,237,170,
+237, 26,108,168,254,234, 94, 83,166,136,212,164,164, 36, 92,186,116, 9, 35, 70,140, 64, 69, 69, 5,140,122, 61, 22, 93,191,142,
+174,147, 38, 65, 47,147, 65, 16, 4, 40, 20, 10,108,222,188,249, 47,123,198,215, 17, 88, 34, 68,136,248,255,117,187, 70, 62, 77,
+174, 26, 7,107,227,198,141, 55, 55,110,220,248,152, 27,246,151, 10, 44,150,101, 81,119,200,114, 67,141,177,169, 49, 88,151, 47,
+ 95,214,157, 63,127, 94,149,149,149, 85,235, 16, 73, 36, 18,180,109,219, 22,132, 16,156, 58,117, 10,251,247,239,199,170, 85,171,
+ 32,145, 72, 96,101,101, 5, 31, 31, 31, 99, 78, 78,211,163,161,251, 12,120,181,237,255,177,119,222,225, 81, 84,251,255,127,159,
+153,217,158, 94, 73,150,132, 64, 8, 53,148, 84, 18,144, 18,145,142, 72, 17, 68, 68, 69, 65, 44,148, 43, 32, 2,126,239,189,128,
+138, 1, 1, 17, 68,154,168,168,160, 20,233, 8, 2,210, 33, 9, 73, 32,212,208, 18, 66, 72,239,109,179,117,102,206,239,143,100,
+115, 3,146,100, 3,168,252,116, 94,207,179,207,238,236,206,190,231,204,153,153, 51,239,249,156, 86,221, 6, 75, 0, 0, 47, 47,
+175,166, 91,183,110,173,175, 13, 86,131,227,217,152, 76, 38,200,100, 50,236,221,187, 23,253,250,245,195,177, 99,199,160,174,110,
+212,124,229,202, 21, 4, 5, 5,225,198,141, 27, 54,221,192,107, 71, 71, 12, 6, 3, 0, 32, 37, 37,197,214, 19,160,225,210,190,
+ 67, 7, 8,213,145, 43,142,227,238,137, 92,177, 44,139,219,213,233,110,111,131,150, 92, 46, 79,206,201,201, 9,243,244,244, 68,
+ 81, 81, 17, 20, 10,197, 61,230,140,227,184,154,200,150, 66,161,176,182,211, 74,110, 72,151, 97, 24, 76,153, 50, 5,155, 55,111,
+ 6, 0,188,253,234, 48,104, 52,106,152, 76, 38, 24, 12, 6,188,253,234, 80,172,254,110, 23, 24,134, 65,116,116, 52,250,245,235,
+103,115, 4,107,210,164, 73,117, 70,176,118,237,218,165,183, 53,159,173,199,200,218, 54,238,113, 30, 35, 91, 35, 88,182, 24, 44,
+ 66,200,155,237,219,183,159,161, 82,169,238,230,230,230,110,241,242,242,154,178,124,249,114,223, 59,119,238,192,209,209, 17, 7,
+ 14, 28, 80, 77,157, 58,245,157,179,103,207,142,161,148, 30,106, 40, 93, 29, 59,118, 60, 18, 17, 17,209,166,246, 48, 13,213,215,
+125,246,149, 43, 87, 30,101,128,209,195, 3, 6, 12, 24,236,232,232,136,215, 95,127, 29,114,185, 28, 35, 70,140,128,147,147, 83,
+209,186,117,235, 16, 22, 22, 86, 99,226,231,206,157,139, 59,119,238,128, 16,114,184,174,232, 85,245,249,121,173, 73,147, 38, 33,
+163, 71,143, 70, 73, 73, 9,178,178,178,224,232,232,136,192, 37, 75,112,241,157,119, 16,180,102, 13,152,222, 85, 53,157,181,206,
+207,107,117,233,249,248,248,132,139,162,248, 49,128,174,248, 95, 39, 29, 10, 32,134, 97,152,127,103,100,100,196, 63,160, 76,100,
+172,230,177,122, 93, 9, 9,137, 63, 49,130, 85,219,104,213,138, 66,213, 69,126,237,118, 89,117, 25,180,218,109,178, 0, 24, 31,
+ 71, 90,185, 90,133,251,253, 61, 0,111, 37, 37, 37, 5,116,232,208, 1,233,233,233, 40, 41, 41,121,160,128,157,157, 29,212,106,
+ 53,110,222,188, 9, 74,233,173,134,110, 48,181,163, 10,181,123, 12,126,240,193, 7,152, 61,123, 54,250,246,237,139,167, 26,217,
+182,229,215,221,107,202, 78, 29, 18,117,130, 72,179, 0, 32, 55, 55, 87,252,232,163,143,116, 7, 15, 30, 52,213,110, 40,111,173,
+206, 19, 4, 33,167,129, 3,200,151,149,149,113, 10,133, 2,132, 16,156, 62,125,186,102, 24,137, 43, 87,174, 64, 38,147, 33, 45,
+ 45, 13,114,185, 28,102,179, 25,168,170, 38,224, 27,115,243,110,132,195,182,253, 96,222,215,230,170,177,145,171,234,168,217,177,
+184,184,184,160, 62,125,250,112, 58,157,238,129, 6,203,106,174,148, 74, 37, 98, 99, 99, 77,122,189,190,193, 17,174, 89,150,197,
+178,101,203, 96, 54,155,107,134,105,176, 86,135, 89,199,194,122,251,213,161,216,177,241, 75,204,156, 57,211,230, 54, 88, 50,153,
+ 12, 95,127,253,181, 94, 38,147,213, 84, 51,214,110,127,101,109, 59,247, 48, 6,235,113, 29, 35, 47, 47, 47,119, 15, 15,143,229,
+ 46, 46, 46, 42,131,193,240,187,245,107,255, 94, 95,132,203,138,191,191,255,251, 73, 73, 73, 77,138,139,139,181,123,247,238,141,
+244,244,244,132, 82,169,196,176, 97,195, 42, 69, 81,100,150, 47, 95,174, 90,179,102,141,106,214,172, 89,171, 0,180,180,193,252,
+ 54, 93,179,102,141,211,137, 19, 39,238, 25,158, 96,204,152, 49,143, 52,192,104, 98, 98,226, 11,145,145,145,126,130, 32, 92,236,
+220,185, 51,119,231,206, 29, 60,251,236,179, 80,171,213, 53,199, 70,167,211, 89,219,165, 81,142,227,130, 26,154, 33,194,104, 52,
+158, 60,122,244,104,208,240,225,195,153, 27, 55,110, 64, 46,151, 87,245,238,237,218, 21, 65,107,214,224,210,244,233,232,149,154,
+ 10,131,197, 2,181, 90,141,253,251,247, 91, 42, 43, 43, 79,214, 99,216, 86,198,196,196,180, 87,169, 84, 48,155,205, 16, 69, 17,
+ 12,195, 16,150,101,187, 5, 6, 6, 46, 1,208,163,246,250, 90,173,182,245,228,201,147,155,242, 60, 47,100,102,102, 22, 73, 81,
+ 44, 9,137,199, 22, 77,106,168,160,206,191,207, 28,153,106, 45,231,163,106,110,229,103,171, 63,163,214,231,120, 0,225,247,173,
+107,253,221,116,223,187,245,247,164, 63, 52,130,197,178,236,240, 55,222,120, 99, 69,223,190,125,163,102,204,152, 1,123,123,123,
+100,103,103,215, 68,170, 20, 10, 5,124,125,125,161,215,235,113,226,196, 9,148,148,148, 28,103, 89,118, 74, 67, 27,180, 88, 44,
+ 53, 55,189,218, 61, 6,253,253,253,177,107,215,174,223, 25,130,186,134, 44,168,205,218, 29,186, 54,181,151,207,157, 59,231, 7,
+ 0, 31,126,248,225, 67,101,138, 76, 38,219,179,109,219,182,231,251,247,239,207, 88, 35,120,214,116,212, 30, 74,194,104, 52,226,
+251,239,191,167, 42,149,234, 72, 93, 61, 8,107,239,119,237, 8,214,227,186,121, 91, 44, 22,104,210,210,238,233,213,233, 83, 86,
+118,207,114, 59,209,246,102, 34,132,144,101,171, 87,175,158, 16, 18, 18,226,226,237,237,141,202,202, 74, 16, 66,224,225,225, 81,
+ 99, 96, 84, 42, 21,228,114, 57,146,147,147,113,232,208,161, 74, 74,233, 50, 91, 34, 88,239,190,251, 46,118,238,220,121,143,121,
+178,154, 43,235,112, 13,148, 82, 44, 94,188, 24,131, 7, 15,174, 55,114, 90,219,240,189,254,250,235,117, 70,176, 14, 31, 62,172,
+183,213,172,253, 17, 6,171,105,211,166,157, 34, 34, 34,246,174, 93,187,214,213,221,221, 29, 89, 89, 89,247,156,211, 77,155, 54,
+237,212,165, 75,151,189,107,215,174,117,245,240,240, 64,122,122,122,131,251,157,154,154,186,122,200,144, 33,243,134, 14, 29, 74,
+250,244,233, 3,181, 90,141,127,255,251,223,184,122,245,234,100, 0, 23,119,239,222,125,126,226,196,137,104,222,188,185,151,141,
+233,175, 25,104,180,118, 84, 90, 16,132,188, 71, 45, 96,120,158, 95,184, 98,197, 10, 78,163,209, 64,175,215, 35, 63, 63,255,158,
+ 42,193,202,202, 74,120,121,121, 97,242,228,201,228,243,207, 63, 95,140, 6,198,193,226,121,254,139,241,227,199,143,235,211,167,
+143,179, 86,171, 69,118,118, 54,228,213,213,130,228,233,167,209, 51, 37, 5, 38, 65,128, 70,163, 65,114,114, 50,214,175, 95,175,
+ 51,155,205, 15,172,147, 15, 8, 8, 80, 48, 12, 19, 32,151,203, 49,118,236,216,123,126,251,238,187,239, 16, 41, 8, 33,175,251,
+248, 20,136, 12, 99, 42,234,216,241, 4,195, 48,100,202,148, 41, 62, 61,122,244,104,127,249,242,229,212,130,130,130,179,210,109,
+ 81, 66,226, 79, 35,254, 47,250,239,227, 55, 88,241,241,241,183, 1, 12, 14, 9, 9,121,225,196,137, 19,139,166, 79,159,238,222,
+189,123,119, 20, 21, 21,193,207,207, 15,222,222,222, 72, 72, 72, 64, 82, 82, 82, 33,165,116,118, 66, 66,194, 79, 15,184, 89,255,
+110,182,109,189, 94,143,245,235,215, 99,234,222,189, 88,218,161, 3,138,238, 27, 7,169, 54,159,127,254,185, 53, 66, 84,175,214,
+238,131,252, 0, 0, 32, 0, 73, 68, 65, 84,230,253,109,176,130,131,131, 99,154, 53,107,230,157,158,158,206,215,142, 96, 89, 63,
+223,223, 6,235,126, 77,163,209,248,193,150, 45, 91,100, 63,252,240,195, 96, 81, 20,101,245,152, 80, 94,165, 82, 29, 50,153, 76,
+ 51,235,219,119, 74, 41,241,244,244, 68,243,230,205,161,215,235, 27,213,171,173,246,205,248, 65,251,110, 50,153,176,108,225, 66,
+ 44, 61,115, 6,147,186,118,173,215,136, 60,168, 93,209,253,154,113,113,113,229,193,193,193, 19,103,206,156,249,253,135, 31,126,
+168,246,240,240, 0,207,243,248,226,139, 47, 32,138, 34, 68, 81,172, 49, 87, 51,102,204,168,172,172,172,156,120,254,252,249,242,
+134,142, 17,203,178, 88,188,120, 49,120,158,175, 25,166,193, 58,208,168, 74,165,130,193, 96,192, 55,155,247,131, 97, 24,204,152,
+ 49,227,119, 85,211, 15,210,180,166,229,199, 31,127,212,223, 31,181,186,127,185, 14, 51,121,207, 49,178,183,183,135,159,159, 31,
+220,220,220, 30,219, 49,114,115,115,123,119,253,250,245,174,122,189, 30,201,201,201, 72, 78, 78, 6,195, 48,215,238,255, 93,167,
+211,225,210,165, 75,184,122,245, 42, 8, 33,215,234,203, 79, 74,233, 18, 66,200,166, 95,127,253,117,168, 82,169, 28,238,233,233,
+233,147,158,158,190,153, 82,186, 21, 0,222,126,251,109, 88, 44,150,134,170,246,107, 52, 47, 94,188, 88,231, 0,193,181,171, 15,
+173,215, 16,165, 52,251,220,185,115,221,108,185,222, 1,152,118,239,222, 13,123,123,123,236,220,185,147,119,113,113,225,230,207,
+159, 15,133, 66,129,121,243,230, 33, 61, 61,157,159, 48, 97, 2, 39,138, 34, 40,165,166,134, 52, 41,165, 21,132,144,201, 61,122,
+244, 88,255,203, 47,191,168, 90,183,110, 13,235, 64,196,115,230,204,193, 23, 95,124, 1,141, 70,131,107,215,174, 97,232,208,161,
+122,157, 78, 55,185,246, 24, 88,181, 53,121,158, 39,114,185,156,138,162,136,127,255,251,223,247, 12, 44,170,209,104,160, 6,176,
+ 32, 62, 94, 29, 29, 21,165,158, 50,111,222,208,106,131, 39, 92,190,124, 57,117,245,234,213, 49,148,210,227, 13,236,251,163, 86,
+133, 72,154,146,230, 63, 74,243,239, 70,131,245, 71,231,206,157,219, 18, 20, 20,116,112,225,194,133, 31,237,216,177,227,181,169,
+ 83,167, 18, 71, 71, 71,108,221,186,149, 22, 23, 23,255,160, 82,169, 62, 56,117,234, 84,137, 77, 27,227,184,235,135, 15, 31,238,
+ 60,125,250,116, 25, 59,115, 38,254,115,223, 36,191,247,147,156,156, 76,117, 58,157, 96, 48, 24,234,157, 83,236,113,183,193, 74,
+ 76, 76,204, 1, 48,246, 49,230,243,190, 79, 62,249,100,212,134, 13, 27, 56,181, 90,141,148,148, 20,220,176, 78,191, 82,183,121,
+195,103,159,125,198,155,205,230, 58,123, 50,168, 84,170, 59,167, 79,159,246,249,232,211, 79, 89, 35,195,224,243, 90,195, 21, 60,
+ 40,106,115,250,244,105,170, 80, 40, 74, 27, 74,236,249,243,231, 15,132,134,134,190, 52,101,202,148,111,134, 12, 25,162, 9, 11,
+ 11,147,251,249,249,129,227, 56,164,167,167,227,228,201,147,166, 3, 7, 14,232,141, 70,227,235,231,207,159, 63,100, 75, 6, 48,
+ 12,131,247,222,123, 15, 12,195,160, 77,203,102, 56,120, 34,254,158, 30,115,187, 15,158,130,151,167, 27, 58,116,232,128, 69,139,
+ 22, 97,216,176, 97, 13,233, 9,102,179,153,213,104, 52, 53, 99,149, 89,247,221, 90, 93,216,187,119,111,245,233,211,167,245, 38,
+147, 9, 44,203, 54, 20, 14,219,183,100,201,146,145, 63,252,240,131, 76,163,209, 60,182, 99,196,243,124,187,226,226, 98,232,116,
+ 58, 36, 36, 36,208, 47,191,252,178,160,180,180,116,110,237,223,139,138,138, 80, 94, 94,142,179,103,207,210,175,190,250,170,160,
+188,188,188,193,161,226, 41,165, 57, 0, 86, 87,191,238, 33, 55, 55,183,210,108, 54,107,178,179,179, 45,143,122,226, 90,171, 15,
+ 99, 99, 99,225,224,224, 0, 39, 39,167, 70, 85, 29, 82, 74,103, 28, 60,120, 80,142,234,169,114,242,243,243,207,202,100, 50,133,
+ 66,161, 64,102,102, 38, 68, 81,236,178,110,221,186,104, 0,102,142,227,166,218,168,121,136, 16,242, 90, 96, 96,224,154,121,243,
+230,217, 69, 69, 69,113, 90,173, 22,253,250,245,195,245,235,215,241,203, 47,191, 88, 86,173, 90, 85,169,211,233,222,162,148, 30,
+169,167, 60,162,148, 82,194,243,252, 61, 29, 55,172, 61,100,245,162,136, 15,130,131, 13,148,227, 76,243,230,205, 59, 14, 0, 89,
+ 89, 89,197,249,249,249,137,162, 40, 30,207,206,206,206,148,110, 33, 18, 18, 18,117,154,208,198, 52, 33,136,136,136,136, 16, 69,
+241,103, 65, 16,100,132,144, 17,137,137,137,167, 27,227,112, 35, 34, 34, 28,228,114,249, 97,189, 94, 31,104,203,246, 20, 10, 69,
+137,197, 98, 25, 28, 31, 31,127,161, 62,215,252,230,112,187,235, 26,149,200, 86, 26, 44,183,214,238,176, 12, 12, 9, 9,185, 51,
+104,208, 32, 85, 93,109,176,204,102,243,205,132,132,132,103,254, 44,119, 79, 8, 97,130,131,131,207,200,100,178,136,234,237,215,
+190, 89,212, 12,150,104, 93,174, 21,157, 74,191,126,253,122, 43, 74,169,185,142,252,244,148,201,100, 71, 13, 6,131,159, 45,105,
+ 82, 42,149,217, 70,163,177,127, 98, 98, 98,170, 45,251,222,189,123,119,103,158,231,255,165, 84, 42,159, 54, 26,141,237, 0, 64,
+173, 86, 39,235,245,250,163, 28,199, 45,175,203, 88, 63, 72,179,115,231,206, 58,150,101, 73,237, 33, 25, 30,244, 94,123,184,134,
+138,138, 10, 79,235, 36,223,247,107,246,232,209, 99,195,232,209,163, 7,190,242,202, 43,132,227,184,154,124,179, 30,107,107, 53,
+180,209,104,196,134, 13, 27,232,246,237,219,247, 31, 59,118,108, 92, 67,199,136,227,184, 8, 66, 72,205, 49,122,208,245,209,152,
+ 99,228,231,231, 23,100,103,103,183, 14, 85, 35, 11,167,148,150,150, 78,205,204,204,204,172,253,187, 90,173, 94, 7, 64,193, 48,
+204,239,126,127,152,243,147, 16, 50,177,109,219,182, 51,175, 93,187,182,172,174,177,175,108,213,236,212,169,211,145, 46, 93,186,
+180, 57,127,254,188,217,122, 13,213, 53,254,149, 45,154,161,161,161, 91, 0, 12,174, 94,255,112, 66, 66,194,208,135,125, 74, 38,
+132, 56,201,229,242, 73,106,181,186,167,193, 96,104, 91,253,208,113, 77,175,215,159, 48,155,205, 95, 82, 74, 75, 27,210,244,247,
+247, 63,123,242,228,201, 64,107,212,211, 58,122, 59,203,178,104,218,180,233,185,172,172,172, 30, 82,212, 65,210,148, 52,165, 8,
+214, 31,110,176,164, 19,229,159,171,105, 29,169,213,150, 70,189,127, 70, 58,187,118,237,170,229, 56,110,129,209,104,236, 95,223,
+ 40,237, 44,203, 10,106,181,250, 87,147,201,244,127,247, 79,246, 44, 29,119,233,252,124,152, 94,132,210, 49,146, 52, 37, 77,201,
+ 96,217, 2, 39,101,129,132, 45, 60,105,189,165,170,205,210, 56,233,200, 72, 60,202,249, 89,109,160,250, 74, 57, 40, 33, 33,241,
+184, 97,164, 44,144,144,144,144,144,144,144,144,120,188, 16, 0, 29,235,120, 34,108, 76,155,143,142, 15,241,196,121, 73,210,148,
+ 52, 37, 77, 73, 83,210,148, 52, 37,205,127,150,102, 67,218,127,151,170, 71,169, 13,150,164, 41,105, 74,154,146,166,164, 41,105,
+ 74,154,127,185,230,223, 13,169,138, 80, 66, 66, 66, 66, 66, 66, 66,226, 49, 35, 53,114,127, 8,180, 90,173, 26,192,179, 28,199,
+141,117,113,113, 9, 43, 44, 44, 92,144,145,145,241,197,223,116, 95, 91, 83, 74,199, 50, 12,243, 2, 0,136,162,184,149, 16,242,
+ 67, 86, 86,214,141, 71,213,142, 34,132,243, 2,198,203,128,105, 0, 96, 1,150,229, 0, 95, 31,163,148,255, 59,159, 63, 61,131,
+201, 44,133, 92,246,186,193,108, 89,116,234, 60,253, 38, 42,148,184,241, 34, 22,170,228, 92, 15,163,137,255,244,100, 18, 93,255,
+136, 79,150,246, 30, 30, 30,209, 12,195, 60, 77, 41, 37,148,210, 19,249,249,249,179, 40,165,101,210,213, 43, 33, 33, 33,241, 4,
+ 25, 44, 66, 8,219,190,125,192,203, 44, 33, 79, 1,112, 6, 80, 34, 80,122,250,234,213, 91, 63, 80, 74, 31,106,190,178,168,168,
+ 40, 78,175,211,141,225, 88,118, 32,165,180, 35, 40, 37, 32,228, 18,207,243, 7, 52, 14, 14, 27, 27,154,122, 6, 0, 70,141, 26,
+197,102,102,102, 94,231,121,222,163, 49,219,150,201,100, 57,103,206,156,105,243, 48,233,246,241,241, 25,209,180,105,211,213,145,
+145,145,154,224,224, 96,200,229,114,124,250,233,167, 83, 1,216,108,176, 72, 84, 20,215,164,216,109, 12, 35,227, 6, 1,180, 35,
+165, 0, 37,220, 37,152,205, 7,114, 93, 11, 54, 82, 27,246, 29, 0, 66, 66, 66,102, 18, 66,198, 86,247,160,218,112,238,220,185,
+207, 31,229,100,248,239, 27,108, 46,165,162,189, 72, 9, 42, 12, 50,243,207,199, 93, 47, 7, 7, 7,135,204,156, 57, 19,145,145,
+145, 16, 69, 17, 39, 78,156,152,182,108,217,178,105,222,222,222, 9, 44,203,110,148,203,229,219, 82, 83, 83, 31,234,198,237, 5,
+140,143,236,222,125,241,107, 51,102,176,149, 39, 78, 96,249, 55,223,124,138,178, 50, 0, 88,219, 72, 67, 65,186,116, 9, 26,238,
+232, 72, 6, 50, 4, 65, 20,148, 16,144, 11, 69,197, 56,144,144,112,254,103, 74,169,248,176,121, 18, 22, 22,182,157, 82,218,191,
+122, 59,191, 38, 36, 36,140,120,148, 60,238, 22, 76, 34,219,182,240,254,239,228,151,158,198,123, 11, 55, 79,238,222,137, 20,168,
+237,228,171,159,239, 30,224, 28,216,210, 25, 31,174,141,153, 10,224,161, 13, 22, 33, 68,227,225,225, 17,183,107,215,174,166, 17,
+ 17, 17, 28, 0, 36, 36, 36,140, 25, 60,120,112, 47, 66, 72, 56,165,180,252,175, 40,104,186,118,237,170,226,121,126, 34, 11, 60,
+ 67, 41,237, 80,157,214,203, 2,240, 27,199,113,235, 98, 98, 98, 12, 82,113, 44, 33, 33,241,143, 50, 88,132, 16,182, 99, 96,235,
+165, 19,223,124,171,221,240,225,195,189,213, 26, 7, 85,122,250,173,172,117,107, 86, 57,177,132,233, 76, 8,153,209, 88,147, 21,
+ 17, 17,209,142,136,226,143,111,191,254,122,243,176,110,221,184, 38,222,222, 48,148,150,226,214,181,107,190,241,103,207,246,217,
+117,248,240,180,208,208,208,177,137,137,137,151,235,211, 41, 40, 40,144,113,130,224,121,228,147, 79, 88,198,197, 5,148,231,193,
+183,107, 7, 81, 20, 65, 5, 1,220,233,211,128,197, 2, 42, 8, 48,247,174,154, 13, 68, 20, 69,244,239,223,223,231, 97, 50,203,
+215,215,215,187, 85,171, 86,235,231,204,153, 35, 55, 26,141, 56,127,254, 60,206,156, 57, 35,230,231,231, 47,181,217, 84, 4, 15,
+109,231, 5,175, 77, 67,135, 15,106, 54,184,175,135,194,207,203, 3,162,168,196,181, 84,139,239,161,147,231,250,254,178,255,224,
+187, 77, 58, 14,125, 57,247,210,174,122,247,189, 75,151, 46,253, 24,134,153,151,144,144, 0, 0, 8, 13, 13, 93, 16, 26, 26,186,
+160,161,237,219,217,217,229,233,116,186,241,137,137,137, 15,152,160, 89,212,204,159,250, 22, 68, 10,124,181,239,154, 60,121,213,
+174, 16, 71, 71,199,123, 38, 75,238,215,175, 31,250,246,237,139,244,244,244,176, 29, 59,118,132,173, 95,191,254, 83, 31, 31,159,
+121, 25, 25, 25, 43, 26,155,159, 50, 96,218,107, 51,102,176,118,105,105,176, 59,127, 30, 99,203,202,184, 69, 85,209, 44,155, 13,
+ 86,120,120,120,139,126,125,131, 55, 14, 27, 30,213,214,203, 43, 80, 46,147,185, 87, 79,220, 92,212, 42, 63,255,234, 48, 23, 23,
+188, 23, 17, 17,241, 82, 67,147, 8,215, 58, 55, 61,121,158, 95, 1, 64,206, 48,204, 12, 74,105,255, 3, 7, 14, 64, 16, 4, 12,
+ 30, 60,184,127,120,120,120, 11, 81, 20,151,218,217,217, 81,163,209,248,118, 92, 92, 92,163,230,235,227, 8, 62, 26,253, 92, 95,
+232, 45, 12, 44, 22,222,195,219,195,225,135,169,175,244,146,129,154,240,221,238,115,176,240,226, 55,143,114, 65,107,181,218, 5,
+223,127,255,189, 79,100,100,100,205,216, 96,193,193,193,236,146, 37, 75,180,211,166, 77, 91, 12,224,205, 70,152,203, 32,165, 82,
+185,160,164,164,100,212,149, 43, 87,116,157,222,222,233,193, 89,212, 14, 50,181,104,140, 91, 49, 32,179, 17,199, 40,140, 35,100,
+211,146,247,199,123,181,237,212,153, 81,121,184,131,220,201, 67,177,160,127,250,204,165,171, 61, 62, 95,181,113, 82,120,120,248,
+ 75,241,241,241, 9, 82,145, 44, 33, 33,241,143, 49, 88,237,219, 7,188, 60,254,141, 55,218,189,245,246,228, 80,179,217, 88,121,
+ 33,241,248, 17, 78,206,176,147,167,188,225, 84, 84,156,239, 78,169,248, 50,128, 13,141, 48, 87, 1, 77,155, 52, 57,180,112,209,
+ 34,103, 87, 15, 15,228,228,228,224,110, 70, 6,178, 47, 93, 2, 1,208,183,111, 95, 69, 80,231,206, 45,151,173, 93,123, 32, 60,
+ 60,188, 95,124,124,252,213,250,244, 88,142, 3,177,179, 67,102, 72, 8, 32,151,163, 52, 38,166,234,123,158,135,253,144, 33, 85,
+ 43,201,229, 48, 95,184, 0,134, 97,224,233,233,249,208,153, 69, 41,141,232,222,189,187, 28, 0,222,123,239,189,114,157, 78,183,
+152, 16,178, 37, 51, 51, 51,203,150,255,123, 4, 61, 31,224,233,238,121,112,201, 71, 19, 93, 58,250,183,132,201, 98, 65, 70, 94,
+ 38, 40,148,240,242,180,199,216, 97, 65,242,167,194,100, 1, 75, 87,254,246,171, 87,231, 33,125,115, 46,236,169,115,223, 89,150,
+ 93, 58,123,246,108,108,217,178, 5, 0,176,105,211, 38,180,110,221,186,193, 52,156, 57,115,198,243,253,247,223, 95, 13,224,129,
+ 17, 60,145, 86,205, 91,216,178,101, 0,156,156,156,234, 50,221,240,243,243,195,180,105,211, 16, 18, 18,162,120,249,229,151, 63,
+ 2,176,226, 97,242,180,242,196, 9,216,157, 63, 15,156, 56,209,232,255,134,134,134,250,182,111,239,118,116,233,146,255,186,239,
+217,123, 25, 75,150,124,131, 91,183,170,124, 84,203,150, 45,241,210,152, 81,178,141, 63,172,109, 63,107,214,220, 35, 93,186,116,
+121,230,236,217,179, 55, 27,210,228,121,126, 69,116,116,244, 96,123,123,123,204,158, 61, 59,201,223,223, 31,142,142,142, 88,187,
+118, 45, 92, 92, 92,192,243,124,210,162, 69,139,184,172,172, 44, 44, 95,190,124, 53,128,225,182,166,183, 71, 16, 25, 20, 22,220,
+ 49,210,207,183, 25,142,157, 57, 11,185, 66,230,252,206,171,207,194,193,158,195,226,175,247,137,233, 25, 69,147, 79, 38,209,239,
+234,125,224, 25,181,141, 13,210, 37,185, 36, 29, 80, 20, 81, 58, 87,180, 70,240, 80, 61, 72,102, 19,111,237,160,158, 61,123,178,
+213,231, 43,210,210,210, 96, 50,153,208,190,125,123,198,108, 54,247,108,196,117, 26,162, 80, 40,246,155,205,102,181,157,157,157,
+ 6,128,142,179,168, 29, 68, 57, 55,210, 76,197,171,157,102, 30, 50, 95, 92,220, 55,223, 22,115,213, 46,160,217,190,229, 11,254,
+207,142,205,191, 1, 29, 57,143,226, 92, 51,176,116, 15, 24, 71, 15, 60,253,222,100,174,115,112,144,118,246,255, 69,239,235,210,
+165,203,160,179,103,207, 38, 74,197,178,132,132,196,223,129, 6, 27,185,179,132, 60, 53,108,216,112, 15,147, 73,175, 51, 24,116,
+ 37,183,239, 36,100, 31, 57,178,254,210,245,171, 39,111,244,235,223,213,204,176,228,169,122, 12,201, 61, 61, 12, 70,141, 26,197,
+ 50,130,176,121,209,226,197,206,172, 92, 14,139,197, 2, 63, 63, 63, 24, 12, 6,148, 21, 23, 35, 39, 61, 29,167,247,238,133,174,
+160, 0, 83,198,142,117,150, 17,178, 41, 52, 52, 84, 86,159, 38, 40, 5,248,123,107,212, 24,134,185, 39,234, 98,253,238, 65,243,
+243, 61, 80,179, 14, 68, 81, 76,203,202,202,130, 70,163, 65,187,118,237,236, 8, 33,103, 50, 50, 50,178,108,209, 36,163, 70,177,
+ 50, 25,187,109,241, 71, 99, 92, 8,123, 29,215,211, 19,192,177, 74,184, 57,249,194,100, 6, 78, 37,254,130,111,182,253, 7, 25,
+153,113,152, 56,182,149,147, 90, 77,127, 38,161,111,214,185,239,102,179,185,121, 64, 64, 0, 58,118,236,136, 78,157, 58, 65, 16,
+ 4, 92,190,124, 25, 23, 47, 94,196,249,243,231,145,152,152,136,248,248,120,196,198,198,226,204,153, 51, 24, 53,229, 51,188, 53,
+101, 38, 42, 42, 42, 96, 50,153,124, 30,156, 78,166,114,252,127,190,199,225,171,102, 20, 20, 27,176,117,235, 86, 20, 21, 21, 97,
+243, 23,221,177,102,174, 55,214,204,245,198, 15,159,133,160,184,184, 16,177,177,177, 88,188,120, 49,116, 58, 29, 4, 65,224, 30,
+ 38, 63, 45,192,178,229,223,126, 43, 38,159, 56,129,100, 0,235, 9, 17, 45,192, 50,155,242,147, 16,226,230, 42,254,180,108,217,
+127,220, 89,230, 10, 92,157, 22,225,236,217,211,200,205,205, 69,110,110, 46,226,226,206,192,197,249, 43,112,220, 85,124,246,217,
+ 60, 87,103,103,254, 71, 66, 8, 99, 67, 58,229,201,201,201,208,235,245,248,233,167,159,184,232,232,104,196,197,197, 65,173, 86,
+ 99,220,184,113, 88,177, 98, 5,231,234,234,138,219,183,111,163,162,162,130, 52,234, 92, 34,120,109,212,240, 97, 96,229,118,184,
+118, 43, 3,189, 34, 67,224,233,233,137,171,105,197, 72,207, 44,202, 37, 4,227, 6, 60,165,204,233, 25, 76,198,215,165, 73,183,
+142, 20, 94, 26, 57, 32,120,192, 4,199, 9, 77,195, 39,118,174,222,167,234,116,180,231, 8,163,112,178,154,171,155, 55,111, 34,
+ 57, 57, 25,119,238,220,193,157, 59,119, 96,177, 88,234, 76,103,175, 94,189,222,137,140,140, 44, 14, 15, 15, 47,239,209,163,199,
+ 70,150,101,247, 47, 88,176, 64,163, 82,169, 76,188,139,159, 93,232,155,191,249,202,101, 10,158, 18,198, 72, 5,124, 40, 43,151,
+187, 4, 76, 61,160,168,111,223,187,118,237,170,146, 49,204,166, 21,209,255,182,179, 36,108, 7,188,155,194,211,127, 34,236, 93,
+ 34, 65, 75,244,224,147,146, 81,190,100, 37, 56,149,136,127,255,223, 44, 59, 34,138, 63, 4, 4, 4, 40, 30,230, 92,106,228,131,
+146,164, 41,105, 74,154, 79,160,230, 63, 46,130, 69, 24, 56,107, 52,106,121,204,233,157, 7,178, 50,174, 20,100,231, 94, 42,101,
+ 64,153,172,172,132, 82,255, 86, 79,187,161,170, 77,150, 77,164,166,166,190, 56,237,173,183,252,157,170, 34, 1,112,119,119, 71,
+ 70, 70, 6, 12, 6, 3, 42,203,202,160,175,168,128,177,172, 12, 87,143, 28, 65,183,129, 3,209, 63, 56,216,119,239,185,115,175,
+ 1, 88, 87,231, 77,154, 97,192,119,238,140,210,196, 68, 16,179, 25, 78,161,161, 53, 81, 43,227,149, 43, 85,198,202, 98,129,236,
+169,167, 64, 52, 26,144,121,243, 30, 58,179,178,178,178,146,252,252,252, 14, 14, 24, 48,160,223,196,137, 19,153,156,156,156, 93,
+ 94, 94, 94,189,115,114,114,146, 27,250,111,147, 27,226,216, 87, 39, 6,183,112,119, 34,216,115,230, 87, 68,182, 27, 14,141,146,
+ 67,126,113, 37, 24, 66,112,235,246, 97, 8,130, 29,146,146,211,209,173,163, 29,186, 71, 56, 54,213,253, 86,252, 58,234,169, 46,
+ 51, 24, 12,200,203,203,131,197, 98, 1,207,243, 24, 57,106, 20,190,219,176, 1, 58,157, 14, 6,131, 1, 38,147, 9,162, 88,213,
+252, 40, 39,207,128,184,115,251, 17,218,169,238, 40,215,135, 95, 9, 77,180, 90,109,229,119,123,214,226,208,161,170, 57,156,119,
+237,218, 5, 67,110, 10, 38,189, 88,213,244,104,217,119, 63, 97,217,103, 75, 97,182,136, 86,163,247,208,249,121, 19,248, 38, 85,
+ 20,103, 13,216,190,221,227,204,206,157, 98,236,158, 61,153,202,242,242,175,109,249,111,151, 46, 65,195, 39, 79,126,182,173, 90,
+165, 70, 70,250,231,104,215, 78,142, 25,211,220, 16,189,168, 0, 0, 48,117,178, 15,194,194,220, 80, 86,178, 13,238,158, 31,224,
+189, 25,195,253, 43, 42, 48, 6,192,198,122,159, 56, 24,102,198,198,141, 27,147,250,245,235,199,157, 59,119, 14, 74,165,178,102,
+162,112,181, 90,141,156,156, 28,152, 76, 38,108,217,178,133,103, 24,102, 70,227, 74, 36, 52,109,226,229, 3,134, 90,144,149, 91,
+128,161,131,250,129,147,219, 35, 45,163, 0, 65,129, 45,189, 95, 26,242,148, 55, 75,120,188,191,232,199,119, 0, 60, 48, 31,162,
+162,230,115,239,252,103,172,229,157, 54,205, 29,247, 30, 60,253,218, 30,134, 20,230,150, 94,253, 28, 55,206, 24,148,173, 58,190,
+216,214, 31,230, 35, 71,142,168,123,246,236, 9,189, 94,111,141,118, 98,227,198,141, 34,207,243,117,134, 9, 5, 65,152,245,253,
+247,223, 43,220,221,221, 49,101,202,148,190,227,199,143, 87,135,134,134, 18, 74, 41,168,162,149,147,192,209, 94, 60,248,179,172,
+ 73,216, 11, 57,219, 79,224,204, 99,157, 5,118, 45,128,140,122,162,129, 19, 23,127, 60,181, 9, 85,231, 65,222,123, 32,152,124,
+130,204,183,158,131, 88,110,128,121,193, 36,136, 84, 14,163,137,131,121,216, 36,200,253,219, 96,114, 72,184,247,242,115,241,111,
+ 0, 88, 41, 21,205, 18, 18, 18,247, 17, 14,192,218,222,186,160,250,193,210, 13,128, 53,146,238, 1,192,132,170,121, 95,173,220,
+191, 92,123,221,251,151,107,127, 46, 64,213,148, 89, 30, 0, 4, 0,103, 1, 20, 63, 84, 4,139, 16, 66,107, 69, 6,238, 29, 24,
+139,146,130,140,140,212, 34,163,185,216, 48, 32,170,219,180,103, 35,188,230,191,246,226, 59,115,157, 28, 84,234,244,180, 91,148,
+ 48, 40,180,117, 99, 74,153,172, 95,104,100,164, 44, 39, 39, 7, 78, 78, 78,200,204,204,196,141, 27, 55, 96, 48, 24,160, 43, 45,
+133,177,184, 24,124, 97, 33, 80, 88,136,180, 19, 39,208, 86,171, 85,176, 54, 76, 99, 33,138, 34, 8, 33, 96, 89,246,129, 81, 43,
+134,101, 65,236,237, 1,123,123,128,105,220,200, 20, 90,173,246,217,118,237,218, 29,211,106,181,179,170, 13,197,180,232,232,232,
+ 66, 74, 41,102,205,154,229,224,224,224,176,177,121,243,230,202,134,116,236, 93,249,225, 17,157, 90,177,215,211, 47, 34,172,245,
+243,104,238,221, 19,183, 50, 75,145, 95,106, 64, 78,145, 14,109,218,204,132,135,118, 34,156,188,222,194,133,107,119,161,245,242,
+103, 24,153,188,222,125,207,201,201,185,103,249,199, 77,155, 80, 89, 89,137, 86,173, 90,225,197, 23, 95,196,251,239,191,143,209,
+163, 71, 67,171,213,162,123, 75,224,245,151, 71, 34, 47,175, 81, 77,134,224,227,227, 83, 51, 65,155, 40,138,224,121, 30, 22,203,
+255, 76,149,201,100,178, 89,203,203,203,235, 61, 47, 47,175, 56,111,111,239, 4,111,111,239, 29,185, 90,237, 57,139,191,191,103,
+247,225,195, 73,224, 11, 47,176,119,237,236,200, 29, 63, 63, 59, 91,180, 28, 29,153, 1, 97, 97,221, 21, 37,197,223, 0,168, 50,
+123,175,191,230,129, 83,199, 59,224,244,201, 80, 76,153,220, 18, 12, 81,129, 48,114, 84,234,126, 67,251,192,142,114, 7, 7, 58,
+176, 62,205,176,176,176,237,162, 40, 94,238,208,161, 3,247,246,219,111, 67,169, 84,226,187,239,190,195,234,213,171,241,217,103,
+159,225,250,245,235,240,243,243,131,183,183, 55,154, 52,105,194,137,162,120, 57, 44, 44,108,187,173,251,175, 86,169,220, 20, 42,
+ 39,176,114, 59,112, 50, 25,154,249, 54, 7, 43,183, 67,113, 89, 37,198,189, 48, 4,151,110,102,227,227,213,123,120,139, 69,172,
+179,186,245,248,241,185,194,142,125,199, 44, 21, 21, 58,238,185, 65,125,244,111,189,246, 98, 43, 23, 85,203,111,224,211,167,115,
+139,102,222, 47,254, 55,122,133,105,194,219,239,154,191, 90,255, 53, 45, 47, 47, 71, 89, 89, 25,150, 47, 95,206,239,217,179, 39,
+ 75, 16,132,153,245, 24, 44, 5,203,178,160,148, 98,194,132, 9,154, 54,109,218, 16,158,231, 65, 41,133,194,172, 51, 51, 34,218,
+ 16,194,140, 32, 44,107, 22, 64, 54, 18,202,246, 16,121, 78, 94,111,244, 27,120, 38,176,115,103,182, 82,159, 6,123,199, 80, 20,
+126,250, 95,136, 57,197,160,121,101, 16, 56, 13,244,162, 10,101, 38, 25,138, 58,133, 32, 43, 41, 25,158, 26, 71,142, 35,164,143,
+116, 31,145,144,248,103, 81,175, 7,249, 31, 30,132,144,189,132,144,189,115,230,204,121, 26,128, 27, 33,100,111,181, 9,242,168,
+254,172,176,174, 83,199,178, 71,109,157,251,254, 91,251,179,251,156, 57,115,122, 19, 66,246,118,235,214,237,229,106, 35,247,248,
+ 35, 88,130, 32, 28,253,242,203, 85, 77,222, 24,255, 92,147,109,123,191,142,254,121,251,133,206, 47,141,206,185,162,109,218,201,
+ 99,227,170,211, 10,158,167,123,109,222,154, 40,118,114,107,210, 4,105,105,105,136,143,143,135,193, 96,128,209,104,132,209,104,
+132,185,184, 24,150,146, 18,144,242,114, 40,120, 30,134,244,116,180,236,212, 9, 4,104,111, 67,168,178,206,106, 65,150,101, 65,
+ 68, 17,196,206, 14,196,206,174, 81, 6, 75,171,213, 6, 7, 7, 7,127,191,110,221, 58,249,244,233,211,195,253,253,253,215,100,
+103,103,167,251,250,250, 14, 90,178,100,201,137,143, 62,250, 72, 57,118,236,216,214,235,214,173,123,169,174,136,131, 21,185,202,
+208,193,175, 73,107,148,235,187, 64,163, 80,160,168,204,136,226,114, 35, 10, 74, 12,216,190,107, 12,140,134, 74,240, 70, 19, 4,
+ 51, 15,251, 38,195,209,202,245,105,128,222, 12,172, 79, 51, 54, 54, 22,151, 47, 95,174,137, 96, 25, 12, 6, 12, 24, 48, 0,195,
+135, 15, 71, 90, 90, 26,206,157, 59, 7, 39, 39, 39,120,120,120, 96,235,214,173,184,120,241, 34, 66,173, 17,190, 70,192, 42,221,
+240,197,166,205, 48, 24, 12,160,140, 61,104,173,154,229,198, 68,176, 8, 33, 99,179,135, 13, 11,192,241,227, 24,216,172, 89,187,
+182,109,219,194, 96,248, 95,231,177,128,128, 0,223,140,140,140,219, 90,173,118, 51, 33,100, 93,102,102,230,133, 58,181, 32, 6,
+185,184,182, 71,214,221,232,106,109, 14, 4, 74,244,238,155, 4,179, 89,196,245,107, 3,160, 82, 42,193, 16, 37,120,190, 16,142,
+ 78, 77, 0,144,192, 6,206,163,254, 7, 14, 28,128,163,163, 99, 77,181, 32, 0, 60,251,236,179, 51,236,237,237,187, 27, 12,134,
+161,123,247,238, 69, 73, 73, 9,252,253,253,225,233,233,137,184,184,184,254,182,238,191,157,157,131, 43, 39,183,131,200,112,112,
+114,114, 1,167,176,131,200,115, 16, 68,192,193,201, 29,103,206, 93,195,213, 59,236,155, 55, 83,177,181,238, 52,130, 6, 12,188,
+ 20, 95,169,171,236, 48,244,185,126,174, 33,157, 59, 26,162,231,189,239,176,240,179, 53, 31,255,103,214, 91, 77, 50,203, 84,101,
+125,167,238,207,219,241,235,188,230, 75, 62, 91,174,202,203,203,179,152,141,134,253,162, 40, 78,173,175, 7, 33,165, 20,151, 46,
+ 93,130,131,131, 3, 82, 82, 82,224,230,230, 6, 65, 16,170, 30, 94,144, 87, 46,200,185,205,172,133,255,150,149,169, 86, 3,230,
+100,145,210,118,148, 19,229,100,254,124,134,206,157, 43,214,161,217, 65,161, 84, 66,167,163, 40, 63,189, 15, 98, 81, 37,104,137,
+ 30,168, 52, 65,167,103, 81, 94, 73, 80, 94, 41, 66,223, 57, 12,194,193, 88,184,148, 26, 64, 41,237, 36,221,110, 36, 36, 36,234,
+ 41,171,158, 37,132,236,141,142,142,126,182,190,223, 41,165,207, 2, 48,221,183, 12, 91, 62, 3,192,194,133, 11, 63,169,181, 92,
+249,135, 24,172,203, 87,111,109,237,216,177, 85,160,143,143, 75,235,208,142, 29, 61,124,154,222, 42,115,247,240,113,248,229,192,
+ 69,117, 94,110,241,181,203,151,111,238,104,140, 81,213, 23, 21, 33,235,194, 5,148, 21, 21, 65,175,211,193, 80, 94, 14,190,184,
+ 24,222,109,219,130, 86, 84,128,213,235,193, 25,141,144,139, 34,212, 26, 13,240,191, 25,238, 31,136, 76, 20,193, 29, 61, 10,251,
+225,195, 1,185, 28,166,171, 87,171,204,150,197, 2, 89,207,158, 32,118,118, 96,156,157, 65,246,237,171,250,222,193, 1,248,188,
+225,209, 12,180, 90,173,155,151,151,215,214, 47,190,248, 66, 94, 80, 80,128, 43, 87,174, 92, 76, 77, 77, 45,115,119,119,183,231,
+ 56, 78,188,118,237,218,209,107,215,174, 13,108,209,162, 5, 4, 65,104,217,144, 94, 69,137,189,217,108, 17,145,153,119, 7, 25,
+217,151,224,100,223, 12,148,241, 69,110, 81, 37, 8, 60, 97,209, 95,131, 88,221,150,204,168,207,128,206, 72,108,202, 80,179,217,
+ 12,179,217, 12,158,231, 97, 50,153,240,202, 43,175,224, 76, 76, 12, 54,237, 58,129,187,119,239,194,191,137, 26, 47,142, 30,137,
+160,160, 32, 88,123, 28,218, 98, 88,107,211,162,203, 82, 40, 20, 10,108,219,182, 13,154,170, 99,210,104,131,229,237,237, 29,221,
+174, 93,187,128,107, 58, 29,174, 36, 39,163,203,168, 81, 0,128, 83,167, 78,213,172,163,215,235,241,210, 75, 47, 41, 82, 83, 83,
+ 95, 77, 78, 78,126,213,219,219,123, 69,118,118,246,156,186, 52,247,237,139,193, 91,111, 93, 65,126,126, 85,100,119,243,166,255,
+249,167,180, 84, 51, 6, 12, 62, 0, 0,112,118,118,198,210,165,182,205,246, 32, 8, 2,214,174, 93, 91, 83, 45, 8, 0, 10,133,
+ 34,114,250,244,233, 67, 31,180,126, 96, 96,189,158, 13, 30, 30, 30,118, 10,133, 98,180, 32, 8, 47, 7,182, 16,184,162,114, 61,
+192,155,112, 59,237, 54, 74,116,102, 80,222,130,244,140,108,232,140, 34, 10,139,202, 17,218,101,208, 23, 38,254,204,255,105,181,
+218, 15,178,178,178, 30,248,240,114,107,255, 10,147,107,192,212,141, 57,249,155,103, 77,158,248,178,204,201,197,171, 98,253,202,
+ 79,156, 24,194, 96, 79,162,165, 56,176,165,155,203,208,200, 21, 21,111,190,251,239, 36,163,112,123, 58,210,127,185, 81, 29,238,
+174,151,162,162, 34, 24,141, 70,220,190,125, 27,106,181, 26, 50,153,172,218, 96, 89, 79,140,234,143, 22,209, 66, 57,194,112, 22,
+150,153,135,185,117, 95,236, 12, 3,220,206, 1, 86,238, 66,209,184,193,176,124, 52, 9, 2, 47, 71, 69,153, 8,211,224,201, 48,
+153, 69, 88, 88, 5,244,237, 58,160,248,195, 5, 48,218,171,129, 75,167,165, 59,136,132,132, 68,125, 15,234,123,103,207,158,253,
+129,141,171, 31, 6, 48,184, 49,198,205,186, 60,123,246,236, 15,172,219,138,142,142,214, 3,200,106,108, 90,109, 10,231,136,162,
+124,213,193, 3,113, 50, 70,198, 49, 45,252,236, 74, 1, 19,206,198,103,218, 89, 4,217,186, 70,230,204,197,148, 27, 55, 64, 69,
+ 17, 21, 37, 37, 48, 20, 21,193,146,151, 7, 75, 94, 30, 72,121, 57, 56,189, 30,156,193, 0,153,201, 0, 21,199,161, 52, 55, 23,
+132, 97,174, 52,152, 49,181, 26,239, 90, 35, 89, 44,203, 2,246,246, 85, 85,131, 26,205,255,170, 11,109,140, 96, 41,149,202,111,
+215,174, 93,235,229,237,237,141,175,191,254, 26, 94, 94, 94,109,158,121,230,153,130, 30, 61,122,228, 62,247,220,115, 9,239,191,
+255,254,192,176,176, 48, 20, 20, 20,128,101,217,148,134,244, 44,102,229,249,171, 41, 2,242, 11,206, 35, 46,241, 91,236,253,117,
+ 14,146,111, 95, 65,118,161, 14,118,158,227,193,217,247,168, 89, 87,225, 24,133,220,220, 2,128,212,191,239,247, 27, 33, 74, 41,
+ 46, 92,184,128,239,118,158,129, 54,240, 25,200,236, 60,112,233,210, 85, 28, 59,116, 16, 62, 62, 62, 13,154,161,255,190,193,230,
+ 62, 19, 82,138, 67, 91, 38, 34,239,230,183, 54, 27, 60, 27, 47,138,209,243,231,207, 71,233, 91,111, 1, 91,183, 66, 46,175,170,
+ 93,138,140,140, 68,120,120, 56, 62,252,240, 67, 68, 70, 70,130,101, 89,180,106,213, 10, 67,135, 14, 5, 33,100,116,157,251, 14,
+114, 65, 20, 10,209,178,229,255,188,237,119, 63,228,227, 92, 66, 31, 92,185, 56, 4, 59,119,103,215,124,223,172, 89, 51,228,228,
+164, 2,160, 87, 26, 72,227,175,131, 7, 15,198,222,189,123,161, 82,169,160,209,104, 48,124,248,112, 84, 86, 86, 62, 95,253, 68,
+ 3, 66, 8, 8, 33,152, 87,221,150,175,178,178,210, 88,159,166, 66,161,248,246,141, 55,222, 88,184,127,255,254,192, 37, 43,246,
+152, 14,253,122,208,114,224,224,111,252,123, 31,172, 55, 29, 59,121,222,114,228,212, 69,254,249, 49, 51,204,191, 28,185,196,191,
+ 57,117,177,105,201,146, 37,248,234,171,175,188,100, 50,217,199,245,233, 22,167,124, 81,145,124,243,242,202, 21,107, 54,176, 10,
+ 57, 85,222,201,183, 20,159, 74,214,103,217, 41,137,172,117, 19,106,247,175, 57, 31,221,206,206,185, 62, 7,233,191,220,180,177,
+112, 65, 97, 97, 33, 10, 10, 10,144,145,145,129,252,252,124, 20, 20, 20,128, 82, 10, 10, 79, 7,214,204,143, 6,203,236, 16, 44,
+ 70,163,133, 35,173, 1,154, 42,136,102,211,220,185, 16,235, 17,189, 92, 89, 86, 14,198, 64, 33,158, 79,131, 73, 84,161,212,196,
+161,196,200,162,220, 32,160,140,200, 81,206, 40, 81,212, 45, 10, 70,129, 69, 89,105, 25, 8, 33, 23,165, 91,136,132,132, 68,125,
+ 70,104,225,194,133,159,252, 81,218,214,207,209,209,209,151,107,109, 75,253, 40, 17,172,168, 90,245,158, 81,247,175,116,229,202,
+149,220, 1,253,159,241, 92,241,229,177,150,102,147,192,239,250,229,144,217, 98,182,215, 95,189,150,210,168, 6, 61,102, 81, 60,
+152,152,144, 48,160,123,183,110,202,180,115,231, 96, 41, 46,134, 80, 92, 12,153,217, 12, 78,167, 3, 99, 52,130,213,235,209, 44,
+ 88, 3, 80, 47,156, 77,201,226,205,130,112,184, 65,147, 97, 53, 88, 44, 91, 99,174, 24, 74,193,216,219, 87, 85, 13, 58, 56, 52,
+202, 92, 53,105,210, 68, 51,112,224,192,168,144,144, 16, 80, 74,177,120,241, 98,152,205,102,133,217,108,134,197, 98,129,217,108,
+ 70,121,121, 57,126,254,249,103,124,255,253,247, 49,142,142,142, 63, 52,108, 2,141, 7,143,156, 78,234,255,202,240,222,138, 67,
+199,214,195, 98,228, 81, 97,112,134,206, 96, 66,185, 94, 6,147,178, 31, 8, 57, 1,134, 85,162, 91,112, 0,142,158,186, 97, 16,
+ 45,230, 67,141,116,246, 48, 26,141,200,203,203, 71, 81,197,111, 64,105, 6,220,205,229,168,184,125, 11,193,175,188,218,160, 25,
+ 98, 24,104,190,254,232, 21,112, 28,135,159, 99, 42,192,113, 28,120,254,193, 99,158,178, 44, 11, 39, 39, 39, 84, 84, 84, 0,128,
+ 77, 46, 75,175,215, 99,211,166, 77,136,140,140, 68,175, 94,189,144,153,153,137,148,148, 20, 12, 26, 52,168,102,157,164,164, 36,
+156, 59,119, 14, 81, 81, 81,245,106,149,150,138,191, 22, 21,221, 28, 62,116,232, 80,121,108,108, 44, 40,165,104,221,218, 25,142,
+ 14,246, 32,140, 18,237,219,123, 0,184, 6, 66, 8,162,162,162, 96, 54,103,241, 58, 29,126,173, 79, 51, 33, 33, 97, 68,120,120,
+120, 11,158,231,147, 58,117,234,196,229,228,228, 96,228,200,145,216,188,121,179,245,137, 6,179,103,207,190, 55, 50, 89, 81, 81,
+175,193, 10, 13, 13, 13,158, 58,117,170,204, 90, 93,173,109,182,128, 55,155,205, 34, 0,180,235,220,243,127,227,199,245, 7,110,
+222,188,137,165, 75,151, 66,167,211,129,101, 89,121, 3,231, 61, 37,132,228,165, 19,187,237, 63,239,220, 59,126,200,179, 67, 57,
+139, 32,240, 29,253, 56,199,159,126,222,155,159,121,247,206, 42,220, 57,124,181,246,250, 13,232,153,178,179,179,237,213,106, 53,
+ 46, 94,188,104, 82,171,213,114, 47, 47, 47, 66, 41, 5,207,217,113, 34,131,235,160,244, 44, 17, 4, 57,203,114,163, 65,200, 9,
+194,178,245, 30,119, 1,248,237,230,149,171,189, 90, 53,109,205,148, 31,187,140,210,144, 30, 40,215, 1,186, 10, 2, 65,166,134,
+142, 83,162,162,101,107,148,187,121,129, 3,131,172,187,105, 22,158,210,195,210, 45, 68, 66,226, 31, 71,189, 30,228,254, 8, 86,
+215,174, 93,127,170, 29,101,178,126, 6, 96, 4, 80, 95,155,232,252,218,145,170,218,134,234, 65,219,185, 79,247,225, 12, 22,165,
+244, 56,234,169,138,243,245,245,237,254,238,187,239,118,126,243,205, 55, 81, 81, 81,129,239,190,251, 14,171, 86,173,130,175,175,
+111,247,187,119,239,158,178,117, 99,205,155, 55,255,113,247,161, 67,211, 58,183,109,219,186,121,243,230,184,118,243, 38,228,102,
+ 51, 56,158, 7, 91, 89, 9,153,197,136,230, 97,118,144,171,220,145,157, 86,137,159, 46, 95,190, 67, 41,173,119,224, 69, 11,195,
+192,212,191, 63,248,235,215,193,240, 60,228,189,123, 87,181,181,114,116, 4,179,107, 87,149,177, 18, 69, 96,238, 92, 80, 59, 59,
+136,207, 60,211, 96, 58,115,115,115, 43, 91,181,106,117, 46, 57, 57, 57,180,109,219,182,152, 63,127, 62,238,222,189, 11, 74, 41,
+242,242,242, 12,121,121,121, 89, 69, 69, 69,233, 12,195,236,206,204,204,252,214,150,145,194,115, 91, 51, 27, 15, 29, 58,252,110,
+ 88,112, 96,171, 62,189,230, 97,239,222,255,162,164,172, 12, 58, 35,135, 10,189, 25, 58, 3,133,214,161, 37, 34, 58,135, 32,191,
+208,132,235,151, 19, 51,243,229, 46,141, 26,116,146, 16,130,164,164, 36, 52,115, 5,174, 92, 75,128,187,177, 16,109,157,237, 17,
+210,189, 7, 82, 83, 83, 31, 24,245,250,157,201, 34, 0,207,243, 40, 43, 43, 67,183,182,109,145,155,155,139,194,194,194,123, 34,
+132,174,174,174,208,104, 52, 72, 72, 72,192,201,147, 39, 45, 12,195,252,215,134,228, 89, 76, 38, 83, 77, 85,229,225,195,135,209,
+187,119,111,244,236,217, 19,199,142, 29, 67, 66, 66, 2,206,157, 59, 7,134, 97,224,239,239,111, 29, 82,192, 82,151, 88,124,252,
+133,237,142,142,228,189,113,227,222, 9, 28, 59,118, 44,126,254,249, 39,188,254, 90, 27, 16, 70, 9, 66,148,120,110, 72, 59,124,
+248, 81, 2, 34, 34,162,224,238, 46,199,225, 95,200,149,199, 0, 0, 32, 0, 73, 68, 65, 84,195,151,211, 56,206,233,199,134,163,
+181,226,210, 69,139, 22,113, 42,149, 10, 38,147, 9, 21, 21, 21, 53,251,191,112,225, 66,204,153, 83, 85, 99, 57,119,238, 92,204,
+155, 55, 15, 6,131,161,222, 14, 14, 22,139,133, 50, 12, 67,238,222,189,107,214,104, 52,196,213,213,149, 83, 42,149, 48, 26,141,
+ 53, 70,235,230,205,155,216,187,119, 47, 50, 50, 50,224,234,234,202,184,184,184, 64, 16, 4,155,122,172, 20, 37,127,191,111, 55,
+193,224,238, 93, 35,252, 59,249,121, 43,138, 11,243,176,125,247,254,171,230,148,159,247,163,170, 90,208,166,217,220, 41,165,139,
+ 98, 99, 99, 63,166,148,114, 26,141,102,255,197,139, 23,251,232,116, 58, 13,165, 20, 68, 72, 45, 99, 76, 17, 63, 11,132, 99, 40,
+199, 14, 6, 65, 43,176,248,175, 92,161, 41,168,183,112,225,184,117, 31,108,220, 57,233,171, 53, 75,180,101,186, 82,232, 23,172,
+133, 57,241, 10,204, 10,123, 20,126, 20,141, 74,147, 8,125,113, 5, 28,190,250, 18,106, 47, 47, 28, 43, 79,201, 43, 45, 43,251,
+ 74,186,215, 72, 72,252,227,162, 82,245,122,144,218,230,200, 90,244, 1, 72,139,142,142, 46,168,213, 22, 43, 31, 64, 18,128,160,
+234,245,242,239,251, 95, 62,128,120, 0,225,181,116,242,107, 25,173,218,159, 77,247,173,147,244, 48,251, 69, 26,186,225, 90, 9,
+ 15, 15,175, 28, 61,122, 52,244,122, 61, 50, 50, 50,176,111,223, 62,100,101,101,105, 26,184,225,255,110,182,237,136,136,136, 0,
+ 23, 59,187,163, 83, 70,140,112, 81, 26,141,200,136,137,129, 57, 43, 11, 30, 45, 90, 64, 33,147,193,181,185, 55,202, 75, 13,248,
+234,242,229,178,212,178,178, 62,247, 15, 52, 90, 91, 51, 42, 42, 74,105, 54,155,243,119,239,222,205,150,148,148,128,225,121,176,
+195,135, 87, 69,173,156,156,192,110,216, 80, 85,165, 35, 8,192,178,101, 96,236,237,161,121,234, 41,244,154, 51, 7,137,137,137,
+154,250,210,217,180,105,211,166,126,126,126,113,191,252,242,139,115,102,102, 38,158,123,238,185,164,178,178,178, 1, 5, 5, 5,
+ 21, 54,154,157,223,105,122, 4, 61, 31,224,226,232,116,116,220,184,113, 46, 26,165,128,115, 87, 46,225, 78,177, 39, 76,102, 30,
+142,118, 10, 68,180, 85, 33,175,208,136, 95,247,239, 45, 49, 86, 22,245,187,127,160,209,218,154,161,161,161,149, 99,198,140,193,
+193,131, 7, 97, 50,153,170,123,247, 85,249,145,127,253,235, 95, 56,115,252, 24,202,211,110,161,107,143, 40, 12,124,101, 28, 94,
+127,253,117,196,198,198, 98,212,168, 81,184,114,229, 74,205,254,215,214,180, 78,149,195, 11, 12,242, 75, 21,194, 93, 93, 55,102,
+250,244,233, 36,251,194, 44,232, 43,114, 96, 52, 26, 33, 87,185, 35, 71, 24,133,253,251,247,211,194,194,194,237, 50,153,108,126,
+122,122,250,237,134,246,221,199,199,103,140,179,179,243,138, 62,125,250,168,170,163,132,184,120,241, 34, 40,165, 56,121,242, 36,
+ 0,192,207,207, 15,126,126,126,200,201,201, 65, 90, 90,154,222,108, 54,255, 43, 35, 35,227,199,186, 52,187,116,233,210,188,109,
+ 91,215,227,131, 7,143,112, 51,155, 45,232,251, 76, 57,120,190, 0,132,145,131,227, 60,113,242, 20, 65, 94,110, 17,206,196,196,
+ 20,223,186, 85,222, 47, 46, 46, 46,185,161,116,134,134,134,110, 25, 50,100,200, 96,149, 74,133,159,127,254,153,111,210,164, 9,
+231,236,236,140, 13, 27, 54,212,105,106, 41,165,117,158, 75, 90,173, 54,122,214,172, 89,111,141, 28, 57,146, 21, 4, 65, 40, 46,
+ 46, 22, 0, 16, 47, 47, 47, 54, 38, 38,198,178,123,247,110,232,245,122,248,248,248, 48,132, 16, 18, 31, 31, 47,166,164,164,196,
+ 17, 66, 62,200,200,200,184, 84, 87, 58,171,191,175, 26, 96,212,173,159,103,179,182, 1,235, 22,126, 56,215,253, 63, 31, 47, 44,
+ 77,185,120,229, 53, 20, 30,204,175,101,174,232,253, 17,172,186, 52,107, 93,167, 33,162, 40,238, 23, 69, 81,205,113, 92,203,184,
+184,184,188,208, 55,143,250, 11, 44, 29, 5,134, 38,243, 28,137,187,252,121,239,188,134, 52,195,195,195,195, 90, 54,111,182,239,
+157, 41, 83,236,202,242,203, 80,244,254,199, 40, 55,139, 40,124,111, 54,140, 60,133,219,143,235,193,169, 29,112, 76, 94,166,203,
+173, 40,253,221, 64,163, 13,165,243,161, 10, 61, 73, 83,210,148, 52,159, 72,205,191, 27, 54,205, 69, 88, 29,193,194, 91,111,189,
+133,242,242,114,252,244,211, 79,248,245,215, 95, 27, 29,193, 2,128,184,184,184, 91, 17, 17, 17,253, 62,222,176,225,199,193,109,
+219, 54,107,219,178,165,220, 53, 48, 16,106,141, 6, 37,133,133, 72, 74,203, 22,190,191,118,237,182,129,231, 95, 78, 76, 76,188,
+106, 67,196, 1, 60,207,195,201,201, 9,148,231, 33,155, 53, 11, 32, 4,148,101, 97,172,186,249, 65,164, 20,178,174, 93, 65, 89,
+ 22,165, 21, 54,249, 35,100,102,102,102,250,250,250,142,153, 60,121,242, 47,223,125,247, 29, 19, 21, 21,213,121,247,238,221,244,
+ 81, 50, 59, 63,233,231, 91, 94,193, 67,251,173, 88,177,106, 83, 72,120,132,111,243, 22, 45,148,221,125,157, 96,182, 8,200,205,
+ 43,196,241, 51, 87,141,215,175,156,207, 0,111,120, 57,247,210,158,122,247, 93, 46,151,167, 57, 59, 59, 55,159, 55,111, 30,120,
+158,135, 40,138,176, 88, 44,200,207,207,199,185,115,231, 16, 26,217, 21,237,198, 79, 64, 81, 81, 17,190,254,250,107,248,248,248,
+ 96,208,160, 65, 40, 41, 41,193,181,107,215,210, 30,164,249,225, 87, 66,147,218,203, 90,173, 54,120,252,248,241, 11,166,189, 80,
+222,227,189,241,227, 64, 41, 69,244,218,245,248, 97,231,247,167, 0,242, 65,118,118,246,249,134,246, 57, 32, 32, 64, 97, 52, 26,
+ 59, 83, 74,185,146,146,146,149,197,197,197, 99, 63,248,224, 3,175,207, 62,251, 12, 79, 61,245, 20, 50, 50, 50,144,154,154,138,
+182,109,219,162,180,180, 20,241,241,241, 66, 69, 69,197,122, 74,105,116, 78, 78, 78,189, 17,146,179,103,207,166,133,134,134, 62,
+157,155,179,250,199,183,223,234, 23, 96,177,132, 41, 28,157,122,128, 82, 30, 37,197,119, 65,232, 5,243,142,157,191,165,150,151,
+203, 95,180,117,170, 28,142,227,166,238,217,179, 7,168,158, 42, 39, 43, 43,235,178,181,106,249, 65, 17,172,134,200,202,202,154,
+227,235,235,123, 96,197,138, 21,179,199,143, 31, 31, 49,114,228, 72, 25,203,178, 98,102,102, 38,255,227,143, 63,146,214,173, 91,
+ 51, 74,165,146,196,196,196,136,151, 47, 95,142,165,148, 46,202,204,204, 60,105,227, 83, 31, 37,132,224,237,145, 45, 34,210,210,
+ 82, 10, 62,157,222,183,147,159,171,235,213,222, 35,252,187,148,149,141, 62,178,121,243,230,202, 7,153, 43, 27,175,211,115, 97,
+ 97, 97,253, 9, 33, 11,116, 58, 93, 37, 0,136, 10, 83, 57,163,103,182, 17,150, 53, 39,173,236,109, 83,243,128,248,248,248,132,
+240,240,240,193,179,102,206,218, 52,108,216, 11, 77,124, 95,123,137, 37, 23,174,193,172, 82, 64,121,253, 58, 24,123, 7,186,175,
+ 52, 53,183, 92,198,190, 24, 31, 31, 47,141,226, 46, 33, 33,241,183,193,230, 8,150, 86,171,173,244,243,243,131,171,171, 43,138,
+138,138,112,231,206,157,135,138, 96, 89,185,127,178,103, 66, 41,161, 54, 76,246,124, 95, 4,139, 51, 26,141,169, 22,139,165, 81,
+ 99, 84,200,100,178,252,216,216,216,230,182,164,179,105,211,166,163,124,124,124, 62,202,204,204,220,149,145,145, 49,235,113,184,
+123,235,100,207,224,228, 3, 65,197,142, 0, 8, 24,182,193,201,158,239,139, 96, 69,201,229,242, 47,204,102,115,243,251,215, 51,
+155,205, 40, 44, 44,132,209, 88, 85,109,172, 80, 40,224,230,230, 6,133, 66, 1,150,101,211, 4, 65,152, 98,157,139,208,150,167,
+144, 79,255, 37,171,156,254,250,120, 10, 0,139,191, 90, 71,110, 86, 82,215,111,191,165, 70, 91,246,253,246,237,219,173,236,237,
+237, 71, 18, 66,134, 3,104, 93, 81, 81, 97,252,207,127,254,115,225,216,177, 99,229,173, 90,181,234,219,175, 95, 63,114,245,234,
+ 85, 92,186,116,137, 22, 20, 20,236,224, 56,110,254,221,187,119, 83, 27,149,159,132, 48,221,186, 5,143,116,176, 39, 3, 68, 42,
+118,174,254,238,114, 69, 5,126,245,246,246,223,188,117,235, 86,225, 97,159,192,194,194,194,182, 87, 84, 84,244,191,126,253,250,
+ 67, 69,176,238,123, 80,233,161, 82,169,230,140, 29, 59,182,203,115,207, 61,199,196,197,197,225,196,137, 19, 66, 92, 92,220, 89,
+139,197,178,240,238,221,187, 39, 27,147,206,121,243,230,177, 37, 37, 37, 61, 69, 81, 28,218,162, 69,139, 32, 47, 47, 47,135,220,
+220,220,226,219,183,111,159,165,148,254,226,234,234, 26, 51,111,222,188,135,222,247,199,249, 68, 91,123,178,103, 78, 20, 59, 90,
+ 8,161,182, 76,246, 44, 69, 8, 36, 77, 73, 83,138, 96,253,237, 13, 86,117,134,254, 31,128, 15, 0,124, 66, 41, 93, 32,157, 40,
+255, 12,205, 79, 38,147, 34,150,169,106, 56,200,139, 48,243, 87,225, 62,247, 24,229,109,209,108,222,188,185,210, 98,177, 4, 1,
+104, 69, 8,113,162,148, 22, 91, 44,150, 67,121,121,121,121,222,222,222, 33, 0,172,173,198, 23,102,103,103,159,123, 18,243, 83,
+171,213,158, 49,153, 76, 45,141, 70,163, 92,175,215,203, 40,165, 53,109, 5,212,106,117, 65,101,101,165, 95, 99, 52,171,141,214,
+187,148, 82, 24,141,198,207,235, 50, 86,182,106, 78,158, 60,121,104,245, 58,254,132,144,107, 0,146, 43, 42, 42,142,110,216,176,
+ 65, 39,157,243,146,166,164, 41,105, 74, 6,235,175,129,107,204,202,213,166,106,129,148,109,255, 44, 62, 88, 73, 93, 31,246,191,
+105,105,105, 70, 0,177,213,175,123,168, 54, 84, 35,159,244,253,207,202,202,234,246, 56,245,170, 13,213,201,199,165,183,114,229,
+202, 93, 0,118, 73,103,170,132,132,132,196,147, 3, 35,101,129,132,132,132,132,132,132,132,196,227,133, 0,120,224, 16,215,141,
+ 9,253, 17, 66, 58, 54,118,195, 13,233, 75,154,146,166,164, 41,105, 74,154,146,166,164,249,247,211,108, 72,251,239, 82,245, 72,
+ 30,162,131,145,237,226, 82,253,180,164, 41,105, 74,154,146,166,164, 41,105, 74,154,255, 64,164, 42, 66, 9, 9, 9, 9, 9, 9,
+ 9, 9,201, 96, 73, 72, 72, 72, 72, 72, 72, 72, 72, 6, 75, 66, 66, 66, 66, 66, 66, 66, 66, 50, 88, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18,146,193,146,144,144,144,144,144,144,144,120, 98,248, 67,123, 17, 74, 72, 72, 72, 72, 72, 72, 72,252, 19,145, 34, 88, 18,
+ 18, 18, 18, 18, 18, 18, 18,127,132,193, 34,132,208,218,239, 18, 18, 18, 18, 18, 18, 18, 18,127, 6,127, 87, 15, 34, 69,176, 36,
+ 36, 36, 36, 36, 36, 36, 36, 36,131, 37, 33, 33, 33, 33, 33, 33, 33,241,255,135,193,138,170, 14,205, 69, 73, 89, 34, 33, 33, 33,
+ 33, 33, 33,241, 39,242,183,244, 32, 53,189, 8, 9, 33,148, 82, 74,164,227, 44, 33, 33, 33, 33, 33, 33,241,167,154,145,191,161,
+ 7,145,134,105,144,144,144,144,144,144,144,144,120,204,252,161,109,176, 8, 33, 29, 37, 77, 73, 83,210,148, 52, 37, 77, 73, 83,
+210,148, 52, 37,131, 37, 33, 33, 33, 33, 33, 33, 33, 33, 33, 25, 44, 9, 9, 9, 9, 9, 9, 9, 9,201, 96, 73, 72, 72, 72, 72,
+ 72, 72, 72, 72, 6, 75, 66, 66, 66, 66, 66, 66, 66, 66, 66, 50, 88, 18, 18, 18, 18, 18, 18, 18, 18,127, 17, 4,192, 3,123, 2,
+ 80, 74, 47,217, 44,242, 16,189, 9, 26,210,151, 52, 37, 77, 73, 83,210,148, 52, 37, 77, 73,243,239,167,217,144,118, 99,252,199,
+ 19,109,176,254,200,113,176, 8, 33, 29, 31,119, 70, 73,154,146,166,164, 41,105, 74,154,146,166,164,249,247,211,252,187, 33, 85,
+ 17, 74, 72, 72, 72, 72, 72, 72, 72, 72, 6,235,175,135, 16, 50,134, 16,178,139, 16, 18, 79, 8,217, 77, 8, 25,243, 8, 90,106,
+ 66,200,140, 90,122, 59, 9, 33,211, 8, 33, 74, 41,167,159,232,115,128,149,114,225, 47,205,127,226,227,227, 19, 16, 26, 26, 42,
+251,163,182, 17, 26, 26, 42,243,245,245,245,255, 35,183,241, 56,209,106,181,109, 2, 3, 3, 19,181, 90,109, 27,233, 12,145,144,
+248,235,225,234,250,161, 75,151, 46,215, 5, 65,240,105,140,152, 66,161,200, 56,115,230, 76,157, 23,119,120,120,248,117, 81, 20,
+127,167, 41,147,201, 68,139,197,242, 64,179, 39,147,201,242, 99, 99, 99,155, 63, 65, 5,251,215, 46, 46, 46,150, 85,171, 86,173,
+ 13, 14, 14, 14, 40, 46, 46,214,189,249,230,155,125, 8, 33,189, 41,165,227, 27,169, 21, 72, 8, 89, 31, 30, 30,190,107,234,212,
+169,219,219,180,105,227,160,215,235, 21, 91,182,108,105,178,122,245,234, 67,132,144,183, 40,165,201,210,105,250, 68,221,196,130,
+ 40,165,159,181,110,221, 58, 68,171,213, 38, 18, 66,166,101,102,102, 94,148,114,230, 79,203,127, 95, 0, 19,218,183,111,255, 98,
+219,182,109,189, 83, 83, 83, 77,222,222,222,191, 80, 74,167,231,228,228, 20, 60,142,109,248,248,248,184,136,162,248,153,167,167,
+231,144, 46, 93,186, 40, 82, 82, 82, 76, 90,173,118, 15,195, 48,211, 51, 50, 50,138,159, 84,115, 21, 17, 17,113,234,147, 79, 62,
+113,155, 51,103,206, 41,173, 86,219, 61, 43, 43,235,186,116,198, 72, 52, 68,243,230,205,157,202,203,203, 87, 49, 12, 19,164, 82,
+169,154, 56, 56, 56,192,222,222, 62, 87,169, 84, 94,112,114,114,122,123,231,206,157,165, 82, 46, 61,102,131, 69, 41,245,250,237,
+183,223,224,232,232, 8, 65, 16, 32,138, 34, 68, 81, 4,165,180,230,189, 54,102,179, 25,253,251,247,247,170,111, 99,148, 82,239,
+163, 71,143,194,193,193,225,158,255,117,237,218,149, 57,117,234, 20, 84, 42,213, 61,235,155, 76, 38,116,235,214,205,227, 9, 50,
+ 87,163,221,220,220, 76,119,238,164, 71, 24, 76,230,136,119,222,155,255,241,232, 33, 79, 59,198,196,196, 48,131, 7, 15,150, 17,
+ 66,198, 80, 74,127,180, 81, 75, 77, 8, 89,253,193, 7, 31, 44,149, 43,237, 61,182,238, 59,201,101,173,250, 33,163,115,160, 63,
+121,119,202,219,154, 41, 83,166, 36,180,107,215,110, 13, 33,164, 47,165,212, 40,157,170, 79,196,241,231,124,125,125,183, 68, 71,
+ 71,107,115,179,179,177,116,217,178, 46,162, 40,126,142,191,217, 12,240, 79,114,254,251,248,248,108,137,142,142,238,248,194, 11,
+ 47,128,101, 89, 24, 12, 6,197,246,237,219,135,127,252,241,199, 79,249,248,248,132, 60,170, 1, 10, 8, 8,112, 80, 42,149,241,
+209,209,209, 94, 35, 70,140, 0, 0, 84, 86, 86, 42,182,110,221, 58,242,147, 79, 62,121, 42, 32, 32, 32,248,214,173, 91,229,143,
+176, 15,140,155,155,219, 84, 0, 79,139,162,168, 4, 16, 87, 92, 92,252, 49,165,212,252, 40,233,118,113,113,217,184,100,201, 18,
+ 55,165, 82,137,111,191,253,214,237,133, 23, 94, 56,169,213,106,123, 72, 38, 75,162, 62, 60, 60, 60,198,149,149,149, 45,211,104,
+ 52,114,103,103,103,168,213,106,200,229,114, 40, 20, 10, 95, 23, 23, 23, 95,123,123,251,254, 47,189,244,210,180, 77,155, 54,109,
+144,114,235, 49, 26, 44, 0,208,104, 52,248,233,167,159,192,113, 28,228,114, 57,100, 50, 25,100, 50, 25, 20, 10, 5, 56,142,171,
+ 89,150,203,229,240,241,177, 61,216,181,123,247,110, 56, 57, 57,193,209,209, 17,237,219,183, 7, 0, 40,149, 74, 28, 62,124, 24,
+114,185,188, 70, 59, 44, 44,236, 79,207,144, 81,125, 72, 37, 0,108,253,188, 93,213,242,187, 85, 1,164,173,159,183,195,224,158,
+118,120,118,204,130,151, 42, 77,150,167,168, 72, 12,217, 69, 98,209,130,101,107,175, 6, 5,182, 37, 91,183,110, 13,118,119,119,
+127, 1,192,143, 54,110,234,157, 46, 93,186,236, 19, 24,149,231, 43,227, 94, 27,251, 26, 67,248,225,227,102,124,114, 58,233,122,
+201,250,192,144,205, 5, 5,153, 19, 86,172, 88,113,115,210,164, 73,111, 3, 88,102,107,250,107, 71, 9, 89,150, 45, 84,171,213,
+254,199,142, 29,227,159,128,155,163, 55,128, 5, 0,120, 0, 75, 41,165,215,107,253,214, 74, 46,151, 47, 48,155,205,197, 0, 62,
+166,148,102, 60,137, 23,139,143,143, 79,155,151, 95,126,217,173, 48, 63, 31, 75,151, 45,179,166, 61,132, 16,194, 82, 74,133, 63,
+ 51, 45,225,225,225, 45, 20, 10,197, 2, 0, 65, 70,163, 81, 91,125,189,102,137,162,184, 91,175,215,207, 79, 76, 76,212, 63,228,
+113,242, 1,208, 30, 85, 61,140, 31,248,156, 20, 29, 29,125,115,246,236,217,183,255,108, 77,173, 86,251,175,167,159,126,186,227,
+152, 49, 99,112,232,208, 33, 28, 61,122, 20, 65, 65, 65,232,219,183, 47,238,220,185,227,177,102,205,154, 49, 0, 86, 62, 74,190,
+ 26,141,198, 81,211,166, 77,243, 26, 49, 98, 4,246,236,217,131,163, 71,143,162, 91,183,110, 24, 52,104, 16,210,210,210,188, 54,
+108,216, 48, 10,192,250, 70,230,169, 18,192, 84, 0, 79,179, 44,219, 99,220,184,113,252,148, 41, 83,100, 12,195, 88, 62,255,252,
+115,143,245,235,215,143,118,119,119, 15, 41, 40, 40,168,120,216,116, 23, 23, 23,127,252,209, 71, 31,125,183,114,229, 74,135,148,
+148, 20,204,159, 63,223,125,242,228,201,199,181, 90,109, 47,201,100,213, 13,203,178,165,162, 40,202, 0,184, 82, 74,141, 13, 45,
+255,157,246,221,221,221,253,141,162,162,162,207,181, 90, 45, 60, 60, 60, 64, 72,213,229, 41,138, 34,116, 58, 29,244,122, 61,252,
+253,253,229,237,219,183,255,114,210,164, 73,178, 47,191,252,242, 43,233,140,105,100,121, 10,160, 23,165,244,120,173,194,160, 23,
+165,244,120,120,120,120,217,169, 83,167,184,189,123,247,130,101,217, 26, 35, 85,219, 84, 89, 63,203,100, 50,120,121,121,161, 79,
+159, 62,252,217,179,103, 29,235,218, 88,104,104,104,197,238,221,187,153,148,148, 20, 56, 58, 58,194,201,201, 9,222,222,222,232,
+218,181, 43, 98, 98, 98, 16, 27, 27,123,143,113,235,208,161, 3, 34, 34, 34,144,152,152,168,249,211,114,228,106,251, 74,180,191,
+170,169,163,160,188,112,245,234,213,175, 23,172, 59, 92,150, 87, 84,154,223,202, 89, 94, 57,166,123, 27,141,127, 83, 55,165, 87,
+100,247,207, 9, 33,249,148,210,112, 27, 11,221,157,223,127,255,253,142, 45,135,174,217,125,245,217,251, 19, 57,134,240,239,205,
+253,236,227,166,142, 44,223,132,229,117, 97, 3, 7, 58,118,232,208, 97,130,157,157,157, 64, 41, 29,102,107,242,195,194,194,202,
+126,253,245, 87,142,227, 56,244,233,211, 71,208,104, 52, 30,199,142, 29,251,203, 11, 6, 66,200,242,220,220,220, 9, 6,131, 1,
+ 97, 97, 97,229,133,133,133, 3, 40,165, 23, 8, 33, 29,134, 14, 29,122,120,235,214,173,246,231,206,157, 67,100,100,228,118, 74,
+233, 43, 79,210, 69,162,213,106,247, 0,232,205,178, 44, 70,143, 26,101,250,105,203, 22,133, 40,138, 85,206,128,210,248,236,236,
+236, 63, 53,130, 21, 26, 26,218, 70,165, 82, 29, 93,186,116,169, 67, 96, 96, 32,145,201,100,224,121, 30, 55,110,220,192,198,141,
+ 27, 13,103,207,158,205, 52, 24, 12, 97,137,137,137,150,135, 56, 78,253,143, 31, 63, 94, 25, 16, 16,240, 64,195,168,211,233,216,
+ 86,173, 90,249, 3,216,240,103,107, 54,109,218,180,169, 40,138,203,163,162,162,250,159, 56,113,226, 10,128,143, 40,165,239,110,
+220,184, 49,210,206,206, 14,207, 63,255,124,114,122,122,250, 35, 61,149,249,250,250,158,140,141,141, 13, 41, 47, 47, 71,239,222,
+189, 19, 57,142,251, 15,207,243, 31,109,219,182, 45,148, 97, 24,188,240,194, 11,231,238,222,189,219,163, 17,251, 30,168, 84, 42,
+ 55,252,248,227,143,246, 45, 91,182,108, 41,151,203,153,150, 45, 91,162,168,168, 8, 6,131, 1,158,158,158, 88,176, 96, 65,210,
+242,229,203,211,202,203,203, 71, 60,228,249,217,166, 75,151, 46,167, 62,252,240, 67,183,171, 87,175,162,117,235,214,200,207,207,
+ 71,106,106, 42, 86,172, 88,145, 91, 94, 94, 30,245, 87,153, 44, 66, 72, 14, 0, 7, 0,222,148,210,178,199,164,167,176, 46,203,
+100, 50, 40,149, 74, 40,149, 74,168,213,106,164,166,166,238, 98, 89,246, 77, 0, 54,157,251, 28,199,149, 9,130,192, 1,120, 26,
+ 64, 2,203,178, 37,245, 45, 83, 74,197, 39,160, 44,109,202, 48,204,167,148,210, 94, 0, 24, 66,200, 73, 79, 79,207,153,217,217,
+217,233,182,106, 52,109,218,212,181,160,160, 32,213,195,195, 67,230,233,233,105, 53,155, 8, 11, 11,131,193, 96,192,229,203,151,
+ 97, 45,227, 66, 67, 67,209,169, 83, 39, 75,105,105,169,255,156, 57,115,138,254,128,253,121,160, 7,249, 59, 24, 44, 6,192, 49,
+235, 78, 85,127,119,204,250,163, 32, 8,247,152,168,218,175,218, 70, 72, 38,147,129, 97,108,106, 47, 79, 76, 38, 83,141,185,114,
+116,116,132, 76, 86,213,126,148,231,249,223,105, 10,194,195, 7, 5, 92, 92, 92,118, 19, 66,158,121,204,249,149,146,159,159,111,
+ 30,210,163,181, 82, 86,150, 95,244,202, 83,173,156, 58, 5, 52, 13,244,244,105, 54, 66,167,211, 37, 2,200,105, 76,185,216,190,
+125,123,135,130,188,156,194,151,254,181, 56,122,230, 39,171, 23,134,183,106,234,208,163,109, 11,175,110,157,219, 53,119,183, 88,
+ 24,141, 70,211, 30,128,182,177,137,116,114,114,194,145, 35, 71,158,180,115,205, 89,175,215,163,168,168, 8,107,214,172,113,112,
+115,115, 59, 64, 8,121,105,232,208,161,191,109,219,182,205,190,180,180, 20,102,179, 25, 0, 12, 79,224,117,178,208,197,197,197,
+ 52,108,216, 48,252,184,121,179, 66, 20, 69, 29, 0, 29,128, 28, 66,200,244, 63, 59, 49, 74,165,242,221,143, 63,254,216, 33, 48,
+ 48,144, 20, 20, 20, 32, 43, 43, 11, 5, 5, 5,112,119,119,199,123,239,189,167,106,213,170,149, 86,169, 84,206,124,216,242,174,
+ 46, 35, 4, 0,118,118,118, 2, 26,223, 57,230,129,154, 60,207,147,200,200,200,105,157, 59,119,254,202, 22,205,204,204,204,204,
+236,236,236, 17, 39, 78,156, 24, 39, 8,194,107,153,153,153,251, 0, 44,223,189,123, 55,156,157,157,209,190,125,251,118, 62, 62,
+ 62, 1,143, 96,164,125,194,194,194, 66,188,189,189,177,117,235, 86, 48, 12,179,242,238,221,187, 39, 25,134, 89,185,103,207, 30,
+120,120,120,160, 93,187,118, 33, 90,173,214,166,112, 61, 33, 68,169, 84, 42, 55,220,188,121,179,237,144, 33, 67, 90,149,149,149,
+ 49, 90,173, 22,214, 99,150,158,158,142, 11, 23, 46, 96,252,248,241,158,130, 32,116,179,213, 76,245,234,213,235,238,200,145, 35,
+ 11,159,127,254,249,194, 17, 35, 70, 20, 14, 30, 60,248,236,183,223,126,235,102, 45, 71,231,204,153,131,148,148, 20, 56, 59, 59,
+227,181,215, 94,107,162, 86,171, 55, 62, 1,215, 80,182, 76, 38,171,116,113,113,113,124, 68, 29,133,245,197,113,156, 66,161, 80,
+ 40, 84, 42,149, 66,165, 82, 41,148, 74,165,226,111, 31, 17, 33, 68, 75, 8, 73,228, 56,110,128,179,179,179,163,171,171,171,189,
+175,175,111,159,150, 45, 91,198,191,246,218,107,126,182,234,232,245,250,245,106,181, 90,230,225, 81,213, 2,167, 95,191,126,216,
+184,113, 35, 70,143, 30, 45,246,235,215, 79, 28, 53,106, 20,154, 52,105, 2, 0, 72, 74, 74,130, 66,161,144,217,219,219,175,255,
+131,118,171, 78, 15,242,255, 59,220,125, 59,121, 79, 8, 95, 20,197,154,232,213,131, 76, 85,237,151,173, 8,130, 0, 47, 47, 47,
+104, 52, 26,104, 52,154,123,182,117,191,230,163,140,209,213,170, 85,171, 94, 26,141,166, 27, 33,100, 20,165,244,168,173,255, 27,
+245,110, 50,182, 30,174,243,231,189,239,190,251,110,255,152,152, 24, 99, 68,199,150,162, 42,235,110,145,198,197,163, 35,227,238,
+209,123,210,196, 55,227, 0,108,105, 76,129,163,215,235, 21, 45,188, 89,125,102,105,133,169,133,157,147,115,115, 7,181,166,133,
+135,147,171,179, 74,201,216, 53,245,244,182, 88, 44,165, 0,178, 27, 18,170, 93, 45,168, 82,169, 76,132, 16,206,217,217, 25, 78,
+ 78, 78,230,226,226,226,162,208,208, 80, 40, 20,138, 66,185, 92,110,115,117, 97,151, 46, 93,210, 4, 65,168,183,253,155, 92, 46,
+207,143,137,137,177,181, 3,194,252,160,160,160, 30,171, 86,173,114,111,221,186, 53,214,172, 89,227,176,109,219,182,117, 27, 55,
+110, 68, 73, 73, 9,110,223,190,141,215, 95,127,189, 28,141,168, 14,253,179,112,117,117, 61, 60,114,228, 72,172, 95,191,158, 82,
+ 74, 9, 0, 59,134, 97, 34, 28, 29, 29,111, 92,185,114,197,252, 23, 20,178,125,218,182,109, 75, 74, 75, 75, 65, 41, 5,203,178,
+247,188,102,206,156,169, 30, 63,126,252,172,110,221,186,189, 43,147,201,202,121,158,223, 86, 89, 89,185, 40, 41, 41,233,137,106,
+172,218,179,103,207,201,119,239,222, 29,232,231,231,247, 75, 99,254,151,153,153,185,205,250,153, 82,122, 41, 39,167,234,185, 70,
+173, 86, 3,128,234, 17,242, 85,229,228,228, 4, 0,184,123,247, 46, 0, 88, 59, 47, 92,204,202,202, 2, 0,216,219,219,131, 16,
+ 98,235, 54,166,110,221,186,213,193,219,219, 91,173,215,235,145,146,146,130,208,208, 80,148,151,151, 67,167,211,161,178,178, 18,
+102,179, 25,165,165,165,206,130, 32,152,108, 60, 23, 55,126,249,229,151, 62,237,218,181, 3,207,243,176, 88, 44,160,148,226,248,
+241,227,208,233,116,176, 88, 44,104,219,182, 45, 22, 46, 92,104,152, 52,105,146,106,203,150, 45,121,122,189,126,236, 95,125,172,
+ 89,150,133, 82,169, 4,199,113,217,205,154, 53, 3,195, 48,174,105,105,105, 15, 19, 89,247, 2,144,195,113,156, 66,169, 84, 66,
+165, 82,193,250,126,249,242,229,109,141,137, 94, 85,159, 63,180, 49,203,127,121, 68,132, 97, 62,229, 56, 78,225,230,230, 38,183,
+126,103, 54,155,229, 46, 46, 46,240,245,245,253, 12,192,112, 27,165, 58,187,187,187,131, 16, 2,185, 92,142, 55,222,120, 3,241,
+241,241,187,239,222,189,251, 70, 94, 94, 30, 42, 42, 42,190,114,116,116,124, 46, 47, 47, 15,130, 32, 32, 45, 45, 13, 65, 65, 65,
+157,255,224,221,251,157, 7,249, 91, 24, 44,171,115,172,229, 32,235, 52, 61,181, 77, 86,237,207, 54, 94,100,226,139, 47,190,248,
+192,238,237, 60,207,223,211,254,234, 81, 13,150, 82,169,196,160, 65,131, 84, 26,141,102,115,181,201,122,232,144, 99, 59,111, 85,
+ 51, 14,178,239,158,237,221,179,243,196,119,223,147,245,238,221,251,151,157, 59,119, 6,121,244,124,122,192,137,223, 54,123,174,
+157,189,231,151,159,126,250,169,194,214, 6,238,213,196,108,223,190,221,235,189, 41,111,203,163,162,162,118,142, 11,154,193,105,
+149,130,189,179, 66,206,218,177, 44,163,244,105,222,247,183,227, 39,114, 0,156,178,161,144,240, 58,124,248, 48,156,157,157, 1,
+ 64, 97, 50,153,224,236,236,140, 53,107,214,168, 28, 29, 29,225,232,232,136,110,221,186, 57,203,229,114, 14, 85,109,160,108, 49,
+194, 30,199,143, 31,135,157,157, 29,116, 58, 29,140, 70, 35,120,158, 7,165, 20, 28,199, 65,165, 82,161, 87,175, 94, 30,141, 40,
+200, 82, 9, 33,125,223,121,231,157, 67,171, 86,173,114, 15, 8, 8,192,252,249,243, 81, 88, 88,136,244,244,116,140, 29, 59,182,
+ 60, 53, 53,117, 64,237,182, 89, 79, 2,157, 58,117,170, 60,125,250, 52,246,239,223,143, 33, 67,134,144,221,187,119,155, 5, 65,
+144,103,100,100, 92,254,171,210, 36, 8,130,189, 66,161,128,197, 98, 1,199,113, 96, 89,182,230,157,101, 89, 52,109,218, 20,135,
+ 14, 29,226, 42, 43, 43,185,194,194, 66,205,215, 95,127,253, 86, 66, 66, 66, 19, 0,175,253,149,121,185,102,205, 26,223, 9, 19,
+ 38,100,112, 28, 71, 7, 14, 28,248,226,157, 59,119,134,120,123,123, 31, 59,114,228,200, 10, 0,173, 26,171,215,173, 91,183, 52,
+ 79, 79, 79,143,188,188, 60,252,240,195, 15,200,203,203,131,155,155, 91,108,104,104,232,189,133, 28,199,229,199,197,197, 53,248,
+ 32,224,227,227,115, 56, 59, 59, 27, 43, 87,174, 68,118,118, 54, 60, 60, 60,146, 66, 67, 67,225,225,225,129,188,188, 60,108,218,
+180, 9, 69, 69, 69,240,246,246, 62, 12,160,153, 13, 73,140,138,136,136,240, 43, 41, 41,129,147,147, 19, 42, 42, 42,144,144,144,
+128,192,192, 64,100,101,101,129, 97, 24, 56, 59, 59, 99,245,234,213,149,132, 16,155,170, 94,138,138,138,198,190,242,202, 43,199,
+246,236,217,211,196,203,203, 11,249,249,249,208,235,245,240,243,243,195,138, 21, 43,208,172, 89, 51, 28, 62,124,184, 72, 16,132,
+ 9,235,215,175,255,183, 94,175, 31,251, 87,183,193, 98, 24,166,166, 26,175,150, 41, 42,138,140,140,196,233,211,167,183, 52,198,
+ 20, 81, 74, 77,214,106, 65,149, 74, 85,243, 82, 42,149, 96, 24, 70,124,136,107,201,137, 16,210,217,122, 99,111,104,249,175,134,
+ 82,218,195,206,206, 78,126,255,247,197,197,197,242, 54,109,218,116,179, 85, 71,165, 82,185, 86, 63,144,160, 87,175, 94,200,203,
+203, 19,252,253,253, 95, 29, 53,106,148, 5, 0,222,124,243,205, 87,243,242,242,138, 44, 22, 11,203,113, 28,242,243,243,209,178,
+101, 75,215, 63,240,161,241,129, 30,228,255,123,131, 69, 41, 37,132, 16, 90,251,189,214,193,108, 48,114,101,253,205,150, 42, 66,
+ 81, 20,105, 29,189, 8,107,204,220,227, 52, 88,206,206,206, 24, 51,102,140, 38, 51, 51,115,157,173, 5,184,181,113,123,109,115,
+165,117,107,114,100,209, 39,243,189,110,237,255, 6, 95, 45, 95,204,199,197,197,237,246,242,242, 26, 6,160,220,203, 13,158, 57,
+133,216, 65, 41,221,220,136,147,137, 1,240,115,108,108,108, 76,255,254,253,227,110,223,190,237,156,122,243,102,140,131,190, 84,
+231,224,215,146,151,123,120, 62,171, 55, 91,184,231,159,127, 94, 9, 96,181, 13,122, 16, 69, 17,251,246,237,131,131,131, 3, 28,
+ 29, 29,225,236,236, 12,171,185,122, 88, 82, 82, 82,144,145,145, 1, 59, 59, 59,216,217,217,193,222,222, 30,246,246,246, 80, 40,
+ 20,214,104, 65, 99, 11,135,155,132,144,153,219,183,111,223,240,201, 39,159,160,164,164, 4,149,149,149,152, 59,119, 46, 82, 82,
+ 82,102, 82, 74, 47, 60, 73, 23, 71,231,206,157, 43, 99, 98, 98,112,234,212, 41,232,116, 58,172, 92,185, 18,222,222,222,131, 0,
+204,254, 43,211, 37, 8,130,156,101, 89, 48, 12, 3,134, 97,126, 23,193,178,154, 45,181, 90, 13,119,119,119,204,153, 51, 71, 62,
+116,232,208,129,127,101,154, 63,253,244,211,150,203,151, 47, 95,189, 97,195,134,131, 47,191,252,242,207,151, 46, 93,122,217,209,
+209,241,242,225,195,135, 23, 41,149,202,135,106,215, 98, 50,153, 60,146,146,146,254, 23, 34,157, 63, 31,130, 32, 64, 16,132,154,
+232, 78,101,101, 37,134, 12, 25, 98,211,131,128,197, 98,113, 59,112,224, 0, 0, 96,202,148, 41, 53, 15,153,181,245, 38, 78,156,
+136,193,131, 7,187,217,152, 68,173,139,139,139, 44, 61, 61, 29, 60,207, 35, 36, 36, 4,171, 87,175,198, 11, 47,188,128, 14, 29,
+ 58,160,188,188, 28, 87,174, 92,193,134, 13, 27, 92,228,114,249,243,182, 8,102,101,101, 93,215,106,181, 81,131, 6, 13, 58,185,
+ 99,199, 14,247,102,205,154,225,194,133, 11,200,206,206, 70,135, 14, 29,176,112,225, 66, 29,165,244,169,106, 83,181,235, 9,136,
+184,220, 99,132,212,106,245, 61,230,232, 97,224,121,222, 75,169, 84,230, 84, 87, 13, 66,169, 84, 34, 33, 33,161,209,209,171, 90,
+229,210,133,198, 44,255,149, 88,203, 97,139,197,242,187,239, 91,183,110,109,179,142,189,189, 61,177,222, 99, 45, 22, 11,178,179,
+179,133, 75,151, 46, 9, 33, 33, 33, 0, 0,111,111,111, 33, 54, 54, 86, 48, 26,141,172,245,126,237,228,228,244,135,152,204,250,
+ 60,200,223, 34,130, 5,224,196,125,239, 53,133,139,213,240,212, 21,185,178, 46,219,216, 6, 11, 28,199, 97,251,246,237, 53,237,
+176, 58,119,238, 92, 99,230,238,215,181,246,106,120, 24, 20, 10, 5,156,156,156,112,240,224, 65, 67, 82, 82,210,164,135,141, 92,
+105,221,154, 28, 89,186, 56,218,171,240,106, 12, 50,178,114,113,243,114,198, 17, 74,233, 38, 0,155, 0, 88, 27,197,219,108,174,
+ 2, 61,237, 58, 69,182,246,218,242,116,223, 1,218, 97,175,190,195, 76,154, 52, 41,226,213, 87, 95, 45,126,245,213, 87,223, 86,
+169, 84,129,130, 32, 20,255,118,252,120,250,243,207, 63,239, 90, 86, 86, 54,145, 82,170,183,161, 16,203,233,215,175,159, 15, 0,
+ 56, 56, 56,152,190,249,230, 27,133,179,179, 51, 94,122,233, 37, 67, 78, 78,142,170, 58, 63, 74,108,141, 94, 89,159,250, 39, 76,
+152,224,209, 64, 30,231, 55,242, 41,165,243,179,207, 62,187,114,243,230,205, 40, 44, 44, 68,101,101, 37,228,114, 57, 22, 47, 94,
+140,187,119,239, 46, 33,132, 92,121, 82, 10,179,160,160,160,202,184,184, 56, 92,188,120, 17, 70,163, 17,111,188,241, 6, 40,165,
+214, 58,237, 33,127,113,242, 72, 70, 70, 6,126,248,225, 7, 8,130,128,177, 99,199,162,121,243,230, 53, 6, 43, 39, 39, 7,223,
+124,243, 13, 4, 65,192,132, 9, 19,208,172, 89, 51, 88, 44, 22, 85, 84, 84, 20,247, 87,245, 40,157, 62,125,122,234,142, 29, 59,
+ 14,102,100,100,244, 91,180,104, 81,119, 66,136, 56,115,230,204,165, 78, 78, 78,143,212,251,178,184,180, 28,215,110,222, 1,207,
+243, 15,124,121,184,187, 54, 90,239, 70, 74, 58,120,190,202, 84,241, 2, 15,129,231,171,151, 45,112,115,109,148, 94,102, 81, 81,
+ 81,107,150,253,127,237,157,121, 92, 84, 85,255,199, 63,231,222,185,115,103, 31, 96, 8, 17, 68, 81,220, 23, 52, 89, 21,125,244,
+209, 52, 82,212,204,210, 39, 31, 75,109,251,169, 61, 46,143,230,146,102, 18, 21,104,174,105, 41, 60,105,101, 90,102,155,230,174,
+165, 86,138, 32, 66,106, 41, 34, 18,200, 42,187, 16, 12,179,221,153,243,251,131, 37, 52,209, 25,212, 28,237,190, 95, 47, 94, 51,
+115,239,240,153,115,207, 61,247,220,207,253,158,141,149,166,167,167,195,215,215, 23, 33, 33, 33,136,142,142, 70,113,113, 49, 4,
+ 65, 64,139, 22, 45,108, 22,139, 37,197,100, 50,253,104,175,104, 65, 65,129,190,125,251,246,134,231,158,123,142,190,247,222,123,
+ 68,171,213,226,210,165, 75,144, 72, 36,208,104, 52,250,212,212, 84,167,137, 2, 55,142, 92,201,100, 50,240, 60, 15,153, 76, 86,
+ 31,185, 34, 0,246, 2,112,200, 96, 83, 74, 77,173, 91,183,110,136, 92, 53, 55,122,117,183,184,155, 35, 19,187,116,233,242,147,
+ 90,173, 30,118,225,194,133,107,162, 88,227,199,143, 55,119,232,208, 33,222, 94, 29,141, 70,115,149,231,121,157,193, 96,192,137,
+ 19, 39,208,181,107, 87,105, 69, 69, 69, 20, 33,100,113,221,195,101, 84, 97, 97,161,180, 85,171, 86,245,191,139,138,138,138,171,
+173, 91,183,190, 91,217,118, 67, 15,242, 64, 24,172,186,209, 8, 13,175,215, 71,176,110,213, 60,104,111, 4,139, 16,130,170,170,
+ 42,168,213,106,212, 77,102,134, 70,163,177,254,212, 68,120, 59, 6, 75, 46,151,227,200,145, 35,134,184,184,184, 9,148,210,239,
+236,253,191,198,125,176, 60, 31,242,216,185,242,157, 90,115,117,230,216, 33,124,113,250, 74, 62, 97,108,255,109,110,154,122,180,
+ 80,249,123,122,184, 31, 88,181, 98,169, 38, 47,113, 31,182,199,173,162,103, 78,158,236,127,242,228,201,209,211,166, 77,115, 67,
+109,127,171,124, 0,241, 0,214,219, 99,174, 0, 32, 49, 49,177, 97,114,215,144,144,144, 74,173, 86, 11,181, 90,141,226,226, 98,
+169, 90,173,214, 53,103, 20,161, 61, 77, 42, 14,154,171,142, 35, 71,142, 60,248,213, 87, 95,169,174, 94,189,138,172,172, 44,204,
+155, 55, 15,239,191,255, 62,180, 90, 45,118,239,222,173, 30, 49, 98,196, 1, 66,200,160,123, 61,185,106,239,222,189,245, 73, 73,
+ 73,200,204,204,132, 32, 8, 24, 61,122,116, 99,115,117,207,177,217,108,116,214,172, 89,248,224,131, 15,192, 48, 12, 38, 78,156,
+136,202,202, 63, 6,104,233,116,186, 27,237, 99,235,174,247,123, 98,176, 36, 18, 9,253,225,135, 31, 86, 13, 28, 56, 16,185,185,
+185,143, 6, 5, 5,109,152, 60,121,114,254,237,234,186,185,104,240,112,247,246, 48, 26,141, 48, 26,141,240,246,246, 70, 85, 85,
+ 21,210,211,211, 97, 52, 26,225,217,194,213, 97,189,222, 61, 58,194,100, 50,193,104, 52,162, 69,139, 22,168,174,174, 70,102,102,
+ 38,140, 70, 35, 60, 60,220, 28,145,251,225,216,177, 99,190, 67,134, 12,233,114,238,220, 57,252,248,227,143, 48,153, 76,232,221,
+187, 55, 46, 94,188,136,190,125,251,162,178,178, 50, 49, 41, 41,233, 91, 7,174,163,214,225,225,225, 71, 62,253,244, 83,247,173,
+ 91,183,154, 38, 77,154,196, 71, 71, 71, 19, 66, 8,170,171,171,225,100, 93,134,254,100,176,146,147,147,191,228, 56,142, 2,104,
+ 86,180,169,158,156,156, 28,183,158, 61,123,150,203,100, 50, 62, 62, 62,126,123,115,163, 87,119,229,233,231,143, 27, 87, 79, 66,
+200,169, 58, 35,217,228,103, 71, 70, 38,118,238,220,121,158,151,151,215,224,128,128, 0,156, 63,127, 94, 42,147,201,240,204, 51,
+207,152, 35, 34, 34,204, 44,203,218, 61,224, 70, 46,151,167,106, 52,154,254, 70,163, 17, 38,147, 9,223,127,255, 61,220,220,220,
+254, 59, 98,196,136,105, 5, 5, 5,200,207,207,231,235,140, 43, 24,134,193,160, 65,131, 80,213, 69, 54,191, 0, 0, 29,173, 73,
+ 68, 65, 84, 86, 86,118,215,234,229,166, 60,200,131, 18,193,106,234,160,237,106, 30,116,196, 12, 25, 12,134,134,166, 38,141, 70,
+211, 96,204, 8, 33,127,210,180, 55, 42,118, 35, 82, 82, 82, 18, 50, 50, 50,214, 82, 74, 15, 52,231,255, 59,121,186,180, 11,108,
+163,233,152,159,184, 23, 23,206,156,194,231, 41, 87,242,171, 5,243,144,212, 2, 67,118, 83,134,236,166,209, 48, 79,117,119,111,
+ 15,247, 3, 43, 87, 44,213,148,158, 63,129,244,179,167,176, 55, 49,239,103, 35,165,151, 0,188,115, 39, 79,106,115,154,239,238,
+ 54,114,185,252, 63, 95,126,249,165,234,234,213,171,200,200,200,192,132, 9, 19, 42,178,178,178,102, 61,241,196, 19,171,247,237,
+219,231,170,211,233,112,240,224, 65,117,235,214,173,163, 0, 60,121, 15, 43, 71,189,213,106, 69,105,105, 41, 0,160, 95,191,126,
+ 78,101,174, 0,224,212,169, 83, 46, 35, 71,142,220, 11, 96,224,249,243,231, 97,179,217, 18,146,147,147, 27, 70,204,222,108,159,
+ 61,254, 77,175,215, 75,148, 74,165,208, 68,217,226, 28,141, 56, 52,214, 60,126,252,248,202,149, 43, 87,126, 59,103,206,156,140,
+219,212,188, 97, 4,107,196,136, 17,168, 49,152,145, 91, 88, 1, 65, 16,160, 55, 21,222, 86, 4,171, 86,207,132,236,130,114, 8,
+130, 5, 85, 6,135, 2,110,107,199,143, 31,255,212,241,227,199,203,186,116,233,162, 75, 74, 74, 66, 81, 81, 17, 44, 22, 11, 6,
+ 15, 30, 12,153, 76,118, 57, 38, 38, 70, 10, 96,173,157,101, 83, 57,116,232,208, 3,219,182,109,107, 25, 31, 31, 15,147,201,100,
+203,205,205,205,156, 61,123,182,230, 63,255,249,207, 67, 44,235,124,171, 55,213, 71,172, 82, 83, 83,235,141,213, 75,119,202, 8,
+213, 71,176,254, 78,108,222,188, 57,127,227,198,141,129, 62, 62, 62,239, 60,251,236,179, 3,189,189,189, 25,158,231,127, 98, 89,
+118, 46, 0,187,167,105, 80, 40, 20, 83,220,220,220,126, 97, 89,150,205,203,203,195,197,139, 23,193,178, 44, 40,165,124, 77, 77,
+ 13, 60, 61, 61, 81, 95,158,198,143, 31, 15, 31, 31, 31,107,106,106,234, 20,136,220, 57,131, 5, 0,111,190,249, 38,118,253,246,
+ 27, 70,250,249,221,244,123, 95,127,253,245,141, 42,132, 63,173,182,109,177, 88, 16, 19, 19,211,240,249,219,111,191,109, 48, 88,
+211,166, 77,187,230,255,119,236,216, 97,151,230,141,184,116,233, 82,184, 3, 55,213, 6,205,250, 62, 88, 23, 11, 43, 50,123,121,
+107,143,127,252,237,247,253, 50,203, 12,153,122,193, 28,113,189,185,178, 87,179,135,151,186,139,183,135,238,224,202,229, 75,181,
+245,209,176,109, 41, 5,149,196, 74,167, 59,120,243,191,229,177,115, 28,119, 37, 44, 44,204,167,174,114,187,101,179,224, 95,181,
+202,186,193, 96, 64, 66, 66, 2, 0,224,249,231,159,175,200,202,202, 26, 74, 41, 61, 79, 8, 73, 29, 62,124,248,193,189,123,247,
+214,135, 26,202,238,101, 58,129,218,145,174, 18,137, 4,157, 59,119,118,216, 92,253, 85,233, 44, 44, 44,156, 62,101,202,148,117,
+ 70,163,145, 53, 24, 12,211,237,221,119,171,116,126,254,249,231, 25, 29, 58,116,232,143,166,167, 77,176, 1, 72,188, 29,205,119,
+223,125, 23, 0, 58,221,142,102, 83, 17,172,207, 63,255, 28, 54,155, 13, 62,158, 46, 48, 26,141, 80,169, 84, 14,105, 94, 31,193,
+218,190,125, 59,108, 54, 27,218,120,185,193,104, 52, 94, 51,242,249, 86,154,148, 82, 35, 33,100,114, 88, 88,216, 39,111,189,245,
+214,111, 93,187,118,109, 29, 22, 22,230, 86, 86, 86, 86,244,243,207, 63,103,197,197,197,169, 5, 65,152,220, 84, 51,209,245,154,
+238,238,238,171, 54,111,222,236,115,254,252,121,228,229,229, 97,245,234,213,151,139,139,139,135, 75, 36, 18,217,218,181,107,143,
+ 70, 68, 68,120, 10,130, 96,116,134,242, 89, 79, 65, 65,193,158,186,251,140, 67,198,202,158,116, 38, 38, 38,126, 93,167,125,192,
+ 30,237,191,234,216,111,119,100,226,173,210,249,194, 11, 47,228, 1, 24,127, 59,233,220,191,127,255,229,167,159,126,122,169,191,
+191,255, 34,181, 90,141,180,180,180,134,105,145,234, 31,208, 9, 33, 24, 59,118, 44,166, 78,157,138, 67,135, 14, 45,253,215,191,
+254,117,249,110,231,231,223,198, 96,113, 28,151,157,145,145,209,118,243,230,205, 76, 5, 33,216, 66, 8, 88,150, 5, 33,164,161,
+ 99,109,253, 43, 0, 28, 57,114, 68,224,121, 62,235, 22, 55,255,236,147, 39, 79,182,217,184,113,163, 68,165, 82, 65, 46,151, 35,
+ 61, 61, 29, 18,137, 4,151, 47, 95,198,103,159,125,118, 77,167,221, 67,135, 14, 89, 21, 10,197, 61,155,213,251, 76,126,229,163,
+157,124, 20,222,234, 60, 67,113, 42,165, 55,188,128,175,239, 20,127, 35,148, 26,237,155, 43,151, 47,117,105,100,174, 42,140, 38,
+219, 99,231,138,170,239,120,225, 60,126,252,184,179, 46,244,250,214,192,129, 3,109, 0,220, 1,188, 65,107, 35,119,168, 51, 89,
+255,236,220,185,243, 12, 0, 10, 0,111,221,203,232,149,205,102,107,136,156, 58, 91,228,170, 49, 73, 73, 73,153, 0,134, 59,186,
+239, 86,140, 27, 55,238, 55, 0,191,221,201,180,222, 13,205,122,202,174, 86,226, 82,102, 94,221, 82, 94, 86, 88, 47, 95,249,163,
+255,148, 96, 65, 89,101,169,195, 17,172, 75,153,185,176,217,104,173,158, 53,175,182,147,187, 85,128, 96, 17, 80,114,213,177, 9,
+242, 41,165,231, 8, 33,125,231,207,159, 63, 3, 64,127,212,142, 62,204, 70,237,232,224,181,246,246,193,225, 56,174,255,154, 53,
+107,134, 51, 12,195, 36, 36, 36, 24,151, 47, 95,158, 83, 92, 92,252, 56,165, 52, 27, 0,188,189,189,255,185, 99,199,142,173,206,
+ 48, 37,195,117,188,120,159,106, 55,155,251,101,100,226,182,109,219,162,167, 77,155, 38, 9, 13, 13,157, 27, 28, 28,204,100,102,
+102,162,184,184, 24, 44,203,162, 83,167, 78, 8, 15, 15,135,175,175,175,109,223,190,125,203, 71,143, 30, 29, 45,218,165, 59,104,
+176,172, 86,235,144, 57,115,230, 28, 54, 26,141,118,245,197, 81, 40, 20,121,213,213,213, 67,110, 81,240,134,196,198,198, 30, 94,
+179,102, 77,219, 70, 21, 71,141,197, 98, 89, 52,109,218,180,183, 5, 65, 80, 92,167,153,107, 54,155, 7,253,149, 25,114,125,147,
+223,197,220,154,219,238, 39,162,226,225,151,147,176, 7,233,103,147,241,121, 74,193, 85,189,153,134,167, 22, 85,159,251, 59, 21,
+ 52, 74,105, 49,128, 89, 77,236,187, 4, 96,186, 19,164, 81, 73, 8,209, 59,179,177, 18,249, 3,158,231,139, 31, 29, 50,248,150,
+ 35, 4, 37, 18, 73,177,189,122, 67, 31, 25,116, 75, 61,142,227,138, 29, 44, 87, 70,212,118, 3,104,118, 87, 0,150,101,231,132,
+134,134,178,115,230,204, 41,220,183,111,223,247,229,229,229,179, 41,165,250,250,253,117,163, 6, 3,197, 82,225, 52,245,221,125,
+ 49, 50,113,253,250,245, 81,179,103,207,222,234,235,235,187,177,127,255,254,157, 59,116,232,160,209,104, 52,168,172,172,172, 42,
+ 43, 43, 75,219,181,107,215,243,147, 39, 79,206, 20,207,232, 29, 54, 88,137,137,137, 69, 0,186,223,201, 31,187,133,230,255,156,
+ 38, 87,206,119,211,215,155,173,198, 81,170, 38, 63,223,162, 15,214,149,146,223,103,188,245,241,222, 24,163,197,102, 19,108,116,
+ 74,106, 97, 85,170, 88,244,156,182, 98, 20,205,213,125, 66,124,124,124, 91,103,214,187,147,152, 76,166,153, 97, 97, 97,239, 90,
+173,214,149, 22,139,229,152,120,246, 69,238, 20,171, 86,173,202, 68,237, 82, 64, 24, 59,118, 44, 11, 0, 95,124,241,133,213, 9,
+147, 26, 12,192, 3, 64,253, 3,142, 7, 0, 19,106,103,246, 47, 6,144,116,223, 24,172,191, 43, 95,124,247,199, 13,246,122,227,
+116,171,207, 77,250,181,130,223,143, 1,232, 39,230,174,136,136, 72, 51,141,127, 54,128,199,197,156, 16,185,171,247, 63,231, 52,
+ 86,245,120, 16, 66,118, 83, 74, 71, 0, 64,253,251,198,219,156, 13, 70, 44, 82, 34, 34, 34, 34, 34, 34, 34, 34,119, 22, 2,192,
+191,137, 39, 38,187, 59, 96, 19, 66,252,155,241, 68,246,139,168, 41,106,138,154,162,166,168, 41,106,138,154,127, 47,205, 91,105,
+ 55,241,255, 17,183,136, 96,237,113, 58,131,117, 55, 39,166,251,171,135, 4,139,154,162,166,168, 41,106,138,154,162,166,168,121,
+127,106,222,130,251,206, 96,137,125,176, 68, 68, 68, 68, 68, 68, 68,156,157,154, 5, 11, 22, 44, 36,132,236, 6,128, 5, 11, 22,
+ 44,116,246, 4,139, 6, 75, 68, 68, 68, 68, 68, 68,196,217,137,143,137,137,209,199,196,196,212,119,104, 47, 70,109, 43,220, 8,
+252, 49,178,240,254, 54, 88, 11,134,248,245,243,110,237,253, 97, 69,105,233,105,155,169,106,234,146, 3,185,229,205,249, 97, 66,
+136,142,231,249,167,148, 74,229, 32, 74,169, 31,203,178, 23, 42, 43, 43,143, 88, 44,150, 47, 40,165,213, 98, 89, 18,185,215, 4,
+ 6, 6,246,224, 56,110, 54, 33, 36, 88, 16,132, 86, 28,199, 21, 16, 66,146, 76, 38,211,154, 83,167, 78,157, 22,115,232,193, 37,
+ 40, 40,232,107, 74,105,120, 93, 93,117,224,212,169, 83, 99,196, 92, 17, 17,185,167,152, 0,156,188,159, 18,236,176,193, 34,148,
+ 62,253,252,139, 19,189,175,230,164,121,127,178,109,127,167, 55,134,183, 13, 95,178, 55,203,161, 5,191, 20, 10,197, 83, 61,122,
+244, 88,177,110,221, 58, 93,187,118,237,136, 66,161, 64, 65, 65, 65,231, 51,103,206,140,138,140,140, 92,200,113,220,255, 89, 44,
+150,195,183,115, 96,132, 16, 23,119,141,100,118, 73,165,229,117,177, 92,138, 56,194,216,177, 99,217,156,156,156, 69, 58,157,110,
+230,252,249,243,101,126,126,126, 80,171,213, 40, 42, 42,106,125,241,226, 69,159,245,235,215, 15, 15, 11, 11,139,149, 74,165,145,
+ 71,143, 30, 21,196, 28,187,255, 9, 13, 13,109, 33, 8,194, 90, 66, 8,207,178,236, 92, 74,105,248,254,253,251, 97,181, 90, 17,
+ 17, 17, 17, 30, 26, 26,218,193,106,181, 46, 87, 42,149, 54,163,209, 56,181,110, 78, 63,145,251,156,144,144,144, 44,171,213,234,
+ 97,239,247,121,158,207,141,143,143,239, 44,230,156,200, 93, 49, 88, 44,197,129, 61, 95,109,159, 56,114, 64, 23, 50,241,241,128,
+ 14, 91,191, 77, 62, 50,231,209,246,143,174, 60,152, 97,215,146, 54, 74,165,114,218,148, 41, 83,162,162,162,162,228, 23, 46, 92,
+192,185,115,231, 32, 8, 2, 52, 26, 13,252,253,253,153, 61,123,246,180,156, 62,125,250,167, 60,207, 79, 49,153, 76, 59,155,123,
+ 96,158, 58, 54, 90, 35,151,140,147, 73, 36, 73, 70, 65,216,227,164, 23,247, 46,139,197,178,242,231,159,127,254,241,126, 41, 48,
+193,193,193,125, 37, 18,201, 66,158,231, 31,127, 80,205,197,229,203,151, 23,254,227, 31,255,152, 25, 25, 25, 41,203,204,204, 68,
+ 90, 90, 26, 10, 10, 10,208,174, 93, 59,180,107,215,142,172, 93,187, 86,190,110,221,186, 41,167, 79,159,102, 0,216,221, 15,128,
+ 16,194,120,121,121, 77, 26, 60,120,240,104,119,119,119,109, 65, 65, 65,101,124,124,252,238,188,188,188, 15, 41,165,205,202, 75,
+ 66, 8,227,225,225, 49, 33, 34, 34, 98,180,155,155,155, 91, 65, 65, 65,249,225,195,135,119, 23, 21, 21,125, 76, 41,181, 53, 55,
+ 15, 8, 33, 45, 81, 59,194, 88, 87,183,233,138,159,159,223,249,140,140,140,226, 59,168, 89,224,231,231,151,218, 28,205,190,125,
+251,122,155,205,230, 61, 0, 58, 54,245, 29, 74,105, 42,199,113, 17,246,152, 33, 65, 16,214,190,243,206, 59, 17, 26,141, 6,243,
+231,207, 63,237,235,235, 11,173, 86,139,184,184, 56,184,185,185,193,106,181,158, 94,177, 98, 5,201,201,201,193,154, 53,107, 54,
+ 0,120, 66,188,125,216,117,206,183, 0,112, 5, 48,137, 82, 90,218,104,187, 59,128,207, 1, 20, 83, 74,199,223,171,244, 89,173,
+ 86,143, 31,126,248, 1, 50,153,172,110,185, 37, 27, 40,165, 13,175,141, 49,155,205, 8, 15, 15,111, 41,158, 85, 17, 7, 2, 82,
+ 77,143, 34,124,117, 72,187,151,252,123, 7,188, 45,229, 37, 10,155,213, 2,155, 96,129,213, 98, 2, 75, 5,116,111,231,138,246,
+ 45,120, 84,253, 94,133, 79, 14,166,255, 94, 90,131, 1,209,123, 47,164,223,226, 98,243, 13, 14, 14, 62,113,244,232, 81,237,247,
+223,127,143, 11, 23, 46, 32, 58,186,118,137, 35,149, 74,133,125,251,246,213,175,232,141,199, 30,123,172, 36, 63, 63,191, 55,165,
+180,188, 25, 23,117,155, 1, 65, 62,199,191, 94, 49,192,173,199, 19, 95,102, 95, 41, 51,245,160,148, 58,221, 4,106,129,129,129,
+122,142,227,244, 38,147,233,169,251,193,100, 5, 7, 7,247,101, 89,118,135,197, 98, 81,170,213,106,247,163, 71,143, 26, 31,180,
+ 11, 34, 48, 48,176,135,171,171,235,209, 29, 59,118,200, 19, 18, 18, 80, 94, 94,142,162,162, 34,204,156, 57, 19, 27, 54,108, 64,
+143, 30, 61,160, 82,169,192,243, 60, 94,126,249,229, 26,189, 94, 31,158,152,152,152, 98,143, 17, 26, 48, 96,192, 71, 91,183,110,
+109,107,177, 88, 24,160,118,225,243,236,236,108,235,194,133, 11,115,146,147,147, 39, 59,106,178, 8, 33, 76, 88, 88,216,166,173,
+ 91,183,250,241, 60,207, 8,130, 0,155,205,134,139, 23, 47, 90, 23, 45, 90,116, 57, 57, 57,249,185,230,148,123, 66, 72, 47,165,
+ 82,217,229,229,151, 95, 46,125,252,241,199,205, 0,144,146,146, 66, 82, 82, 82, 92,124,125,125, 47, 47, 89,178,228, 76, 51, 52,
+123, 43,149,202, 78,211,167, 79, 47, 25, 62,124,184,192,243,188, 45, 33, 33,129, 61,123,246,172,139,159,159,223,111, 11, 23, 46,
+116,104, 52, 82, 64, 64,192,153,247,222,123,175,149,143,143,143,149, 16, 66,235,126,131, 18, 66, 40,195, 48, 20, 0, 82, 83, 83,
+185, 87, 94,121, 37, 59, 37, 37, 37,200,142,243,190, 99,252,248,241, 67,123,245,234,133, 46, 93,186,128,101, 89,164,165,165,225,
+210,165, 75,144,203,229,240,247,247,135, 66,161,192,206,157, 59,241,217,103,159, 29, 74, 78, 78, 30, 45,222, 62,236, 58,239, 63,
+ 0, 8, 2,112, 30,192, 48, 74,105,105,157,185,218, 15,160, 43,128, 19,148,210, 33,247,178, 14, 78, 72, 72,192,142, 29, 59, 32,
+149, 74,193,113, 28, 74, 75, 75,225,235,235, 11,137, 68, 2,142,227,192,113, 28,164, 82, 41,124,124,124,240,200, 35,143, 8, 73,
+ 73, 73, 90,241,204,138,220,118, 4,203,171,229, 67,243,158,124,114,136, 2, 86, 1, 48, 87, 3,102, 61,168,185, 26,212,164, 7,
+225, 21,160, 22, 3, 84,108, 41,254,239,145, 22,154,175,226, 11, 83, 94, 29,220,110, 76,204,225,204, 67, 77,233,105,181,218, 5,
+113,113,113,218,179,103,207, 34, 45, 45, 13,171, 87,175, 70, 84, 84, 20,164, 82, 41,202,203,203, 49,106,212, 40,196,199,199,195,
+100, 50,225,181,215, 94,115, 91,176, 96,193, 20, 0, 14, 47, 50,217, 82, 39,121,119,251, 39,107,221,116,138, 18, 60, 55, 42, 73,
+183,254,139,172,151, 0,108,112,198, 19, 48,111,222, 60,229,242,229,203,191,236,221,187,183, 83,155,172,224,224,224,190, 82,169,
+116,199,226,197,139, 85,139, 23, 47,182,222, 33,205,110, 12,195,124, 98, 50,153, 22,156, 62,125,250, 59,103, 56, 78,169, 84, 58,
+237,149, 87, 94,145,231,228,228,224,234,213,171, 13, 79,182,245,200,100, 50, 48, 12, 3,158,231,241,236,179,207,202, 55,109,218,
+ 52, 29,192,164, 91,233,122,121,121, 77,218,178,101, 75, 91,179,217,204, 84, 85, 85,129,231,121, 72,165, 82,244,236,217,147,157,
+ 59,119,174,207,172, 89,179, 94, 0, 16,235, 72, 90,117, 58,221,191,183,108,217,226,199,243, 60, 83, 80, 80,128,126,253,250, 33,
+ 33, 33, 1,161,161,161,236,188,121,243, 90, 79,159, 62,253, 57, 0, 31, 56, 26,101, 82, 42,149,221,142, 29, 59,150,219,170, 85,
+171,134,237,237,219,183,167,195,135, 15, 47, 59,127,254,124,167, 83,167, 78,149, 5, 5, 5,229, 58,160,233,173, 84, 42, 59, 31,
+ 60,120,240, 74, 84, 84,212,160, 13, 27, 54,140, 0,128,144,144,144, 61, 49, 49, 49, 71,138,139,139,187, 38, 36, 36,148,245,233,
+211, 39,223, 1,205, 14, 94, 94, 94, 85,211,166, 77, 83, 55,245,157,143, 62,250,168,140, 16,210,213, 30, 61,150,101,103,111,219,
+182,237, 76,121,121,185, 36, 57, 57, 25,114,185, 28, 10,133,162,225,245,202,149, 43, 48,153, 76,216,190,125,187,192, 48,204, 28,
+241,214, 97, 55,227, 0, 28, 0,208, 13,192, 62, 66,200, 51, 0, 62, 5,208, 5, 64, 58,128,123,190, 56,181,205,102, 3,199,113,
+144, 72, 36,216,179,103, 15, 98, 99, 99,241,205, 55,223,192,219,219,187,193, 96, 73, 36,146,250,114, 39,158, 81, 17,199, 12, 22,
+ 33,132, 82, 74, 73,253,107,253,206,130,130,162, 85, 31,199,126, 24,205,115, 12, 55, 36,172, 11,220,100, 2,136, 82, 7,233,192,
+ 5, 32,174,190, 0, 0, 90,150, 1,211,129, 5, 24,219,187,132,249,196, 76, 62,127,103, 84,231, 54,243,190, 77,171,106,162, 82,
+ 12,105,211,166, 13,126,252,241, 71,180,107,215, 14,139, 23, 47, 70,215,174, 93,161, 84, 42, 81, 88, 88,136,234,234,106,168, 84,
+ 42, 88,173, 86, 4, 4, 4,176,106,181,122,128,163, 6,139, 16,242,240,243,227, 66,131, 36,218, 46,232,247,216, 11, 56,184,126,
+160,234,227, 61, 5,175, 16, 66, 62,105,188, 56,170,179, 48,122,244,104, 20, 22, 22, 42,183,110,221,218,108,147, 21, 18, 18,178,
+203,106,181, 14,190,213,247,228,114,249,143,199,142, 29, 27,214, 92,115,181,105,211, 38,149,171,171,235, 29,169,100,234,204,213,
+247, 19, 39, 78,212,108,217,178,101,219,195, 15, 63,252,180, 51,152, 44, 66, 72, 31, 63, 63, 63,100,103,103,163,176,176, 16, 70,
+163, 17,133,133,181, 93, 12,115,115,115,225,227,227, 3, 55, 55, 55,248,248,248,160,115,231,206,132, 97,152, 96,123,116, 7, 14,
+ 28, 56, 2, 0,147,145,145,129,226,226, 98,104,181, 90,168,213,106,180,106,213, 10,131, 6, 13,146,180,111,223, 62,220, 81,131,
+ 21, 30, 30, 62, 90,169, 84, 50,217,217,217,200,204,204,132,209,104, 68,122,122, 58, 92, 93, 93,241,200, 35,143,112,126,126,126,
+195, 28, 53, 88, 0,186, 79,153, 50,165,184,177,185,170, 71,165, 82,145,110,221,186,149,107, 52,154, 0, 0,185,142,104,206,156,
+ 57,179, 40, 38, 38,166,255,161, 67,135,102,215,111, 60,116,232,208,127, 1,224,253,247,223, 63,230,226,226, 18, 0,192,161,133,
+213, 41,165,182, 23, 94,120,225, 18,207,243, 13,134,181,254, 61,207,243, 96, 24,198,197, 30,157,250, 14,237,254,254,254,152, 58,
+117, 42,190,249,230, 27,108,222,188,185, 97,255,147, 79, 62,137, 49, 99,198,160,170,170, 10,158,158,158,146,252,252,252, 95,131,
+130,130,156,162,227, 59, 33, 36, 16,192, 82, 0,102, 0,145,148, 82,167, 90,143,141, 82, 90, 68, 8, 9,111,100,178, 78, 0,144,
+213,153,171,112, 74,233, 61,239,203,102,181, 90,193,113, 28,114,114,114,176,113,227, 70,188,244,210, 75,232,217,179, 39, 42, 42,
+ 42, 26, 12, 22,199,113, 96, 24,113,225,147,187, 88,142,111,232, 65, 30,232, 8,150,172,127,118,108,230,113,166,231,216,145, 97,
+ 19,116, 90, 5,108,191,231, 67,250, 72, 36,206,150, 41,177, 38,246, 0, 0, 96,214, 83, 1,240, 31,250, 22,140, 31, 62,138,193,
+190, 38,254,195,159,229,255, 5, 16,117, 35, 61, 15, 15, 15,119, 65, 16,192, 48, 12, 84, 42, 21,116, 58, 29, 20, 10, 5, 74, 74,
+ 74, 48, 99,198, 12,236,223,191, 31, 38,147, 9, 82,169, 20,126,126,126, 48,155,205,126,142, 30,144,167,155,100,253,154, 21,209,
+ 46,165, 25,159, 33,249,194, 85, 40, 93,124,176,232,165, 64,215, 55, 54, 36, 47, 4,176,200, 25, 79, 66,247,238,221, 49, 99,198,
+ 12,229,186,117,235,154,101,178, 40,165, 75, 37, 18, 73,159, 57,115,230, 40,158,122,234,169, 63,237, 63,119,238, 28,166, 78,157,
+ 90,163,215,235,151, 53,199, 92,113, 28,183, 99,227,198,141, 42, 23, 23, 23,100,103,103,223, 49,115,181,118,237, 90, 77,251,246,
+237,193,113,156,252,163,143, 62,114, 10,147, 37, 8,130,143, 82,169, 68, 73, 73, 9,102,205,154,117, 77, 63,140,250,230,108, 0,
+ 72, 75, 75,131,143,143, 15, 12, 6,131,183, 61,186,238,238,238,174,148, 82,188,248,226,139,200,201,201,105,216,238,237,237,141,
+220,220, 92, 8,130,224,230,104, 90,117, 58,157,155,197, 98,193,128, 1, 3, 96, 48, 24,106,195, 5,227,198,129,227, 56, 20, 21,
+ 21,193, 98,177,232,154,145, 5,238,195,135, 15, 47,104,106,167, 90,173,182,232,116,186, 54,142, 38, 53, 34, 34, 34,127,253,250,
+245, 17,215,239, 56,121,242,100,132,139,139,203, 97,119,119,247, 78,205, 9, 62,200,100, 50,240, 60, 15,142,227, 80,255,190,254,
+143,101, 89,155,157,215, 79,248,254,253,251,161,213,106,145,152,152, 8,133, 66, 1, 0, 24, 49, 98,196, 28,181, 90,221,223, 96,
+ 48, 60,190,123,247,110, 92,189,122, 21,126,126,126,104,209,162, 5, 18, 19, 19,195,157,164,250,120, 27, 64,159,186,247,239, 54,
+122,239,108, 38,107, 2,128, 99,117,230,202, 4, 96,188, 51,152,171,198, 17,172,101,203,150, 65, 16, 4,196,199,199, 99,236,216,
+177, 32,132,128, 16, 2,173, 86,139,119,223,125, 87,116, 65, 34,205, 51, 88, 55,114,142,111,188, 65, 24,227,241,182, 27,198, 70,
+244,153,208,205, 71, 5, 99, 73, 6,120,181, 59,136,107, 91,172,137, 61,128,243, 89,101, 0,128, 53, 95,166,224,227, 87,195, 65,
+148, 58,120,213, 92,128,150,151,141,106,202, 96,149,150,150, 86,153,205,102, 55,133, 66,209,240, 84, 80, 82, 82,130,215, 95,127,
+ 29,219,183,111, 71,219,182,109, 33, 8, 2,120,158, 71,113,113, 49, 56,142,115,104,116,162, 68, 66, 30,139,156, 57,172,173,202,
+189, 19, 74, 83,222,168,221,168, 13,192, 75,227, 24,126,229, 39,191,252,155, 16,242, 46,165,212,233,230,203, 80,171,213,232,213,
+171, 23,254,253,239,127, 43,183,110,221,250, 1,110,210,113,247, 70, 36, 37, 37,157, 8, 14, 14, 30,181,106,213,170,111, 11, 10,
+ 10, 20,189,123,247,134, 90,173,134, 90,173, 70, 70, 70, 6,162,162,162, 12, 6,131,225,201,230, 68,199, 24,134,137,125,254,249,
+231, 85, 90,173, 22, 25, 25, 25,208,233,116,183,117,172,193,193,193,221, 88,150,253,126,237,218,181,154, 14, 29, 58, 32, 53, 53,
+ 21,129,129,129,104,217,178,165, 60, 38, 38,230,158,155, 44,169, 84,154, 87, 92, 92,220,190,117,235,214,216,180,105, 19, 24,134,
+ 65,126,126, 62, 22, 45, 90,132,152,152, 24,244,233,211, 7,106,181, 26,173, 91,183, 70,122,122, 58, 20, 10,197, 21,123,116,243,
+242,242,202, 1,120,236,219,183, 15, 37, 37, 37, 13,219,219,180,105,131,178,178, 50,152, 76,166, 50, 71,211,154,159,159, 95, 6,
+160,197,233,211,167,145,153,153,137, 97,195,134, 97,231,206,157, 8, 12, 12,132,213,106,133,197, 98, 41,107, 70, 22, 88, 89,150,
+189,217,242, 14, 4,128,163,102, 80,144, 72, 36,244, 38, 79,175,205,209,132,205,102,163, 77,153, 43,169, 84,138,155,253,230,141,
+162, 24,113,113,113, 13,205,130, 0,192,113, 92,159,217,179,103, 63,222,212, 67,145,147,208, 56, 74,231,148,131, 78, 8, 33, 30,
+ 0,182, 0,224,235, 34,109, 60,128,205,132,144, 97,141, 59,190,223, 75,131,197,178,108,195,103,149, 74,133, 94,189,122, 53, 24,
+ 44,189, 94, 15,142,227, 68,183,112,119, 77,248, 3, 23,189, 2,234, 22,123,110, 28,158,187,198, 92, 13, 11,154,208,213, 71,142,
+159, 83,126,129,196, 84, 6,106,172,188, 73, 13,101, 1,145,170,160, 85, 73, 90,221,228, 66, 59,157,149,149, 5, 87, 87, 87, 72,
+165, 82,200,100, 50,248,251,251,227,196,137, 19,232,212,169, 19,172, 86,107, 67, 69,249,235,175,191, 66, 16,132, 99, 14, 92,196,
+236, 67, 90,201,138,121, 11,163,212,200,219, 4, 87,141, 12,131,250,116, 0, 84,221,192,114, 50,172,122,109,164,155,231, 67, 46,
+239, 56,227, 73, 80,171,213,200,203,203,195,103,159,125,166, 55, 24, 12, 47, 54, 71, 35, 41, 41,233,132,213,106, 29,245,197, 23,
+ 95,212,100,101,101, 65, 46,151,227,226,197,139,245,230,106, 76,115,251,119,217,108,182, 41, 31,124,240, 65,245,238,221,187,161,
+ 86,171,161,209,104,110, 59,114, 53, 99,198, 12,117,199,142, 29,145,145,145, 1, 23, 23, 23,184,187,187,163,127,255,254, 88,183,
+110,157, 92,173, 86,111,123,248,225,135,239, 89,167, 87,155,205,150,152,158,158, 78, 93, 92, 92,208,185,115,103,244,232,209, 3,
+ 33, 33, 33, 0,128,250, 14,208,237,218,181, 3, 0, 92,186,116, 9,148,210, 83,246,232, 30, 59,118,108,119, 90, 90,154,213,203,
+203, 11, 61,123,246, 68, 64, 64, 0, 66, 67, 67,225,235,235,139,255,253,239,127,230,203,151, 47,239,119, 52,173,135, 15, 31,222,
+245,203, 47,191, 8, 94, 94, 94, 8, 12, 12,132, 76, 38, 67,143, 30, 61,224,229,229,133,184,184, 56,115, 86, 86,214,254,102,100,
+ 65,238,153, 51,103,216,166,118, 42, 20, 10, 13, 0, 71, 35, 15,249, 39, 79,158,100,194,194,194,254, 52,154, 55, 36, 36,100,143,
+ 66,161,112, 1,112,197,209,132, 18, 66,108, 60,207, 67, 46,151, 95, 99,174,120,158,135, 76, 38,131, 68, 34,177,119, 20,229,158,
+136,136, 8,236,222,189, 27,114,185, 28, 74,165, 18, 79, 60,241, 4, 12, 6,195,147, 0,176,116,233,210,134,155,109,100,100, 36,
+ 0, 64,175,215, 59,203, 0,143,185, 0,126, 5,240, 27,128,215,156,208, 92,181, 64,109,243, 96, 39,212, 54, 11,246,175,123,173,
+239,147,229,238, 4, 55,119, 72,165, 82,188,249,230,155,224, 56, 14, 45, 91,182,196,194,133, 11,177,120,241, 98, 68, 70, 70, 98,
+249,242,229,112,115,115, 19,155, 8,239,110, 57,185,198,131, 60, 80, 6,235,122, 76, 9,190, 75,158,122,172,247,132,174,173,100,
+ 56,157,242, 43,118,157, 44,184, 88, 82,114, 21,182,194, 95, 96, 43, 78,197,172,167, 2,208,173,173, 14,221,218,234, 48,235,169,
+ 0,216,138,126, 5, 45,207, 0,149,235, 80, 92, 69,154,108, 94, 40, 43, 43, 91, 19, 21, 21,117,213,205,205,173,161, 82,204,205,
+205, 69,247,238,221,175,169, 36, 89,150,197,235,175,191, 94, 82, 84, 84,180,201,110,147,162, 96,159, 91,246,218,211, 45,164, 50,
+ 13, 80,246, 35,180, 90, 53, 54,197,174, 0,140,249, 0,195, 99,228,144,135, 89,175, 22, 46,255, 36,132,116,116,182,147,144,157,
+157,141,200,200, 72,189, 94,175,191,173,142,238, 73, 73, 73, 39, 44, 22,203,168,184,184,184,154,189,123,247,226,237,183,223,190,
+ 45,115,213,200,184,141,222,188,121,115,117,118,118,246,109, 25, 44,142,227, 94, 17, 4, 65,179,122,245,106,219,208,161, 67,173,
+ 47,191,252,178,117,242,228,201,214, 49, 99,198, 88,135, 12, 25, 98,157, 50,101,138,213, 96, 48,200,212,106,245,219,247,234, 92,
+152,205,230,216,216,216, 88, 3,195, 48, 80,171,213,224,121, 30, 30, 30, 30, 13, 70,184,190,159,143,217,108,198,250,245,235,107,
+140, 70,227,251,246,232,150,148,148,108,158, 59,119,110,214,193,131, 7, 45, 21, 21, 21, 0,128,130,130, 2, 68, 71, 71,155, 55,
+108,216,144, 95, 94, 94,254,161,163,105,173,168,168,216, 50,127,254,252,203,123,247,238,181,176, 44,139,242,242,114,184,186,186,
+ 34, 58, 58,218, 28, 27, 27,155, 95, 89, 89,233,176,102,255,254,253, 51,114,115,115, 53, 70,163,145,222,224,252, 17,133, 66, 17,
+ 4,224,168, 35,154, 33, 33, 33, 25,217,217,217,218,183,222,122,235,167,161, 67,135,174,210,106,181,151,180, 90,237,165,161, 67,
+135,174,222,176, 97,195, 15,114,185, 60, 8,192,145,102, 68, 87,109,245,117,134, 92, 46,135, 76, 38,107,120, 64,147,201,100,224,
+ 56,206, 46,131,149,156,156, 60,142, 82,218, 83, 16, 4,161,103,207,158, 80, 42,149, 24, 51,102, 12,164, 82, 41, 0, 96,193,130,
+ 5,160,148,130, 82,218, 96,176,170,170,170,156,194, 96, 81, 74,127,162,148,134, 82, 74,253, 41,165,206, 56, 72,102,107, 35,115,
+ 21, 78, 41, 61, 7, 32,188,145,201,218,238, 12, 6,139,227, 56,116,237,218, 21,179,102,205,194,206,157, 59,145,149,149, 5, 65,
+ 16, 96,181, 90,193, 48, 12, 36, 18,137,104,176, 68, 28,166,161,137,176,241,107, 75, 87,213, 51,221,188, 36, 56,125,250, 60,190,
+ 61, 85,182,149, 97,216,157, 41,153,198,175,194,253,126,135,121,251,120,248,143,221,130,143, 95,173,237,130, 96, 43,250, 21,230,
+ 47,158, 1, 81, 62,132,244, 74, 37,244,230,242,253, 55, 41,200,167,116, 58,221,151,159,124,242,201,196, 73,147, 38,241, 54,155,
+ 13, 10,133, 2,179,103,207, 6,165,180,193, 92, 77,157, 58,181,186,168,168,104, 29,165, 52,195, 78,247,171,104,229,193,207,159,
+240,226, 34, 57,114, 98, 1, 70,138, 18,244, 70,175, 1,207,163, 40,235, 4, 80,125, 30, 32, 82,196, 46,123,193,125,212,228, 21,
+239, 1, 24,234, 44, 39, 32, 53, 53, 21, 75,150, 44,185,109,115,213,216, 16, 5, 7, 7,143,218,185,115,231,255, 12, 6,195,203,
+119, 80,115,244,178,101,203,118,180,104,209, 66,213, 92, 29,111,111,239, 23, 74, 74, 74,166,218,241,213,123,214,212,113,234,212,
+169,211,125,251,246,221,184,122,245,234, 23,103,206,156, 41, 87, 40, 20,208,106,181, 72, 75, 75, 67,155, 54,181, 93,143,106,106,
+106,240,234,171,175,214, 8,130,176, 53, 49, 49, 49,209,206, 74,220, 70, 8,121,126,202,148, 41,147, 58,117,234, 20, 65, 41,213,
+153,205,230,178,203,151, 47,239,175,172,172,108,214, 60, 88,117,154,207, 77,157, 58,117, 66,199,142, 29, 71, 91, 44, 22,157, 32,
+ 8,101, 57, 57, 57,123, 42, 43, 43, 55, 55, 71,243,167,159,126, 42,217,180,105,211,111,249,249,249, 93, 61, 61, 61, 43,221,221,
+221, 77,122,189,158,213,104, 52, 26,158,231,123, 3, 72, 4,112,193, 17,205,196,196,196,162,184,184,184,203,122,189,190, 83,108,
+108,236, 49, 87, 87,215, 35, 86,171,149,240, 60,239,166, 82,169, 6, 2,248, 9,192,165,230, 24,172,250, 7, 51,169, 84,218, 16,
+ 21,175,255, 12,192,230,128,214,138,101,203,150, 73,228,114, 57, 76, 38, 19,244,122, 61, 74, 75,107, 91,175,150, 46, 93,138, 87,
+ 95,125, 21, 0,176,100,201, 18, 68, 70, 70,162,166,166, 70, 38,222, 62,236,162, 12,192, 41, 0,227,234,251, 92, 53,234,248,190,
+ 21, 64,133,179, 24, 44,142,227, 48,105,210, 36, 12, 31, 62,252, 79,211, 52,136,157,220,239,250, 57,184,198,131, 60, 48,145,185,
+ 27,205,131,181, 96,104,219,255,243,113,225, 94,201,175, 20,118,242,125,179,230, 71, 70,130,190,250, 72,219,157,163, 59, 86, 63,
+210,173,165, 13,160, 2,136,182,246,102, 67,171,242, 65, 84, 45, 81,110,115,193,166,195,133,133,148, 97, 66,150,236,186, 88,122,
+ 19, 51,196,185,186,186,174,236,216,177,227,152,232,232,104,151, 46, 93,186, 64,169, 84,130, 82,138,179,103,207, 98,234,212,169,
+229,197,197,197,155, 74, 75, 75,223,160, 55,155,164,171, 17, 30,174,220,155, 27, 34,135,253,103,204,164,215,165,184, 48, 7,144,
+184, 0, 15, 13,193, 21, 50, 24, 45, 37,103, 0,211,149,218,109,156, 11,134, 77, 88, 90,190,255,112,210,191, 40,165,241,247, 58,
+243, 3, 3, 3,245,114,185,252,142,153,171,187, 77,112,112,112, 95,158,231,119, 24,141, 70,165, 74,165,122, 32,231,193,170, 59,
+ 47,156, 76, 38,139,146, 74,165, 47, 60,243,204, 51,138, 46, 93,186,192,215,215, 23, 69, 69, 69, 72, 75, 75, 67,108,108,172,193,
+102,179,125, 92, 86, 86,182,240,220,185,115,230, 7, 49, 15, 46, 94,188,232,213,190,125,251, 96,150,101,219,163,118,162,200, 43,
+ 0, 14, 54,199, 8,213,147,158,158,238,237,235,235, 27, 44,149, 74,253,234, 52,243, 1,124,215, 28,205,128,128,128, 51, 11, 22,
+ 44,104, 49, 96,192,128,106,150,101,169, 84, 42,165, 12,195, 64, 42,149, 82,137, 68, 66, 9, 33,244,211, 79, 63,213,174, 90,181,
+170,192,158,121,176,130,130,130,182,141, 24, 49, 98,164, 92, 46,199, 87, 95,125, 37,120,122,122, 74, 92, 93, 93,241,241,199, 31,
+ 55, 85,143,129, 82,170, 20,111,141,247,253,181,174,255,238,187,239,144,147,147,115,205,156, 87,141,141, 85,253,103, 66, 8,194,
+194,194,132,147, 39, 79,138,243, 96,137, 52,223, 96,221,136,101, 67,252,180, 21,160,159,247,106, 69,255, 17,228, 43,131,135,171,
+ 28, 12, 39, 67,165,129,224, 92,190, 1,199, 82, 43,115,173, 54,242,228,219, 7, 51,206,217, 25,117, 10,105,217,178,229, 92,155,
+205,214,141, 97, 24, 37,165,180,138, 97,152, 51, 5, 5, 5,209,148,210,243,142, 28,132,171,134, 61,235,166,146,184, 72,121,158,
+ 10,130, 21, 0, 11, 48, 4, 32, 12, 0,166,238,149, 5, 8,131,154, 26,179, 84,176,146,157, 69, 37, 37,211,238,117,230, 15, 24,
+ 48, 96, 87, 85, 85,213,125, 55,147,187, 76, 38, 91,200,178,236,227, 15,250, 50, 49,161,161,161, 1, 60,207,207,165,148, 6, 26,
+ 12, 6, 79,133, 66, 81, 68, 8, 73,169,174,174, 94,153,156,156,124, 82,172, 62,238, 29,119,122, 38,247,192,192, 64,119, 66,200,
+106, 74,169,146, 97,152, 87,108, 54,219,175, 62, 62, 62,216,177, 99,199, 13, 35, 88,162,193,122,176, 12,214,196,137, 19,177,235,
+183,223, 48,210,175,233,129,235, 95,127,253, 53,250,245,235, 39, 26, 44,145, 59,111,176,234, 76, 17,153, 59,168,237,147, 18, 66,
+158, 32, 12,237, 78, 0,222, 74,145,206, 16,250,157, 84,102,254, 96,201,174,252,154,235,190,239, 79, 41,253,229,142, 38, 88,212,
+ 20, 53,239,129, 38, 33,132,177,103,233, 25, 49, 63, 31, 12,205,192,192,192,237,213,213,213, 17,105,105,105, 77,105, 92, 99,176,
+196,252,188, 63, 53,251,245,235,119,126,213,170, 85,173, 59,118,236,200, 16, 66,192,178, 44, 8, 33, 96, 24, 6, 44,203, 54,188,
+ 2,192,145, 35, 71,132, 55,222,120, 35,235,167,159,126,234, 37,230,231,221,209,124,208,112,104, 45,194,186, 38,187, 47,235,254,
+ 68, 68,254, 54,220,206,186,126, 34,247, 31,201,201,201,227,188,189,189,227,221,221,221,219, 27,141, 70,105, 77, 77,141,180,241,
+195,168, 66,161, 40, 17,115,233,254, 71, 16,132, 65,115,230,204, 57, 98, 48, 24,124,111,245, 93,133, 66,145, 87, 93, 93, 61, 68,
+204, 53,145,187, 98,176, 68, 68, 68, 68,254, 46,228,231,231,135,137,185,240, 96, 83,215,124,220, 77,204, 9,145,187,129, 56, 44,
+ 66, 68, 68, 68, 68, 68, 68, 68, 68, 52, 88, 34, 34, 34, 34, 34, 34, 34, 34,162,193, 18, 17, 17, 17, 17, 17, 17, 17, 17, 13,150,
+136,136,136,136,136,136,136,136, 72,243,249,127, 79, 26,247,226, 57,216,252,127, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130,
0};
diff --git a/source/blender/editors/datafiles/prvicons.c b/source/blender/editors/datafiles/prvicons.c
index 6222090705a..2a470e056cf 100644
--- a/source/blender/editors/datafiles/prvicons.c
+++ b/source/blender/editors/datafiles/prvicons.c
@@ -1,436 +1,304 @@
/* DataToC output of file <prvicons> */
-int datatoc_prvicons_size= 13732;
+int datatoc_prvicons_size= 9534;
char datatoc_prvicons[]= {
-137, 80, 78, 71,
- 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0,192, 0, 0, 0,192, 8, 6, 0, 0, 0, 82,220,108, 7, 0, 0, 0,
- 6, 98, 75, 71, 68, 0, 0, 0, 0, 0, 0,249, 67,187,127, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1,
- 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,215, 8, 27, 17, 57, 33, 43,142, 73,203, 0, 0, 0, 29,116, 69, 88,116, 67,
-111,109,109,101,110,116, 0, 67,114,101, 97,116,101,100, 32,119,105,116,104, 32, 84,104,101, 32, 71, 73, 77, 80,239,100, 37,110,
- 0, 0, 32, 0, 73, 68, 65, 84,120,218,237,125,121,124, 84,213,249,254,115,238,189, 51,147,201,158, 12, 73, 72,216, 3,200, 98,
- 88, 69, 66, 38, 65, 16, 20,165, 40,213,162, 32, 45,138,203, 79,176,223, 42,180,110, 72,235,190, 97, 91, 91, 21,181,149,182, 90,
- 20, 42, 10, 66, 80,164, 34, 59,146, 5,194, 30, 18, 8, 75, 2,201,144,144,201, 62, 73,102,189,247,158,243,251, 35,235, 36, 51,
-217,200,100, 38,229, 62,159,207,124,146,123,239,153, 59,207, 61,247,125,207,121,223,247,156,243, 30, 64,129, 2, 5, 10, 20, 40,
- 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2,
- 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,
-160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5,
- 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160,
- 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,208, 18, 36, 41, 41,105,
-180, 32, 8,143, 16, 66, 72,119,223,156, 49, 22, 46,203,242,112,198,216,203, 41, 41, 41,251, 60,241, 0,189,157,191, 2,239, 43,
-192, 61, 49, 49, 49, 27,230,204,153,227,215,157, 55,206,206,206,198,169, 83,167, 16, 25, 25, 9,131,193, 64, 37, 73,154,150,146,
-146,146,226, 1, 5,232,213,252, 21,120, 23, 2, 0, 68, 71, 71,219, 23, 46, 92,216,109, 2,180,105,211, 38, 24, 12, 6, 60,250,
-232,163,224, 56, 14, 7, 15, 30,228, 50, 51, 51, 15, 36, 38, 38, 38,164,166,166,102,116,247, 67,244,118,254, 10,188, 7,174,187,
-111, 40, 73, 18,214,175, 95,143, 5, 11, 22,160,111,223,190,240,247,247, 71, 98, 98, 34,226,226,226, 56,149, 74,149,174,215,235,
- 39,250,114,133,244,118,254, 10,188,172, 0, 6,131, 1,193,193,193,136,136,136,128, 32, 8,208,106,181,208,106,181,208,235,245,
- 24, 57,114, 36,167, 86,171, 51,244,122,125,156,175, 86, 72,111,231,175,192,203, 10, 80, 88, 88, 8,157, 78,215,120,172,209,104,
- 26,133, 40, 49, 49, 17,195,135, 15,231,213,106,245,137,132,132,132, 27,124,177, 66,122, 59,127, 5, 94, 86,128,192,192, 64, 88,
-173, 86,167,115,254,254,254,141,159,164,164, 36,196,198,198, 10,126,126,126, 89,122,189, 62,214,215, 42,164,183,243, 87,224,101,
- 5,208,233,116, 48,153, 76,173,206, 55,180,162, 90,173, 22, 73, 73, 73, 24, 56,112,160, 74,163,209,156,213,235,245, 3,124,169,
- 66,122, 59,127, 5,157,131,208,221, 55,140,138,138, 66, 77, 77, 13,172, 86, 43,180, 90, 45, 0,160,170,170, 10,165,165,165, 40,
- 47, 47, 71,105,105, 41, 44, 22, 11, 6, 15, 30, 12, 81, 20,213, 87,175, 94, 61,175,215,235,135,164,165,165, 21,251, 66,133,244,
-118,254, 10,188,172, 0,106,181, 26,227,199,143, 71, 78, 78, 14,116, 58, 29, 14, 28, 56,128,130,130, 2,196,198,198, 34, 42, 42,
- 10, 67,135, 14, 5,207,243, 72, 77, 77,133,209,104,132, 40,138,126, 26,141, 38, 79,175,215, 15, 74, 75, 75, 43,245,118,133,244,
-118,254, 10,188,172, 0, 0, 48,109,218, 52,124,250,233,167, 16, 69, 17,143, 63,254, 56,102,206,156, 9,181, 90,237, 84,102,209,
-162, 69, 48,153, 76, 88,183,110, 29,182,108,217,162,165,148,190, 9,224, 9, 0,204,219,149,210,219,249, 43,240,162, 15, 0, 0,
- 9, 9, 9, 8, 12, 12,196, 71, 31,125,132,217,179,103,183, 18,158, 6,132,132,132,224,201, 39,159,132, 70,163, 97, 86,171,117,
-108,104,104,104,127, 0,196,219,149,210,219,249, 43,240,178, 2, 4, 5, 5, 97,205,154, 53,136,137,137,233, 80,249, 33, 67,134,
- 72, 86,171,213,204,243,252,253,190, 32, 64,189,157,191, 2, 47, 43, 0, 0, 8, 66,199,173, 43, 63, 63, 63, 70, 41,149, 24, 99,
- 26, 95, 17,160,222,206, 95,129,151, 21,160,139,144,123,121,125,202,138, 72, 41, 10,208, 37, 16, 66,100, 66, 72,175, 21,160,222,
-206,255,122,133,208, 19, 63, 98,178,216,193, 24,131, 74,224, 17,160, 81,185,109, 61, 25, 99, 50,122,111, 20,165,183,243, 87, 20,
-192, 19,200, 45,174,194,152,103, 62, 5, 0, 68,135, 5,226,252,234, 37,224,185,122, 51,153, 81, 56,142,252, 11,183, 71, 92,225,
- 39,223, 22, 56, 50, 88,173,213,234, 99,111,136,134, 64,254, 25,249,155,244,139,158,230,166, 82,185, 85, 70,136,162,216,217, 30,
-128, 2,160,138, 15,160, 40,128, 19, 62, 63,112,186,241,255,171,149,181,248,241,100, 30,126, 54,113, 40, 0,128,154,174,192,126,
-124, 61,146,194,192, 35, 76, 51, 28,192,112, 0,183, 17,137,255,216,155,194,223,145,235, 45,148,132, 1,104, 48,129,148, 30, 64,
-241, 1,234,109, 2,202,240,159,159,178,157,206,125,113, 32,171,241,127, 90,118,190,213,119, 24, 80, 30,190, 60,165,192,155,194,
-223,197,251, 80,197, 9, 86, 20,192, 9, 59, 79, 93,194,213, 42, 51,180,234,166,142,230,135, 19,121, 40,173,182,212, 41, 72,217,
- 5,184,208,128, 19,189,169, 2,155, 41, 1,173,247, 1, 20, 40, 10,224,220,218,191,255,240, 76, 52, 44, 89, 23,101,138, 13, 41,
-103,234, 36,166,212,101, 15,112,220,215, 43, 77, 20, 69,167, 15, 0, 13,165, 20, 0,244, 0,120, 69,172, 20, 5, 64,105,181, 5,
-255, 61,158,139, 65, 17, 33, 88,116, 75, 28,102,196, 13,106,230, 23,100,213,247, 0, 46, 20,128,178,227,189,173, 18, 25, 99, 0,
- 16, 7,160, 76,241, 1, 20, 39, 24, 0,176, 33,229, 12, 68,153,226,161,105, 55,130, 16,224,161,105, 99,176,231,116, 62, 0,224,
-236,149,114,100,100,102, 97,148,189,166,213,247,204,140,157, 0,128,146,143,167, 7,242,212, 54, 7,192, 72, 70,137,131,227,113,
- 90,148,232,145,168,223, 30, 54,250,168, 2,252, 4,160, 90, 17, 41,165, 7,104,108,229, 57, 66,240,224,180,186,229,179,115, 39,
- 13, 67, 88, 64, 83,226,134,181,123, 91,155,250,162,204, 44,187,114,228, 75,229,171,227,159,225,101, 91, 49, 24,190, 2,195,171,
-132,176,183, 25,101,219, 4,142,228, 85,172, 78, 88,234,139, 21,233,112, 56,202, 25, 99,134,122,103, 88,193,245,172, 0, 71,115,
-139,113,246, 74, 57,102,142, 25,132,254,225, 65, 0, 0,141,138,199,130,196, 81,141,101, 54,159, 42,133, 85,118, 54,151,171,172,
-180,224, 23,113,170,117, 0,121, 23, 64,128,139, 91,251, 51,176, 79,202, 62, 72, 88,229,131,117, 25, 98,179,217,250,195,247,166,
-151, 40,232,105, 5, 88,187,191, 46,246,191,120,250, 24,167,243, 15, 79,111, 74,166, 80,227, 96,216, 86,230, 60,219, 82, 23,192,
- 15, 35,192,130,246,238, 79, 8,123,166,236,189, 41,163,188, 85,105, 42,149,170, 85, 40,149, 16, 2, 74,169, 77, 81,128,235, 92,
- 1, 44,118, 17,223,164,159,131, 46, 72,139,187,110, 26,234,116,109,236,160, 72,140, 27, 28,217,228, 39, 24, 7, 57,147, 33, 16,
- 24, 96, 7,240, 79, 2,242, 75, 2,242, 75, 6, 28,112, 37,131,132,195,115,222,170,180,102,209,159, 70,225,231, 56, 14, 42,149,
-234, 40,234,162, 64,202,104,240,245,170, 0, 91,143, 92, 64,181,213,142, 7, 18, 71, 65, 45,180,142, 8, 62,220,172, 87, 72,175,
- 14,199,101, 91,147,165, 67, 41,236,162,204,238,214, 45, 59,180, 36,124, 89,250,134,240,101,233, 27,116, 21,126,183, 1,200,105,
-221, 13,224,198,107, 17, 96, 15, 33,166,222, 7, 96, 0, 84,138,120, 93,135, 10,208, 16,251, 95, 60,205,117,238,168,249,250,145,
-240, 19,184,250,232, 9,193,134,226,129,141,215, 14, 92, 52,255, 43,250,119,135,247, 56,201,249,171,251, 37, 66, 88,178,139,216,
-139, 79,229,229,169,207,205, 43,212,127, 72,125,221,106, 20, 17,187,142, 20,224, 82,137, 9, 7,207, 26, 48, 49, 54, 10,113, 3,
- 35, 92,150, 9, 11,240,195, 93,195,154,150, 24,126,109, 28, 8,153, 17, 88, 37, 88, 95,218,102,220,233, 70,188,170, 92,156,243,
-243,149, 74,164,148,130, 82, 10, 73,146, 56, 0, 13,221,139, 31,234,204, 57, 5, 62,140,110, 29, 7,248,226, 64, 22, 24, 3,146,
- 70, 14, 64,102,126,137,219,114, 19,131, 42,241, 13,234, 82,142, 92,117,248, 97,127,101, 36, 2,107, 11, 47, 24,107, 36,171,171,
-242,140,161,159,139,211, 62,149,129,161,190, 7, 16,209, 52, 16,102, 82,196,235, 58, 82, 0,202, 24,214,255, 84,103,254,172,254,
-239, 81,172,254,239,209, 54, 74,107,157,142, 54, 24, 7,226, 94,114,165,202,221,130, 18, 2, 50,136,181, 30, 96,205,242, 86,165,
- 53, 68,128,154,251, 18,140, 49,112, 28, 39,214,215,169,168,136,214,117,166, 0,187, 78, 93, 70, 97, 69, 45,166,142, 26,128,219,
-199, 14,118, 95, 80,118,192,126,116, 45, 14,155,194,177,187, 50, 10, 0,240, 99,121, 95,220,168,209, 88, 40,165,173,166, 19,151,
-175,142, 15,102, 96,183,182,234, 21, 0,175,231,234, 87,169, 84, 78, 74,192,113,156, 67, 49,123,174, 83, 5,104,112,126, 95,186,
- 79,143,164,145,253,221,150,147,138, 78,192,106, 60,143,139,186, 64,236, 62, 86,167, 0, 14,198,225, 44, 63,108, 24, 33, 57,178,
- 11,211,226, 9,198, 16,220,178,195,225,101,124,233, 11, 21,216,208, 27,168, 84, 42,155, 90,173,110,112,128, 21, 92, 79, 78,112,
-121,141, 21,219,143,231, 98, 72,100, 8, 18, 71,244,111,219, 84,170,159, 1, 58,204,191, 22, 55, 7, 87, 52,158, 63, 45,247, 31,
- 76,235,167, 84, 54,160,236,195,201, 51, 24,195, 75, 46,140,162, 45, 97,191, 59,116,217,135,236,255, 82, 65, 16,120, 40, 19,225,
-174,207, 30,224,171,212,179,112, 72, 50, 22,221,114, 35,218,219,169,171,249, 26,128, 95, 70,229,227, 72,117, 56, 0, 32,207, 22,
- 36,124,241,127,250, 79,110,139,170,120,141,112, 40,231, 25,110,167, 12,207,160,117, 40,209,194,113,228, 89, 95,170, 68,158,231,
- 3,120,158,175, 97,140, 29,135, 50, 23,232,250,235, 1,214,238, 63, 13,142, 16, 44,186,165,253,125, 35,154,175, 2,251,121, 68,
- 33,252, 57,169,241,120,111,109,255, 49, 60,193, 55, 28,195, 62, 6,252,158,180, 22,126, 10, 66, 30, 14,123, 50, 45,223,199,234,
-145, 17, 66,168, 39, 54,234, 83,224,163, 61, 64, 65, 89, 53,118,158,186,132,242, 26, 43,178, 13,101,232, 23, 30,136, 31, 79,230,
- 1, 0,126, 54,113, 40, 98,194, 2, 91, 75,137,100, 3,173, 42, 64,165,164,198,119,165,117,243,128, 6,105, 45, 56,107,174, 51,
-241,183,148,246,199,232,128,186, 25,197,183,134,149, 96,160,159,197,201,125, 32,192,178,240,167,210, 55,249, 82, 5,138,162,216,
- 16, 2,149, 91,154,112, 10,254,135, 21, 32,203, 80,134,101,159,237,110, 60, 46,172,168,109, 60, 30,214, 55,204,165, 2,208,242,
- 92,128, 81, 20,219,253,240,252,197,113,173,174, 87, 75,170,198,243,159,141,202,104,174, 0, 57,132,224,255,133, 63,117, 40,181,
- 59, 5,247, 90,215, 6, 55, 68,128, 24, 99,168,239, 1, 20, 5,184, 94, 20, 32,126, 88, 52,118,252, 97,190,203,107, 99, 7,185,
- 30, 5,230,130,251, 65, 59,247, 3,140,112,200,216, 62,185,166,222,129,228,177,230,235, 31,109,135,207,228,173, 11, 12,208,156,
-126,112, 28, 25, 30,161,178, 15, 25, 27,100,178, 1,200, 97,132,238,235,243, 84,198, 94, 79,181,222,157, 77,141, 34, 73, 82,171,
-180,137,132, 16, 48,198,168, 44,203, 65,138, 72, 93, 39, 10,160, 11,210,226,150,209,157,219, 28,133,104, 67, 33,104, 39, 32, 4,
-192,173,131,155,206,127,191,245, 59, 57,220,116,225, 66,126,102,254,174, 63,236, 48,125,212,147,209,148,206, 78,140,115,151, 51,
- 84,201, 12,119, 29, 59,193,221,132,222, 46, 64,138, 2,244,214, 30,192,100, 50, 9, 25, 25,222,219,255,217,100, 50,241,132, 16,
- 42,203,178,220,197,239,247,106,254, 10,188,171, 0,198,226,226,226, 83,171, 86,173,226,237,118,123, 52, 99, 76,141,186,176, 30,
-234, 77, 17,214,204, 36, 97,132,144,198,255, 91, 94,115,119,189,197,189, 90,150,101,178, 44,203,146, 36,149,212, 59,145,157, 53,
-127,122, 59,127, 5, 94, 68,243,184, 53,167,211,233,150, 3,232,139,166, 44,103, 50, 99, 76, 34,132,200,140, 49,153, 16, 34, 53,
- 59, 71,155, 93,107, 56, 47, 19, 66,164,250, 4, 81,114,195, 53, 66,136, 76, 41,149, 90, 28,203, 13,118, 51,165, 84,146,101, 89,
- 98,140, 89,204,102,243,149,174,154,115,189,156,191, 2, 47, 43, 0, 9, 12, 12,140,230, 56, 78, 77, 8, 97,245, 19,189, 26, 91,
-185,134, 86,176,249,113,125,232,143, 1,128,195,225,112,106, 65, 9, 33,172,217,167,161, 44, 44, 22,139,211, 61, 56,142, 99,132,
- 16, 86, 89, 89,201,234,133,182,171, 51, 41,123, 59,127, 5, 94, 86, 0, 87,199, 29, 5,243,209,231,233,109,252, 21,244,180,192,
- 36, 37, 37,141, 22, 4,225, 17, 79, 12,227, 51,198,194,101, 89, 30,206, 24,123, 57, 37, 37,101,159, 39, 30, 64,225,175,240,191,
- 86, 5,184, 39, 38, 38,102,195,156, 57,115,186,117,137, 97,118,118, 54, 78,157, 58,133,200,200, 72, 24, 12, 6, 42, 73,210,180,
-148,148,148, 20, 15,188, 0,133,191,194,255,154,162, 64,136,142,142,182, 47, 92,184,176,219, 30, 96,211,166, 77, 48, 24, 12,120,
-244,209, 71,193,113, 28, 14, 30, 60,200,101,102,102, 30, 72, 76, 76, 76, 72, 77, 77,237,246,120,165,194, 95,225,223, 85,116,251,
- 64,152, 36, 73, 88,191,126, 61, 22, 44, 88,128,190,125,251,194,223,223, 31,137,137,137,136,139,139,227, 84, 42, 85,186, 94,175,
-159,232,203, 54,161,194,255,250,226,223,237, 10, 96, 48, 24, 16, 28, 28,140,136,136, 8, 8,130, 0,173, 86, 11,173, 86, 11,189,
- 94,143,145, 35, 71,114,106,181, 58, 67,175,215,199,249,234, 11, 80,248, 95, 95,252,187, 93, 1, 10, 11, 11,161,211,233, 26,143,
- 53, 26, 77,227, 67, 36, 38, 38, 98,248,240,225,188, 90,173, 62,145,144,144,112,131, 47,190, 0,133,255,245,197,191,219, 21, 32,
- 48, 48, 16, 86,171,115,118, 19,127,127,255,198, 79, 82, 82, 18, 98, 99, 99, 5, 63, 63,191, 44,189, 94, 31,235,107, 47, 64,225,
-127,125,241,239,118, 5,208,233,116, 48,153, 90,167,196,105,208, 98,173, 86,139,164,164, 36, 12, 28, 56, 80,165,209,104,206,234,
-245,250, 1,190,244, 2, 20,254,215, 23,255,110,223, 32, 35, 42, 42, 10, 53, 53, 53,176, 90,173,208,106,235,242,255, 84, 85, 85,
-161,180,180, 20,229,229,229, 40, 45, 45,133,197, 98,193,224,193,131, 33,138,162,250,234,213,171,231,245,122,253,144,180,180,180,
- 98, 95,120, 1, 10,255,235,139,127,183, 43,128, 90,173,198,248,241,227,145,147,147, 3,157, 78,135, 3, 7, 14,160,160,160, 0,
-177,177,177,136,138,138,194,208,161, 67,193,243, 60, 82, 83, 83, 97, 52, 26, 33,138,162,159, 70,163,201,211,235,245,131,210,210,
-210,188,158,237, 77,225,127,125,241,247,200, 22, 73,211,166, 77,195,167,159,126, 10, 81, 20,241,248,227,143, 99,230,204,153, 80,
-171,213, 78,101, 22, 45, 90, 4,147,201,132,117,235,214, 97,203,150, 45, 90, 74,233,155, 0,158,128, 15, 76, 75, 80,248, 95, 63,
-252, 61,178, 32, 38, 33, 33, 1,129,129,129,248,232,163,143, 48,123,246,108,183,171,168, 66, 66, 66,240,228,147, 79, 66,163,209,
- 48,171,213, 58, 54, 52, 52,180, 63,124, 32,177, 84, 75,254, 45, 43, 95,225,255,191,195,223, 35, 10, 16, 20, 20,132, 53,107,214,
- 32, 38, 38, 6,207, 62,251, 44,102,204,152, 1,135,195,225,182,252,144, 33, 67, 36,171,213,106,230,121,254,126, 95,120, 1,205,
-249,119, 4,189,141,191,217, 46,225, 82,105, 45,142, 95,174,192,190, 51,197,136,136,155, 70, 73,212, 40,191,136,184,169,207,196,
-175,248, 79,191,235,169,254, 61,182, 75,164, 32, 8,248,252,243,207,177,122,245,106, 0, 64,114,114, 50, 22, 44,112,189,251,145,
-159,159, 31,163,148, 74,140, 49, 13,124, 36,181,160,187, 94,171, 55,243, 63,122,169, 2,155, 50, 12,200, 41, 50,129,202, 82, 99,
- 90,119, 22, 54,158, 15,157, 50,118,124, 8,165,227, 41,149,151, 37,190,240,245, 22,202,196,215,210,255,184,232,244,255,122,253,
- 11,158,124,136, 63,252,225, 15, 0,128,216,216, 88,124,241,197, 23,110, 21,160, 25,122,251,146, 66,159,229,127,185,204,140, 55,
-191,205,134,192, 1, 49, 33, 26, 20,148,137, 96,148,130,177, 86, 31, 2, 70,231,129,146, 95, 76,126,118,253,188,140,119, 23, 37,
-119,250,189,111,248, 9, 89, 5,158,245,167,191,121,246, 94,168,120,238,154,235,223, 99, 10, 80, 84, 84,132,146,146, 18,188,249,
-230,155,120,238,185,231,176,120,241,226, 54,203,247,246,172, 10,190,206,255, 68,126, 37, 24,163,120,235,254, 9, 24, 17, 29,140,
- 63,109, 59,141,189, 89, 69, 96, 13,189, 64,227, 95,214,112, 76, 64,233, 59, 0, 58,173, 0,207,220, 61, 25, 14,201,179, 85,209,
- 82,248,187, 90,255, 30, 83,128,236,236,108, 68, 68, 68,224,217,103,159, 5, 33, 4,185,185,185, 46,115,234, 52,215,222,250,165,
-136,189,117,113,138, 79,243, 63, 83,104, 2,165, 20, 2, 87,103, 33,168, 56, 82,215, 3,180,248,180, 80,130, 27,110, 90,178,198,
-255,216, 63,150, 90, 58,243, 91, 57,133,229, 40,175,181, 94, 51,103,209, 97,119,235, 59,206, 26, 59, 24, 92,253, 18, 4,187,221,
- 14, 89,150, 57, 89,150,213, 0, 66,208,118,126,214,234,230,215, 59,164, 0,159,237,205,196,165,146,206,109,120,146,157,150,138,
-232, 81,147,240,202,198, 84, 72, 14, 59,206,156,191,136, 87,190, 78, 1,199,183,222, 56,239, 80, 77, 8, 95, 54,112,234, 72,235,
- 0,149, 86, 8, 31, 20, 13,144,118,133, 72, 82,227,143,248,114,101,165, 15,245, 0,180,190, 98,125, 50, 63,168, 67,148,193, 40,
-195,138, 47,143,162, 95,152, 22, 57,133,149,117, 2,207, 24, 24,163,160,204,165, 57, 4,217, 95,173, 6,208, 41, 5,200, 51, 86,
- 33,191,172,250,154, 57,239, 92,247, 49,210,183,111,236, 72, 81, 53,128, 59,235, 63,111,183, 83,246, 70, 0,103, 58,165, 0,250,
- 17,253,220,238,249,229, 14, 17, 86, 3,138,250,248,225,238, 73,195,240,233, 71,239, 33,208,223, 31, 63,143, 31,225,186,194, 82,
-183,211, 98, 83,126,161,228, 96,167,164,240,129,223, 18,158,111, 63,197, 96,165,214,210, 93,194, 65,171, 12,224, 66, 59, 54,162,
-110, 50,153, 96,179,217, 16, 21, 21,213,252, 52, 67, 83, 94, 32, 31,237,193,234, 4,221,108,151,113,174,200,214, 36,244,148,130,
- 82,230,214, 20, 2,215,249, 64,225,162, 91,110,236, 22,198,166, 67,201, 72,175,139,242, 32, 34,194,181,252,157, 57,115, 6,181,
-181,181, 13,141, 80, 25, 99, 44,215,205,237, 70, 1,173,246,153,232,152, 2,140,236,167,235,188, 61, 80, 58, 4, 63, 92,202, 65,
-148,202,129, 13,159,125,130, 25, 51,102, 96,242,176,104,151,101,163, 84, 14,234, 95,109, 40,179,150,151, 95,172,201,220,123, 8,
- 61,156, 98,220,113, 98, 61,184,136, 17, 80,199,253,162,221,178, 85, 85, 85,152, 59,119, 46,118,239,222,221,242,165, 80, 95,115,
-130, 25, 99, 16,229, 58,125, 92,126,199, 72,136,242, 8,103,253,100,117,255, 63,248,167,173,204, 14,129,184, 50,133, 0,128, 93,
-125,186, 97,177,139, 68,162,255, 42,181,247,187,203,255,189, 27, 39, 47,151, 92,187,227,158, 86,183, 59, 46, 55,106, 6,248,113,
- 83,157,174,237,122,105, 1,212, 2,143,105,211,166, 33, 61, 61, 29, 0,160,209,104,126,176,217,108, 15,187,145,159, 61, 0,102,
-244,152, 15, 48, 96,192, 0, 28, 59,118, 12,219,183,111,135,205,102,195,252,249,243,219,109,136,235,109,104,175,180,142,246,148,
- 15, 64, 56, 30,170,209, 63,111,183,244,217,179,103,113,199, 29,119, 96,231,206,157,232,211,167,143, 15,240,119,150,233,140,188,
- 10,164,158, 47, 65, 70, 94, 57,204, 86, 7, 40,149, 91,181,240, 78,231,160, 34, 13, 38, 80, 75, 83,232,181,159, 93,137, 4,112,
-174,241, 25,175,254,238, 44,152,188,140,196,172,118,155,175,245,131, 71,110,235,150,103,121,222,122, 18,239,103,236,192,138,123,
-226,241,240,195,191,236,136,194,119,186,225,236,144, 2, 56, 36, 25,148,117,174,103, 55,219,108,216,187,119, 47,100, 89, 70,100,
-100, 36,102,205,254, 25,108,162,228, 38,118, 72, 64,121, 1,208,104, 57,220,189,212, 15,186,232,246, 31,100,237, 43,246,142,248,
- 10,157, 81, 2,219, 79,127, 5, 8, 15,213,168,187,218, 45,157,149,149,133, 59,239,188, 19, 59,119, 54,238,236,234, 19, 81,160,
- 79,246,229,226,199,204,162, 38, 97,111, 33,216, 77, 2,206,156,237,125, 23,166, 80,235, 42,162, 28,152,116, 35,152,252, 29, 51,
- 44, 25, 72, 6,252,163,194, 21,135,175,211,114, 96,232, 6, 31,224,104,110,221,252,182, 31, 79, 94, 66,217,119,206, 43, 33,127,
-119,215,205,224,185, 86,238,150,103, 20,224,181, 77,169,157,138,235, 58,204,213, 72, 91,243, 18, 26, 50, 5, 14,152,181, 24,143,
-253, 99,143,251, 22,181, 50, 92, 85, 26, 59,123,170, 72, 84,163, 4, 77,240, 47, 96,110,223,142,150, 22,190,189, 24, 27, 96,236,
-238,158,192,118,224,207, 0,199, 67, 53, 98,118,187,165, 51, 51, 51, 49,123,246,108, 76,154, 52, 9,245,137,182,188,170, 0, 57,
- 87,107,240,227,233,171,237, 10,182,187,191,172,222,236,113, 45,252, 18,192,228,186, 15,149, 2,192,228,223, 0,120,195,165, 73,
- 27,226,223, 24,161,185, 22,204,152, 53, 27, 67, 6, 13, 68,220,164,201,232, 31, 17,210, 34,232,224,218,138,104,227,118, 31, 3,
-216, 6,160,184,211, 10,240,214,194, 91, 58, 69,124,225,194,133,176, 86,214,217,128, 43, 86,172,192, 27,111,188,209,102,249,167,
-159,126,218,177,235,232,174, 93,165,165,165,187, 42, 42, 42,190,132, 87,183, 25, 98,176,237,255, 35, 8,199, 67, 24, 62,171,221,
-210, 39, 78,156, 64, 97, 97,161, 42, 40, 40,136,247,182, 15,176,247,140,177, 93,193,102, 45,206, 57,149,173,239, 33,154,161,118,
-214,232,138, 64, 48, 9,160,178,179, 18, 48,233,255,220, 41,192,164,161,125, 33,201,215,254, 10,111, 31, 59, 8,192,189, 46,175,
-185, 81,176,182, 26,206, 45, 93,238, 1, 58,131, 77,155, 54, 97,243,230,205, 0,128,233,211,167, 99,220,184,113, 29, 14, 35,250,
-130, 13, 93,223,213,195,186,247,109,104, 9, 15, 97,216,204,118,139,151,148,148,112, 85, 85, 85, 51,181, 90,237, 78,111,210, 46,
- 40, 51,183, 22,108, 39,211,135,181,109, 10, 81,218,232, 24,215,139,211, 14, 63, 34,198,131,214, 11,190,179, 18,244,101,185,247,
- 69, 76, 93, 92,236,210, 98,200,204,247,236, 72,240,182, 23,230, 65, 45,240, 61,227, 3,116, 20, 70,163, 17,203,150, 45, 3, 0,
- 60,245,212, 83, 88,190,124, 57,222,127,255,125,220,119,223,125,237, 9,191,207,216,208, 78, 74,176,231, 13,104, 57, 30, 66,236,
-244,246,205, 62,135, 35, 66,146,164, 21, 0, 54,163,110,176,165,199, 81,108,178,180, 22,236, 86,145,157, 54, 76, 32,103, 63,239,
-220,188,201,149,175,129,138, 59,235, 91,252,230, 38, 80,195,255,195, 93,241,248,243,131,183,122,235,173,121, 70, 1, 58, 58, 16,
-182,229,253,151, 80, 94, 94,142,126,195,227,224, 55,241,110,124,188,247, 44, 54,126,247, 3, 28, 3, 39, 35,172,175,251, 73,134,
-233, 53,193, 66,241,128, 91, 38, 89, 7,106,116, 66,112,244, 77, 62, 51, 16,198, 40,172,187, 95,131,246,118, 30,194,144,169,237,
-215, 62,165, 35,234,237,204,159, 1, 48,247,228,155,183,139, 50,202,170,173,109, 10, 56, 24,197,168,126, 97, 24, 30, 19, 10,127,
- 53, 95,175, 36, 12,187,247,236,145, 10,140,101,217, 18,175,189,164, 14, 31,144, 77,128,172,111,127,115,246,252,128, 80,219, 23,
- 96, 82,180,139,214, 31,245,102,209, 48, 87,202,254,238,119, 25, 56, 95, 84,225,209,231,253,248,241, 89,174,230, 2,121, 70, 1,
-166,223, 56, 16,147,134, 58,218,142,138,156, 58,129, 11,199,211,160,235, 19,129,127,253,123, 45, 34,162,250,226,245,149,207,162,
-164, 32, 23,255,120,254, 33, 68,247,235,143, 71,150, 62,137, 95, 44, 92,212,186,235, 78,219, 78, 75,170, 46, 94,144,236, 72,167,
-129,186,253,224, 85,237, 63,136, 40,246,140,128, 81, 25,214, 93,175, 64,123,199, 27, 16, 6, 37,118,228, 27,183,212, 43,193, 28,
- 0,214,158, 82, 0,158, 35, 0, 99,110,109,252,176, 64, 53,126, 63,111, 18,110, 30, 80, 14, 34, 93, 6, 88,211,134,246, 55,251,
-149, 18,201, 94,174,234, 19, 74,252, 71, 13,171,138, 38,160,119,130, 74,227, 65,101,190,141,214, 31, 96, 82,128, 43, 5, 88,144,
- 56, 10, 86,187,103,115, 4, 11,174, 7,232,152, 71, 20, 32, 54, 42,180,221, 50, 23,143,213,201,227,250,117, 95, 96,230,228,177,
- 88,191,126, 61,190,251,230,171,198,235, 87, 11,175,224,237,151, 95,192,200,193, 49,120,224,129, 7,156,190,219, 71, 37,202, 1,
-181, 87, 75,106,141,198,139,181,153,123, 79,194,215,246,218,165, 18,172, 59, 95,134,118,214,155, 0, 58, 52, 71,253, 86, 0,223,
- 1,184, 27,128,173, 39, 40, 10, 60,135,240, 0, 21, 74, 76, 98, 43, 27,159,128,225,181, 7,166, 96, 92,216, 15,224,106,178, 90,
-125, 87, 63, 30, 60, 88,232,104, 80,121,180,139, 86, 30,173,148,160, 73, 17,114, 80, 55,247,198, 9,102,155, 3,213, 86,199,255,
-142, 9,212, 17,148,151,151, 35, 52, 52, 20, 51,103,214, 57,141,111,189,245, 22,198,141, 27,135,249,243,231, 35, 47, 47, 15, 35,
- 71,142,196, 59,239,188,131, 23, 95,124,177,149, 2, 52,115, 96,124,119, 54,168, 44,194,150,242, 30,144,240,118, 71,191,113, 27,
-128,135, 0,252,163,167, 40,246, 13,209,194, 88, 89,219,202,244,153,114, 67, 20,198, 70, 21,128,171,205,114,209,102,182, 16,112,
- 87,166,142,203,243, 50, 64,165,179, 0,166,180,188,229,206, 83,151,112,161,216,179,214,233,196, 33, 81, 16,122,202, 4,170,181,
- 57,218, 13,107,197, 12, 28,140, 81,163,111, 68,149,217,134,146, 18, 35,114,115,115,241,205,214,239, 16, 63, 37, 1,143, 62,180,
- 8,171,222,125, 15, 34, 5,126,191,226, 57,100,229, 92, 64,255, 1, 77,115,111,236,148, 16, 89,229,175,146, 2,250,248,225,230,
-135, 67,161, 13,110,255, 65,198,163, 26,175,190,218, 99, 61, 5,231,175,131,118,206,187, 40, 55,117,184,151,125,191, 39,133, 31,
- 0,134, 68, 4,226,100, 94, 73,171,112,231,232, 1,225, 32,226,233,214,214, 66, 91,173, 60,117,161, 4,206,231,175,144,184,148,
-226,164,164,164, 86, 60,150,253,108,146,119,226, 22,158,138, 2,253,101,219, 17,100, 27,218, 14,107,201, 14, 59, 78, 95,184,132,
- 37,107,118,128,202, 18,180, 33, 58,124,145, 85,131,245, 57,251,144,117,165, 2, 75,214,236,128,100,139, 0, 39,168,240,252,231,
- 59, 17, 24,209,228, 20,103, 85,135,169,138, 7,207,184,205, 65,212, 99, 4, 77,224, 67, 29,114,130, 79, 9, 75, 0,148,244,152,
-240,207,253, 0, 92,232, 64,192,148,223, 81,225,255, 93, 79, 11,192,188,248,193,248,238, 72, 30,100,217, 57,220, 25,232,167, 2,
-161,181, 78,206,125,199, 90,249,230,202,209,226, 26,240, 23,119, 60,126,253,207,157, 56,158,231,217, 44, 43, 7,223,248, 85,171,
- 48,168,199,122,128, 87,238,239,144,243,135,249,199, 55,227, 47,247,223,132, 1, 3, 6,224, 29,249, 34,180,154, 34, 44, 95,190,
- 28,203,243,247,225,165,135,146,224,231,231,135, 81,127, 95,129,109,111, 62, 1,190,217,180,232,103,158, 57,232,216,115,108, 79,
-178,209,104,252,161,188,188,124,191, 47,249, 0, 78,194,223, 49,124,224, 13,225, 7,128,200, 16, 45,102,143, 31,128,173,135,115,
-157, 28, 96,231, 9,112,157,106,229, 91, 40,135,220,240,106, 74,219,234,221,254,254,248, 44,175,188,171,102,251,187,245,188, 15,
- 0, 0,127,255,251,223,241,252,243,207,227,239,127,255, 59, 94,120,225, 5, 36, 39, 39, 67,146, 36,140, 27, 55, 14,199,143, 31,
- 71,126,126, 62,238,184,227, 14, 39,225,111,230,189,203,148, 82,159,154, 78,220, 89,225,231,121,254, 27, 89,150,127,231, 77,206,
-191,190, 35, 14,126, 42, 14, 7, 78, 27, 80, 92, 89, 11, 6, 82, 63,106, 74, 1, 38,186,108,229,101, 81, 6,152, 36, 19, 34, 83,
- 14, 50,117,171, 4,117, 14,253, 81, 0,207,146,184, 84,183,211,209,119,158,186,132, 18,147,197,163,207,185, 48,105,116,171,185,
- 64,245, 38, 16,243,154, 2,232,116, 58,188,248,226,139, 88,185,114, 37,238,186,235, 46,220,123,111,221, 48,246,152, 49, 99,240,
-250,235,175,227,198, 27,111,196,154, 53,107,220,105, 47,245,165,129,176,206, 10,127, 80, 80,208, 17,149, 74,245, 65, 69, 69,133,
- 87,121,171, 4, 14, 75,102,197, 97,201,172, 22, 9,148, 77,123, 1, 42,186, 52,117,254,181, 45,216,158,113,228,196,231,209, 97,
-214,159, 94,249, 77,255,227, 42,158,177,102,189,193,121, 18,119,176, 83, 61,178, 40, 83,183, 19, 31,123,101, 20,232,147,157, 39,
-144,107,172,234, 56,139,209,183,227,131,173, 7,241,202,223,214,163,232, 66, 54,170,203,141,144, 28,118,140,184,255,183,120,225,
-203,159, 90,219,115,213, 33,234, 43, 3,111,157,105, 25,172, 29, 42,248,135,221,215,145, 69, 85, 18, 52,175, 99,211,211, 21,190,
- 32,252,227,198,141,147, 36, 73,218, 89, 88, 88,232, 91,225,219, 22,161,220,186, 86,189,181,169,179,244,238, 18,205,210,187,162,
-150,128,201, 75, 90,181,254, 96, 97, 0,170, 58,243, 83,115, 38, 14,245,150, 19,236, 25, 19,104,214,184, 33,168,181,117, 50,174,
-123,155,243, 62, 6, 75, 23,221,143,135,166,141,113, 89,180,228,200,143, 82, 85,213,197,147,146,168, 74,113, 12,158,156, 5,194,
-117,224, 65,170,107,125, 65,248,151, 45, 91, 6,198,152, 99,223,190,125, 62,190,168, 95,114,107, 2, 57, 69,129, 84,209,102, 16,
-129,192,122,222,191,203,102, 88, 39,157,224,221, 47, 63,128, 32,173,218,119,123,128,142, 12,132,181,135, 49,163, 70, 96,236,160,
- 72,151,215,250,168, 68, 57,168,182,176,168,186,176,240,172,249,232,182,147,222,242, 3,186, 34,252,239,190,251, 46,158,121,230,
- 25,230,107, 38, 92,235,214,145, 7,105, 48,129,220,216,248,148,105,109, 92,236,218, 0, 16, 14,184,176,160, 22,142, 66,127, 0,
-246, 78,251,130, 94,114,130,225,205,129,176,230, 56,113,226, 4,190,252,242, 75, 76,157, 58, 21,115,231,206, 5, 0, 12, 29, 58,
- 20,178, 44,187,114,128, 27, 39,195,213, 59,193,232, 77,194,239, 43,252,219, 85, 0,213, 96,192,156,222,102,180,135, 48,137,135,
- 92, 13,112, 26, 64,174, 38, 0, 78,146,184, 84,171,175, 61,203,246,237,219, 81, 88, 88, 8, 0, 40, 46,110,234,105, 40,165, 19,
-209,148, 31,116, 63,128,156, 30, 87, 0, 74, 41,230,205,155,135, 43, 87,174,224,227,143, 63,198,241,227,199, 49,114,228, 72,132,
-132,132,192,106,181, 34, 48, 48,208,149,237,230, 85, 39,152,248,247,233,178,240,251, 2,255, 14,189,151,192, 89,224, 44,135, 64,
-172,103, 93,155, 64,160, 32,128, 10,231,127,110, 7, 56, 6, 38,137, 0,150,250,226,179,172, 94,189, 26,251,246,237,115, 37,123,
-115, 80, 55, 7, 11, 0, 30,243,138, 2,212,214,214,226,202,149, 43,141,202,208,208,226, 23, 23, 23, 67, 20, 69,119, 17, 32, 48,
-198,168,220,176,132,172,135,161,185,249, 49,128,227, 59, 84,182, 95,191,126, 78,194,239, 11,252, 59,166,229, 42, 72, 81,175,131,
- 51,167,129,171, 88, 7, 98,191,220,220,209,109,214, 26,201,118, 64,126, 15,192,123, 36, 46,213,228,139,143,242,231, 63,255, 25,
-149,149, 77, 83, 45,254,246,183,191,217, 14, 31, 62,188,174,180,180, 52, 77, 20,197,252,250, 7,202,233,200,189,186, 93, 1,130,
-131,131,113,251,237,183, 35, 59, 59, 27,159,127,254, 57,134, 15, 31,142,140,140, 12, 24,141, 70,132,133,133,185,127, 63,222,204,
-172,214, 65,225, 7,220,231,172,236, 29,153,237, 8,104, 64, 34,104, 64, 34, 32, 87,129, 56, 10, 64, 28, 6,108,217,188,209,158,
-151,119,225,115,115,109,229, 87, 99,134, 9, 63,205,127,250,156, 79, 63,199,216,177, 99,157,142,183,109,219, 38,231,230,230, 94,
- 48,155,205,135, 76, 38,211,185,206,248,144, 30,241, 1, 54,110,220,136,215, 94,123, 13,159,125,246, 25,190,255,254,123,232,116,
- 58,124,240,193, 7,237,125,173, 87,167, 70,236,117,252,249, 80, 48,109, 40,152,118, 44, 82,206,236,147,246,239,207, 62, 87, 80,
- 80,126,165,170,170,138, 94, 79,245, 47, 0,128,201,100, 18, 50, 50,186,119,255,228,150,171,192, 78,158, 60,233,182,172,201,100,
-226, 9, 33, 93, 54, 33, 60,193,191,147,191,175,240,239,165,252, 5, 0,198,226,226,226, 83,171, 86,173,226,237,118,123, 52, 99,
- 76, 13,128,213, 71, 54, 88,179, 15,234,207, 55,254,223,242,154,187,235, 45,238,213,178, 44,147,101, 89,150, 36,169,164, 62,189,
- 96,103, 67,160, 10,127,133,127,151,249, 55, 31,114,229,116, 58,221,114, 0,125,209,148,229, 76,102,140, 73,132, 16,153, 49, 38,
- 19, 66,164,102,231,104,179,107, 13,231,101, 66,136, 84,191,184, 93,110,184, 70, 8,145, 41,165, 82,139, 99,185,193,110,166,148,
- 74,178, 44, 75,140, 49,139,217,108,190,210, 85, 75, 94,225,175,240,239, 44,255,230, 10, 64, 2, 3, 3,163, 57,142, 83, 19, 66,
-152, 74,165,130, 40,138,141, 90,214,160,133,205,143,235, 67,127, 12, 0, 28, 14,135,147, 6, 19, 66, 88,179, 79, 67, 89, 88, 44,
- 22,167,123,112, 28,199, 8, 33,172,178,178,146,213, 87, 90, 87,215,210, 41,252, 21,254,157,230, 79,218, 57,238, 40,124,101, 6,
-167,194, 95,225,223, 35,132,187, 5, 73, 73, 73, 2,128,217, 28,199,221,247,211, 79, 63, 45,238,109, 97, 7,133, 63,144,148,148,
- 52, 90, 16,132, 71, 8, 33,221, 46, 75,140,177,112, 89,150,135, 51,198, 94, 78, 73, 73,217,231,137, 58, 16,186,169, 34,251, 1,
- 40, 79, 73, 73,177,117,176,252,120,181, 90,189,132, 49,246, 43,157, 78,199,149,149,149, 9, 0, 22,123, 81, 16, 20,254, 93,231,
-127, 67,100,100,228,147,115,230,204,241,235,206,103,202,206,206,198,169, 83,167, 16, 25, 25, 9,131,193,176, 59, 41, 41,105, 90,
- 74, 74, 74,138,207, 40, 64, 82, 82, 82, 8,128,121, 90,173,246,215, 14,135, 99,188, 32, 8, 59,146,146,146,230,166,164,164, 48,
- 55,229, 35, 57,142,123, 80,173, 86,255,159, 32, 8, 81,241,241,241,154, 73,147, 38, 9, 90,173, 22,111,190,249,166,205, 11, 66,
-163,240,239, 38,254,209,209,209,246,133, 11, 23,118,155, 2,108,218,180, 9, 6,131, 1,143, 62,250, 40, 56,142,195,193,131, 7,
-185,204,204,204, 3,137,137,137, 9,169,169,169, 25, 94, 83,128,164,164, 36, 53,128,217,126,126,126, 75,101, 89,158, 62,108,216,
- 48, 41, 62, 62, 62,104,232,208,161, 88,179,102,205,173, 37, 37, 37,239, 2,120,166, 69,249,185, 90,173,246, 73, 73,146,226,227,
-226,226,104,124,124,188,255,224,193,131, 27, 38,144,193,106,181,246,164,208, 40,252,189,200,191, 35,144, 36, 9,235,215,175,199,
-210,165, 75, 17, 22, 22,134,218,218, 90, 36, 38, 38,130, 82,202,101,101,101,165,235,245,250,155,211,210,210,142,247,152, 2, 36,
- 37, 37, 17, 0, 73, 26,141,230, 49, 74,233,188,190,125,251,202, 83,166, 76, 9,137,139,139,131,159, 95,147,210, 63,246,216, 99,
- 1,239,189,247,222, 19,183,220,114, 75, 14,165,244,148, 70,163, 89, 74, 41,157, 31, 19, 19, 67, 19, 18, 18,130,227,226,226,160,
- 82,169,188, 97, 30, 40,252,189,200,191,179, 48, 24, 12, 8, 14, 14,110,220,124, 68,171,213, 66,150,101,232,245,122, 72,146,196,
-229,228,228,100,232,245,250,241,105,105,105, 89, 30, 85,128,122,231,102, 49,199,113,143, 6, 6, 6,170,227,227,227, 3, 38, 76,
-152,192,135,132,132,184, 44,239,239,239,143, 37, 75,150,248,175, 94,189,250, 35,173, 86,235,152, 50,101,138,118,226,196,137,124,
-104,104,104,183, 85,206,244,233,211,251,216,237,118,154,158,158, 94,209, 1,193, 81,248,123,145,127, 87, 81, 88, 88, 8,157,174,
-105, 71, 34,141, 70, 3, 89,150, 33,203, 50, 18, 19, 19, 33,203, 50,127,225,194,133, 19, 9, 9, 9, 55,166,167,167,159,239, 86,
- 5, 72, 74, 74,138,225, 56,238, 87,106,181,122, 9,199,113, 49,147, 38, 77, 18,110,186,233, 38,117,223,190,125, 59,116,179,136,
-136, 8,172, 92,185, 82,237,239,239,175,238,206, 74, 73, 76, 76, 28, 17, 16, 16,176,210,110,183,223, 86, 93, 93, 29,219,134,208,
- 40,252,189,200,191, 59, 16, 24, 24,216,202, 44,243,247,247,111,220,212, 59, 41, 41, 9,178, 44, 11,151, 46, 93,202,210,235,245,
- 35,211,210,210,242,186, 69, 1,146,146,146, 18, 4, 65,216, 59,102,204, 24,122,243,205, 55,251,199,198,198,162, 43,145, 45,127,
-127,255,110,171,140,169, 83,167, 78, 11, 8, 8,120,153, 82,154, 16, 16, 16,160,150,101,249,163,236,236,108,135, 27,225, 81,248,
-123,145,127,119, 65,167,211,193,100,106, 61, 11,187,193, 20,146,101,185, 65, 9, 84, 5, 5, 5,103,245,122,253,176,180,180, 52,
-195, 53, 43,128,159,159,223,107,208,238,250,153, 0, 0, 20,252, 73, 68, 65, 84,119,222,121,167, 58, 33, 33,129,131, 23, 49,125,
-250,116, 65,150,229,251,252,253,253, 95,241,247,247,239,255,224,131, 15, 6, 76,159, 62,157, 44, 88,176,192,102,177, 88, 62,114,
-247, 61,133,191,119,249,119, 23,162,162,162, 80, 83, 83, 3,171,213, 10,173, 86, 11,160,110, 99,194,210,210, 82,148,151,151,163,
-180,180, 20, 22,139, 5,131, 7, 15,134, 40,138,234,171, 87,175,158,215,235,245, 67,210,210,210,138,187,172, 0, 73, 73, 73, 35,
- 1, 36, 77,154, 52,201,107,149, 31, 31, 31, 31,172,209,104,150, 8,130,176, 98,232,208,161,154,135, 30,122, 40,104,202,148, 41,
- 32,132, 96,247,238,221, 16, 4,225, 84,122,122,250, 69, 55,173,167,194,223,139,252,187, 19,106,181, 26,227,199,143, 71, 78, 78,
- 14,116, 58, 29, 14, 28, 56,128,130,130, 2,196,198,198, 34, 42, 42, 10, 67,135, 14, 5,207,243, 72, 77, 77,133,209,104,132, 40,
-138,126, 26,141, 38, 79,175,215, 15, 74, 75, 75, 43,237,146, 2,104, 52,154,151,166, 78,157,170,242, 70,148,160,186,186, 26, 28,
-199,169, 2, 3, 3,139, 38, 79,158,140, 95,253,234, 87, 1, 55,220,112,131, 83,153,111,190,249,166,166,182,182,246,207,238,238,
-161,240,119,195,205, 38,225,167,139,165, 40,169,113, 64, 45,112, 80,243, 4,106,158,131, 70,224, 48, 97, 64, 40,250, 6,251,117,
- 11,255,238,198,180,105,211,240,233,167,159, 66, 20, 69, 60,254,248,227,152, 57,115, 38,212,106,103,183,102,209,162, 69, 48,153,
- 76, 88,183,110, 29,182,108,217,162,165,148,190,137,166,245,192, 29, 87,128,164,164,164,104, 74,233,189,122,189, 94,232, 73,193,
- 41, 44, 44, 68, 74, 74, 10,206,157, 59,135, 57,115,230,240, 11, 22, 44, 8,136,140,108,157, 53, 34, 63, 63, 31, 5, 5, 5,148,
-231,249,111,221,180,158, 94,231, 63,243,206,159,241,139,127,249,128, 79,240,183, 75, 20,169,121,229,216,157, 83,130,140,252, 74,
-136,110,146, 26, 19, 0, 3, 53,118,220,104,207,198, 67,119, 37,240,183,205,127, 34, 32, 50, 50,170,211,252, 61,129,132,132, 4,
-124,253,245,215,120,227,141, 55, 16, 19,227, 62, 29,125, 72, 72, 8,158,124,242, 73,108,223,190,157,213,212,212,140, 13, 13, 13,
-237, 95, 85, 85,117,165, 51, 74, 32,168,213,234,231,110,186,233, 38,174, 59,157, 39,119, 96,140, 33, 39, 39, 7,169,169,169,168,
-172,172,196,125,247,221,135,215, 95,127,189, 77,199, 45, 57, 57,217,193, 24, 91,179,127,255,126,201, 77,151,233, 85,254,137,243,
- 30,197,211,235,126,194, 61,178, 10,145, 94,228,207, 24,240,245,113, 3,214, 30, 42,128, 85,108,127, 93, 8, 3,144,111,215,224,
-151,131,181,184, 91,216, 3,203,119,199, 96, 31, 57, 3,252,144,169, 16,162,199, 55, 46, 19,109,143,191, 39, 16, 20, 20,132, 53,
-107,214,184, 93,126,218, 18, 67,134, 12,145, 12, 6,131,153,231,249,251, 81,151,152,184,227, 10,192,243,252,207, 39, 77,154,164,
-241,228, 3, 73,146,132, 99,199,142, 33, 45, 45, 13, 1, 1, 1, 88,184,112, 33,166, 77,155,230, 50, 69,138, 83,107,102,183, 99,
-231,206,157,212,106,181,254,205, 93, 25,111,242,207,200, 45,198, 93,171,190,129,213, 33,225,238,119,190,193,190, 87, 23, 34, 58,
- 44,176,199,249,151,155, 29,120,251,199,115, 56, 90,208,249,156,252, 19, 2,235,190,227, 47, 85,193,145,181, 5,200,218, 2,226,
- 23, 12, 97,144, 30,108,128, 30,251,246,180,205,223, 83,232,168,240,215, 7, 16, 24,165, 84, 98,140,105,208,201, 9,158, 2, 0,
-194,113,158,241,189,204,102, 51,210,211,211,113,248,240, 97,140, 26, 53, 10, 43, 86,172,232,240,174,145, 0,176,111,223, 62, 8,
-130,112, 36, 45, 45,173,173,156,228, 94,225,159,109, 40,195,188,119,183,194,234,168,107, 24, 11,202,170,113,239,159,147,177,243,
-165,249, 8,214,106,122,140,191,201, 38,225,183,155, 51, 81, 80,209,249,100,180, 4,192,248,160,214, 89, 15,153,173, 26,226,185,
- 29,192,185, 29,248,247,108,162, 82, 17,246, 23,242,192,148,100,104,196,239,195,151, 30,243,201, 76, 17,245,232,218,154,224,238,
- 70,105,105, 41, 82, 83, 83,145,153,153,137,105,211,166,225,195, 15, 63,196,128,102, 27, 98,116, 20, 61,237,124,117,148,127, 65,
- 89, 53,230,190,243, 13,170,204,206,115,200, 50,243, 75,176,240,253,109, 72,126,238, 94,168, 5,222,227,252,173,162,140,231,147,
- 79,119, 73,248, 1, 32, 86, 91,139, 16,161,237,245, 35, 42,142,241, 0,230, 49, 96, 58,236,170,229,229, 31, 76,249, 74,144,201,
-218,144,167,211,189,155, 5,152, 81,128, 52, 53, 28, 93,205,202,209,173, 10,144,151,151,135,148,148, 20, 20, 22, 22, 98,238,220,
-185,120,238,185,231,208,213,161,248,220,220, 92, 92,189,122, 85,140,142,142,254,111, 79,213,105, 71,248,151,152, 44,152,179,106,
- 19,174, 86,185,222,163,111, 95, 86, 62,150,124,178, 3, 47,222, 57,210,227,252,255,153,122, 25, 57,198,154,182, 91,121, 2,232,
- 71,244, 71, 76, 88, 0,204, 54, 17,149,102, 59, 14, 95, 40, 2,101, 12, 19,130, 42,219,234,151,144,122,133,179,199,199,208, 39,
- 52, 4, 7, 67,151,165,229,250, 66, 19, 79, 45,229,176,253,176, 18,204, 82, 6,245,228, 37, 80,141,184,163,177,245,175, 95, 74,
-217,233,244,232,215,180, 26,135, 82,138,204,204, 76,164,166,166, 66,150,101, 60,240,192, 3,184,253,246,219, 91,133,173, 58,139,
-173, 91,183,218, 41,165, 31,111,218,180,169, 61,173,238, 49,254, 53, 86, 7,238,249,211, 22,228, 22,183,157, 44,121, 99,122, 14,
- 12,185, 57,178,218,131,252, 47,150,214, 34,249, 84,161,219,235,129,126,106,172,184, 39, 30, 11, 18, 71,161,127,120,144,211,181,
-203, 37, 38,124,180,227, 56, 6, 95,106, 61,159,204, 6, 13,252, 96, 7, 24,197,153, 50, 97,227,220, 63,166,172,245, 37, 27,135,
- 85, 23, 65,174,200,173,219,179,109,223,219, 16,179,147, 17,227, 7, 82,191, 32,158,118,197, 7,232, 18, 28, 14, 7, 14, 29, 58,
-132,244,244,116,244,239,223, 31, 79, 60,241, 4,226,227,227,209, 29, 11,131,108, 54, 27,246,236,217,195,108, 54,219, 39,158,170,
-200,206,242,183,139, 50, 22,188,247, 45, 78, 94, 54,118,232,254,233, 37,224, 53, 33,137, 20,216,227, 17,254,255, 72,201, 3,117,
-163, 58,209, 97,129,216,242,236,189, 24, 55,216,117, 50,226,193,145, 33,120,247,161, 91, 81,242,229, 23, 78,155,156,214,112, 65,
- 8,162, 77, 61,202,226, 56,199,224, 23,124,204,200,231,251,142,129,118,214, 27,176,238,124, 9,144, 69,200, 37,103,241,255, 6,
- 16,149,223, 20,255,193,111,109, 39, 93,234, 1,186,132,109,219,182,129, 82,138, 85,171, 86, 97,248,240,225,221,250,144,123,246,
-236,129, 32, 8,169,169,169,169, 69,158,170,200,206,240,167,140,225,145,143,183, 99,127,118, 65,167,126,195,206,107, 95,230,231,
-175, 58, 39,111, 92,185,161, 59,185,151,155, 29,200,200,175,116,217,216, 13,208, 5, 97,247, 43, 11, 49, 64, 23,212,142,187, 40,
- 66,107,174,123, 30, 17, 2,100,162,114, 18,126, 0, 80,243,152, 90,249,158,126,124,216,239,210, 78,250,146, 18, 8,131,244,208,
-206,122, 3,182,157, 47,131,201, 14,240,132, 97,241, 36,191,113, 83, 6, 14,122, 88, 16,134,173,155,252,234,225,234,142,222,139,
- 67, 23,246, 21, 48,155,205,200,204,204,196,202,149, 43,187, 93,248, 27,156, 95,179,217,220, 81,231,209,227,252,151,125,182, 27,
- 91,143, 92,232,202,163, 16,194,176, 86,184,127,213,140,238,228,191, 35,171, 16,204, 77, 79,255,135,121,250,246,133, 31,128, 92,
- 94,103, 70,128, 87, 33, 48,225, 9,248, 49,215, 11, 99, 40, 47,223,235,139,225, 30, 97,144, 30,126,179,255, 8,162,210, 54,158,
- 27, 17,169,158, 52, 52,156, 28, 42,251, 48, 97,164, 71,123,128,163, 71,143, 34, 33, 33,161,205, 92,159, 93,197,185,115,231, 80,
- 82, 82, 98, 59,120,240,224, 78, 79, 85, 94,103,248,191,254, 77, 42, 62,219,155,121, 45, 63,167, 6,144,172, 90,240,206, 45,226,
-215, 47,156,234, 14,254,169,103, 93, 79,126, 28,216, 39, 24, 11,147, 70,119, 44, 94, 88,114, 6, 32, 28,180,183,191, 6, 97,112,
- 18,196,236,100,208,106, 23, 62, 5, 35, 9, 61,102,223,215,150, 64, 42, 60, 6, 72,118, 48, 89, 4,100, 7, 24, 21, 65,168, 4,
-230,176,130, 57,106,193, 28,181,128,104, 1,179,155,235,254,111,189, 51,234, 40,194,216,225,242, 15, 19,230,235,158, 74,255,177,
-219, 21,128, 82,138,140,140, 12,188,252,242,203, 30,169,132,173, 91,183,218, 68, 81,252, 0, 30, 74,149,209, 25,254,127,251,241,
- 56,222, 73, 62,212,120, 28,164, 85, 99, 70,220, 32,216, 68, 9, 63,158,188,228,186, 66, 9, 16,224,168, 56,100, 82,133,107, 0,
- 76,168, 63, 29,204, 40,251,193,239,129, 85,122,219, 87, 43, 47, 95, 43,255,203,149, 86,128,104, 91, 93, 91,116,203,141, 80,241,
- 29, 27, 83,160, 37,103,161,137, 95, 10, 97,112,221, 62,191,170,225, 51, 97, 63,246,133,139, 62, 12, 61,178,233,175,116, 97, 39,
-172,123,223,118, 37,208, 93, 65, 48, 24,219, 94,241, 97,252,178,240,167, 14,255,173, 61, 19,168, 83, 56,127,254, 60,130,130,130,
- 16, 23, 23,215,237,149, 96,177, 88,176,127,255,126, 56, 28,142,127,122,170,162, 59,202,255,235,180, 28, 60,183,110, 31,162,195,
- 2,241,248,109,227,240,237,138,121, 48,124,242,127,216,240,219,185,109,239,129, 69, 37,140, 40, 73,253,185,180,105,229, 68, 9,
-100, 16, 1,158, 2,176, 27, 64,164, 36, 99, 7,238,125, 91,119,173,252, 45,196,245,250,243,168,144,128,142,219,102,234, 0,168,
-199, 63,208, 36, 8, 49, 19,221, 21, 13,233, 9, 5, 16,207,239,236, 46,225,111,244,151, 25, 35, 31,151,127,144,240, 62,123,213,
-189,156, 11,157,221, 91,245,240,225,195,248,197, 47,126,225,145, 74,216,181,107, 23, 83,171,213,123,247,236,217,211,225, 13,176,
- 61,193,127, 87,230,101,252,117, 91, 6,214, 44,189, 19, 11,244,163, 58,220,170, 2, 0, 3,145,210,210,210,234,248,111,122,161,
- 64, 4, 62, 2,240,145,102,193,159,134, 74,178,252,172, 32,112,155,164,251,255, 58, 7,155,158,182,118,149,191,138,143,133, 67,
-110,253,181,176, 64,103,197, 56,124,161, 8,195,163,195, 17,222,226, 60, 24,133,122,226,131,206, 78,180,228, 54, 49, 4,199, 54,
-222,207,147,249,155, 60,154,249,218,111,198,139,144, 75,178, 1,209, 10, 38, 90,193, 28, 22,192, 81, 3,106, 53,129,150,157,131,
- 92,226, 58,221, 63, 31, 58, 16,124,248, 96, 64,208,128, 89, 42, 32, 22,157,172,223,240,163, 65, 64,216,242,242,176, 41, 67, 75,
- 62,246, 91, 24,249,155,253,181, 93, 54,129, 24, 99, 40, 47, 47, 71, 65, 65, 1,110,187,237, 54,143, 84,194,166, 77,155,204,213,
-213,213,239,122,196,190,236, 32,127,179, 93,132,192, 17, 28,122,251, 33,116, 37,162, 75, 9,231,114, 79, 45,251,215,207,231, 2,
-248, 53, 22,190, 21, 37,136,142, 9, 18,144,214, 85,254, 1,125, 71,194, 97,110,253, 51,205,103,126,214,218, 28,120,107, 75, 58,
-190, 91, 49,207, 69,171,193,129,248, 59,119, 68,204,230, 54,112, 34,226,204, 38,143,103,110, 35,218, 80, 8,131, 90,111,200, 46,
- 95,205,132, 53,111,127,171,243,170,126, 19,161,141,127, 28, 66,191,241,173,158,195,126,126, 39, 44, 41,171,235,156,124, 0,132,
-224, 46, 94,182,165,148,175,142,191, 75,183,236,240,149, 78, 41, 0, 99,245, 59,142, 51,134,195,135, 15, 99,214,172, 89,208,104,
-186,127,238,217,153, 51,103, 80, 85, 85, 85,147,154,154,186,175,187, 5,191, 51,252, 3, 52, 42,220, 26, 55,168,235,191, 7,210,
-246,172,201, 13,127, 48, 74,128,241, 90,248, 27, 11,131, 81,105,110,189,246, 99,219,145, 11, 88,152, 56, 10,140, 1,203, 63,219,
-141, 62, 65,218, 14,243, 46,185,120, 28,193,174, 47, 93, 32,175,194, 43,123, 6, 72, 23,247,192,186,239,237, 70, 65,110,236, 45,
-110,122, 8,254, 9, 75, 27,167, 66,156, 59,127, 6,102,179, 25,186,112, 29, 6, 13,138,133,223,216,251, 32, 68,220,128,154,237,
- 43,192,172,141,131,150,227, 0,238, 61, 0,247,119,216, 7,160,148, 54,174,195,180,217,108, 56,126,252, 56,238,185,231, 30,143,
- 60,236,150, 45, 91,172,162, 40,190,215,221, 14,111, 79,241,247,148,195,238,138,255,228,225,209, 46,203,239,204,188, 12,139, 93,
-196,239, 55, 28,192,134,212,179,152, 60, 44,186, 99, 74,230,176, 64,147,191,219, 77, 43, 79,206,244,248,131, 51, 10,251,225, 53,
-176,238,126,189,149,240,171,135,205,128,191,254,215, 0,225,112, 56, 35, 29,241, 79,188,138,184, 23,191, 67,252,170, 61, 24,246,
-220, 70,252,252,153, 55,112,241, 98, 14,132,232,177, 8,185,255, 95, 32,126,205,167,178,176,123,171, 62,156, 60,164,165, 2,180,
-138, 67, 55,175,248,134, 79,102,102, 38,134, 13, 27,134,254,253,251,119,251,243,214,212,212, 32, 53, 53,149,216,108,182, 79,187,
-214,200,123,151,255,181,119, 82,157,227, 63,101,120, 63,215, 65, 4,187,136,121,127,217,138, 15,182, 31, 5, 0, 76, 30, 22,211,
- 33, 2,181,199,191,130,134,147,220, 24,124,108,103,143, 42,189,185, 12,150,109,203,225, 56,241,159,214,129, 64, 65, 3,255,233,
-207, 2, 0,242,242,206,227,231,171,119,227,120,133,179,127,243, 95,131, 10,243,255,244, 21, 36, 81, 4, 23,210, 15,234, 33,122,
- 39,151, 65,166,252,114,183, 61, 0, 99,172,177,194, 37, 73,130, 36, 73,141,199,199,143, 31,199,188,121,243, 60,242,208, 59,119,
-238,132, 90,173,222,113,173,249,102,188,197,191, 59,205,181,142,240,159, 59,105, 24, 66,252, 93,155,113, 7,234, 71,171,181,106,
- 1, 99, 6, 69,180,111,102,228,167, 65, 62,245, 31,119,151,109, 68, 35,110,236, 49,147,231,202, 49, 88,191,121, 12,114,145,235,
-225, 18, 85,244, 88,112,218,186,177,155, 15,191,254, 14,229, 14,215, 75, 72, 79, 87,249,225,207,255,168, 11, 36,170, 6, 76,110,
-209,161,177, 71, 13,127, 77,208, 58, 41, 64,131,157,217,178,213,105,120, 17, 6,131, 1, 22,139, 5, 9, 9,221, 59, 38, 66, 41,
-197,158, 61,123,176,118,237, 90,212,214,214,190,123, 45,130,227, 13,254,221,237,167,116,148,127,144, 86,141, 71,110, 29,219,230,
- 61,199,235, 36,168,218,153, 30,239,200,254, 22,150, 31, 86,130,103,110,167, 68,127,213, 35,243,255, 25,133,253,216, 90, 88,183,
- 63, 3,106,117, 63, 67, 85,136,106, 26,228, 59,125,213,220,230, 45,243, 74,235,156,122, 97,192,205, 45, 47, 5,169,180, 36,168,
-185, 19,204, 26, 42,186,193,217,106, 72, 66,212,240, 57,113,226, 4,238,185,231, 30,116,215,194, 19, 89,150,177,107,215, 46,124,
-246,217,103,176, 88, 44,142,226,226,226, 45, 6,131, 33, 60, 56, 56,248,230,234,234,234, 35,157,173,190,158,230, 79,105,183,250,
-132, 93,226,255,200,140, 49, 88,179,235, 68,227,130,156,150,152,192, 95,132,121,227, 98, 8, 35,102, 67,125,195, 29, 32,129,117,
- 19,227,152,104,133,227,226, 62,148, 30,222,128, 16, 91,126, 91, 83, 39, 77, 50, 47,175,244,184,236,139, 86,216,118,189, 2,169,
-224,144,115, 67,205,171,193,192,156,124, 0, 90,219, 20, 29, 31, 18,174,193,129, 54, 18,161,140,111,152, 8,232, 98,108,193,223,
-108,111, 60, 41, 52,111,125, 26, 42,188,249, 75,176, 88, 44, 56,127,254, 60, 94,121,229,149,107,239,226, 36, 9, 63,252,240, 3,
-214,174, 93, 11,155,205,102,191,122,245,234,214,162,162,162,100, 74,105, 49,207,243, 70, 89,150, 75,174,165,245,236, 41,254,255,
- 90,191, 3, 16, 98,187,189,245,119,197,223, 84,107,198,169,220, 43,184,243, 87, 75,177,249,240,121, 28,207, 43, 70,218,185, 66,
-156,184,100,132, 67,114,223,194,223, 20, 84, 9,106, 42,130, 35,227,159,112,100,252,179, 46, 98, 66, 56, 48, 42,131,128,181, 59,
-186, 69, 8, 94,136,252,205,145, 98,143, 10,191,189, 22,214,255, 62, 7,217,152,237,252,219,193, 49,240,159,245, 38,236, 71,254,
- 5, 41,191, 41, 90, 44,149,158,107,252,255,233, 7,238,194,127, 94,217, 6,145,181, 86,225, 80,149,132,217,183,212,141,112,203,
-165,173,179, 39, 50, 78, 77,157,194,160, 45, 95, 64,243, 23,113,234,212, 41, 36, 36, 36,224, 90,114, 76, 58, 28, 14,124,255,253,
-247, 88,183,110, 29, 28, 14,135,173,168,168, 40,185,168,168,232,123,142,227,140,140, 49,163, 36, 73,198,170,170,170,210,107,105,
-145,123,146,255, 85, 41,226, 52,250,224,230,238,142,246,184,226,159,125,250, 52,134,198, 77,192, 15, 89,133,216,118,244, 34,174,
- 86,214,118,232,158, 55, 5, 87,180, 50, 51,192,104,135, 38,203, 51,134,191,233,150, 29,250,196,147,194, 79,173,149,117, 38, 79,
-153,115,170, 33, 97,144, 30,126, 51, 94, 4,209, 4, 66, 24,156,232,164, 0,114,121, 30,236,103,191,135,102,212, 93, 24, 53, 50,
- 14,219,127, 99,196, 67,255, 76, 69,177,189,105,237,198,208, 0, 59, 62, 91, 58, 3,177,177,117,169, 93,172, 39,190,108,249,211,
-162, 57,192, 97,115, 82,128, 6,123,179,229, 11,144,101, 25, 89, 89, 89,120,253,245,215,187,244,144,118,187, 29,223,126,251, 45,
-214,175, 95, 15, 89,150,109,133,133,133,155,141, 70,227, 14,198,152, 17,128,145,231,121, 99,121,121,185,241, 90, 43,179,167,249,
- 91,198,207,187, 25,232, 62, 5,104,139,127,118,214,105,188,254,250,235, 24, 61,122, 52,254,186,120, 6, 14,157, 47, 66,114,198,
-121,108,205, 56,143,194, 10,215,202, 16,163,177, 34, 90,109,235, 98,143,132, 47,117,149,135,158,242,104,203,111,173,130,245,219,
- 39, 65,171,154, 77,234,227, 4,104,110,126, 12,234, 9,191, 68,195, 8, 53, 63, 48,161,254,255,166,104,144, 53,245, 35,168, 98,
- 38,128, 11,233,135, 91,111,153,137,203,137,211,177,231,192, 30, 20,149,150, 33, 38,162, 15,110,155, 62, 19, 28,199, 3,140,194,
-146,178, 26,210,149, 99, 45,186, 54,124, 25,179,244,152,197,165, 15,208,210,254,204,203,203, 67,104,104, 40, 70,143, 30,221,169,
- 7,180, 88, 44, 72, 78, 78,198,134, 13, 27, 64, 41,181, 22, 20, 20,108, 46, 47, 47,223,205, 24, 51, 82, 74,141,130, 32, 24,203,
-202,202,140,232,194, 34,230,182,108,232,158,226, 79,253,195,251,121,194, 7,104,143, 63, 71, 8,244, 35,250, 65, 63,162, 31,254,
-180,232, 86, 28,201,189,138,228,140,243, 72, 62,124, 30, 5,101,213, 78,230, 79, 23, 32,130,177,223,235,150, 29,254, 11, 33,158,
-221,179, 75, 46, 60,234, 36,252, 92,200, 0,248,221,246, 50,248,136, 17, 78,229,184,128, 62,224,251,222, 8,185, 56,171, 89,207,
- 97,130,233,171,135, 17,112,219, 31,160, 30, 58, 29, 60,207, 99,214,140, 89,173, 76,171,218, 29, 47, 66, 44, 56,220,170,174,193,
-216,159,156,122,156,230,161,183,150, 54,232,153, 51,103, 58, 21, 58,172,173,173,197,230,205,155,177,113,227, 70, 80, 74, 45, 6,
-131,225,155,178,178,178,253,140, 49, 35,207,243, 70,198,152,177,170,170,202,136,174,239, 68,216,102,232,176,167,248,171,180, 33,
-241,221, 37, 34, 93,229, 79, 8, 48,121, 88, 52, 38, 15,139,198,170, 95, 78,195,241, 60, 35, 54,238,203, 64,114,250,105,140, 15,
-236,148, 2, 72,140, 97, 7,227,232,107, 17,203, 50,142, 98,185,231,163, 94,252,160, 68,240,125,199, 64, 46, 57, 11,213,136,217,
-208,232,159,116,154,215,223, 28,154,164,223,194,178,229, 9,128, 54, 57,251,204, 81,139,218,255,174,132,122,232,116, 8, 81,163,
-193,135, 15, 1, 9,208, 65,174,184, 12,185,236, 2, 28,185, 7, 64,171, 91,175,165, 98,192,247,125,150, 29,118, 26,216,115,235,
- 3,152, 76, 38, 20, 23, 23, 99,198,140, 25,237, 62, 80,117,117, 53,190,254,250,107, 36, 39, 39,131, 82,106,190,114,229,202,230,
-178,178,178,131,140, 49, 99,189,157, 95, 28, 26, 26,106,188,120,241,162,221, 35,246,164,194, 31,199,246,124,135,204,228,100, 12,
-161,212,188, 35,219,184,189,223, 56,106,191,101,120,224, 68,157, 63, 63, 26,196,133,233, 79,112,152, 49,178, 94,237,112,124, 21,
-252,236,177,178,158, 12,251, 18,149, 22,254,247,124,220,184, 32,167, 77,101,233,115, 3,212,147, 30,169,115,228, 91,250,102,185,
-251,225,200,221,223,193, 31, 37,121, 2,228, 86,234,237,214, 7,200,206,206,198,157,119,222,217,230,188,153,170,170, 42,124,249,
-229,151, 13,203, 11,107, 13, 6,195,230,170,170,170,180, 6, 27,159, 82,106,212,106,181,198,162,162, 34, 75,101,101,165,199, 42,
- 84,225,223,154,255,243,151,152, 81,150,139,140,235, 31, 25, 64, 18, 6, 5,106,136, 74,230,136,172, 34, 96, 50, 7,162,170, 10,
- 95,150, 82, 0,111,131,239, 88, 46, 84,205,132, 95, 1,142, 90, 56, 78,118,121,101,233, 41,153,147,238,212,185,136,106, 53, 42,
- 64,115, 27, 84, 20, 69,156, 63,127, 30,207, 60,243,140,203,187,149,151,151, 99,253,250,245,216,177, 99, 7,100, 89,174,169,175,
-248,140, 6,161, 81,169, 84,197,140, 49, 99, 69, 69, 69,173,171, 92,239,158, 16, 32,133,191,107,254,119,191,239,203,121,172, 58,
-218,101,112,208, 76,249, 53,248, 62, 55,192,182,255,143, 96, 82,167, 28,252, 20,162, 17,239,138,116, 51,160,215,202, 4, 98,140,
-225,226,197,139, 24, 49, 98, 4,250,245,115,246,245, 74, 74, 74,240,197, 23, 95, 96,247,238,221,144, 36,169,218, 96, 48,108,169,
-174,174, 62,202, 24, 51, 54,216,201, 0,140, 37, 37, 37, 61, 90,235, 10,127,239,242,239, 41, 8,195,102,194,191,223, 68,136,103,
-190,131,120,230, 91, 48,179, 91,203,205, 0, 32,153, 3,217, 18,218,183,127, 74, 91,107, 25, 4,198, 24,107,217, 5, 95,184,112,
- 1, 79, 61,213, 20, 9, 43, 42, 42,194,231,159,127,142, 3, 7, 14, 64,146, 36, 83,126,126,254,150,218,218,218,147, 13, 81, 17,
-158,231,141,146, 36, 25, 43, 43, 43,123, 60, 91,152, 87,248,203,220, 81,240,244, 53,215,132,136,205,231,249,247, 98,112,218, 48,
-104,110, 90, 12,205,132, 69,117,249,129, 28, 22,124,182,230, 67, 27, 45, 57,179,121, 76, 31,122,118,100,140,176,179,239,242, 35,
- 29,158, 77, 32, 16, 66,242,171,171,171, 71,134,133,133,129, 82,138,210,210, 82,136,162,136, 41, 83,166,192, 96, 48,224,223,255,
-254, 55,210,210,210, 32,138, 98,229,229,203,151,183,154,205,230,204, 6,231, 16,128, 81,150,101, 99, 85, 85, 85,153,183, 42,196,
- 27,252,197,205, 43,142, 2, 56,218, 91,249,255,111,104, 2, 15,190, 79,221, 96,215, 57,115,152,188,255,136,120,188,160,160, 96,
- 91, 85, 85, 85,167, 54,241, 16,236,118,123,106, 73, 73,201,204,254,253,251, 11,148, 82, 92,188,120, 17, 19, 38, 76,192,203, 47,
-191,140, 35, 71,142,192,110,183, 87, 24, 12,134,111,107,107,107,179, 8, 33, 37,168, 91,204, 97,228,121,222, 88, 82, 82, 98,244,
-118, 61, 40,252,189, 15,147,201, 36,100,100,100,120,243,247,121, 66, 8,149,101,185,243,185, 65, 25, 99, 25,121,121,121,246, 33,
- 67,134, 8,118,187, 29,121,121,121,200,207,207,135,205,102,107,168,248,179,205, 91,155,102,131, 88,212, 23, 42, 95,225,239,117,
- 24,139,139,139, 79,173, 90,181,138,183,219,237,209,140, 49, 53, 0, 86,159, 97,143, 53,251,160,254, 60,107, 10,203, 59, 95,115,
-119,189,197,189, 90,150,101,178, 44,203,146, 36,149,212,167, 71,236,212, 8, 13, 1,128,105,211,166, 61, 79, 41,125, 11,128,236,
-112, 56,106,138,138,138,182,213,214,214,158,227, 56,174,193,198, 44, 97,140, 21,215, 79, 91,144,224, 99, 80,248,251,134, 81,162,
-211,233,150, 3,232, 91,175,156, 50,234, 18,214, 74,132, 16,153, 49, 38, 19, 66,164,102,231,104,179,107, 13,231,101, 66,136, 84,
-159,228, 86,110,184, 70, 8,145, 41,165, 82,139, 99,185, 33, 35, 52,165, 84,146,101, 89, 98,140, 89,204,102,243,149, 78, 43, 64,
- 61, 84,225,225,225, 81,140,177, 48,142,227,180, 0,136, 44,203,118,142,227,202,195,195,195, 75, 60, 53, 8,212,141, 80,248,123,
- 57, 88, 25, 24, 24, 24,205,113,156,154, 16,194, 84, 42, 21, 68, 81,108,108,165, 27, 90,241,230,199,132, 16,218,208,226, 59, 28,
- 14,167, 30,128, 16,194,154,125, 26,202,194, 98,177, 56,221,131,227, 56, 70, 8, 97,149,149,149,172, 94,233,196,174, 42,128, 2,
- 5,215,172, 4, 93,181, 4,189, 69,248,255, 3,212, 21,184,121, 66,226, 69,162, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130,
-};
+137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0,192, 0, 0, 0,192, 8, 6, 0, 0, 0, 82,
+220,108, 7, 0, 0, 0, 1,115, 82, 71, 66, 0,174,206, 28,233, 0, 0, 0, 6, 98, 75, 71, 68, 0,255, 0,255, 0,255,160,189,
+167,147, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,
+217, 3, 14, 12, 53, 26, 8,211, 40, 12, 0, 0, 0, 29,116, 69, 88,116, 67,111,109,109,101,110,116, 0, 67,114,101, 97,116,101,
+100, 32,119,105,116,104, 32, 84,104,101, 32, 71, 73, 77, 80,239,100, 37,110, 0, 0, 32, 0, 73, 68, 65, 84,120,218,237,125,123,
+120, 20, 85,182,239,175, 30, 93,213,121,116, 58, 47, 72, 32, 64,194, 0,137,134, 16, 68, 6, 6, 66, 8,207,235, 1,230,160,131,
+115,124,220, 17,189,119,230,206,225, 19,207,232,204,248, 64, 16,197,232,213,113, 12,160,163, 40,122, 70, 4, 6,225,115,102,206,
+209, 15,225,158,163, 3,142,142, 56, 38,228, 33, 4, 3, 73, 32, 60, 66, 72, 32,129,188, 31,221,233, 71, 85,221, 63,160,234, 84,
+ 63,211,143,170,238,228,176,127,223,215, 95, 63,170,171,123,213,174,223, 90,123,173,181,215,222, 27, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,184, 14,234,102,186,216, 89,179,102,165,139,162,120, 24, 64,158, 94,255,
+193,113, 92, 91, 89, 89, 89,186, 30,191, 61,121,242,100, 62, 41, 41,105,142, 32, 8, 38,189,228, 55, 24, 12,182,242,242,242,195,
+ 55, 11, 39,216,155,133, 64, 55,100,255,242,181,215, 94,227,138,138,138, 80, 85, 85,133,140,140, 12, 24,141, 70, 48, 12, 3,138,
+162, 64,211,244,127, 89, 6,138,242,251, 90,253,153,252,222, 98,177, 96,233,210,165,105,122,145, 63, 49, 49,113,238,150, 45, 91,
+232,162,162, 34, 28, 59,118, 12, 25, 25, 25,224, 56, 14, 44,123,253, 54, 50, 12,227,243,124,127,199,100,216,237,118, 44, 92,184,
+144,191,153,140, 34, 27, 44,129,182,110,221,202, 45, 88,176, 64, 33, 16,207,243, 96, 24, 6, 52, 77,123,144, 99, 40,226,184,191,
+214,139, 64,178,236, 91,182,108,225,139,138,138, 38, 2, 64, 85, 85, 21, 6, 7, 7,145,144,144, 0,150,101,149,107,144,175,195,
+215,195,223,241, 11, 23, 46, 64, 79,242,191,250,234,171,116, 81, 81, 81, 44, 0, 84, 84, 84, 32, 47, 47, 15,137,137,137,138,252,
+106,146,203, 74,225, 78,126, 95,159, 51, 12,163,155,252, 35, 94, 1,212, 4, 90,176, 96,193, 68, 0, 40, 47, 47, 71, 94, 94, 30,
+204,102,179, 79, 2,185,147,101,168, 99,231,207,159,215,203,237,249,114,243,230,205,252,194,133, 11, 39,202,159,211, 52, 13, 81,
+ 20, 93, 20,208, 31,185, 3, 85, 12, 61,201,191,120,241,226,216, 64, 44,122, 40,228,191, 89,193,134, 74, 32,134, 97, 32, 73,146,
+ 79, 2, 5, 75,126,249,181, 30,228, 47, 41, 41, 49, 46, 90,180, 40,203,151, 75, 16, 14,249,245,146,221, 31,249,221,201,172,190,
+158, 80,201,239,254,123, 68, 1,194, 32, 80,168,228,215,146, 68,106,217, 23, 47, 94,156,229,205, 39, 14,150,224,129, 28,139, 4,
+249, 3, 33, 49, 33,127,152, 10, 16, 40,129,100,119, 34, 88,242,251,250, 94, 36,200, 47,223,116, 57,232,213,138,252, 90,201, 63,
+ 20,249,229,246,247,229,186,132, 74,254,155,209, 21, 98, 67, 37,144,193, 96, 8,217,210,235,233, 2,169, 93, 54,247, 94, 75, 13,
+158,247, 76,118, 4,235,239,235,161, 0,129,144,223,151,252,196,242,107,160, 0,129, 18,136,227, 56,175,228, 9,135,252,234, 52,
+100,184,217, 30,117,188, 2, 0, 54,155, 13,141,141,141,104,106,106, 66,103,103,167, 75,250, 51, 92,171,175,149,252,254,200,111,
+179,217,112,225,194, 5, 52, 53, 53,161,171,171, 11,177,177,177, 30,100, 15,135,252, 55,107, 32,204, 6, 67, 32,249, 6,116,118,
+118, 34, 38, 38,198, 37,127, 30,109,242, 3,128, 40,138,135,111,228,249, 39,138,162,136,150,150, 22,212,213,213,225,244,233,211,
+104,111,111, 71, 66, 66, 2,146,147,147, 97, 54,155, 97, 50,153, 60, 20, 32,220, 88, 32, 92, 36, 37, 37,205,185,145,231,143, 21,
+ 4, 1, 45, 45, 45,168,175,175, 71, 67, 67, 3,218,219,219, 97, 50,153,144,148,148,132,196,196, 68,152, 76, 38,176, 44,235, 65,
+252,112,200,127,211,187, 64,162, 40, 30,190,145,231, 87, 8, 84, 91, 91,171, 16,200,100, 50, 33, 57, 57, 25,137,137,137,136,139,
+139,115,201,255,135, 75,126,141, 92,136,188,220,220, 92,108,223,190, 29, 13, 13, 13, 96, 24, 6,105,105,105, 72, 73, 73,193,216,
+177, 99,149, 65, 35,142,227, 96, 52, 26, 21, 2, 13,149,255, 15,230, 88, 56, 16, 4,193,148,155,155,139,183,223,126, 27,231,207,
+159, 7,195, 48, 24, 53,106, 20, 82, 83, 83,145,159,159, 15,150,101,193,243, 60, 56,142, 83,198, 95,124, 89,125, 66,254,208, 92,
+160,188,169, 83,167,226,173,183,222, 66, 67, 67, 3, 88,150, 69, 90, 90, 26,146,147,147, 49,109,218, 52,133, 64, 60,207,195,104,
+ 52,194, 96, 48,128,101, 89,205,200,175,133, 21,237,235,235, 67,124,124, 60,138,138,138,144,152,152,168, 4,233,234, 96,221, 96,
+ 48,120,144,200, 23,201, 35,157, 5,234,237,237,133,201,100, 66, 97, 97, 33,146,146,146, 60,200, 45,203,203,243,188, 34,191,183,
+ 94,128,144, 63,196, 24,160,183,183, 23,113,113,113, 10,129,220, 51, 61, 52, 77, 43, 74,192,243,188,242, 62,216,108,143,175, 99,
+225, 34, 46, 46, 14,249,249,249, 16, 4, 65,137, 77,212,207, 52, 77,131, 97, 24, 24, 12, 6,229,217, 91, 15, 16,106, 32, 28, 46,
+ 18, 18, 18, 48,125,250,116, 69,126, 95,153, 31,119,242, 19,183, 71, 35, 5,144, 9,228, 62, 74,170, 38, 16,203,178, 10,113, 56,
+142,115, 33, 80,184, 46, 81,216, 23,116,195,197,145, 36,201, 43,249,229,255, 83, 91,126,173, 98, 1, 45,228,151,173,187,211,233,
+ 28,146,180, 90,146, 95,118, 7,111,122, 5,144,173,187, 40,138, 30, 55, 86, 38,250,147,123,175,225,211,138, 86, 8,162, 20,210,
+159,246,239, 95,161, 91, 26, 84,125, 35,101, 37, 80, 63,220, 7,192,130,177,252,145, 8,132,189,213,245,248,203,238,120, 35,127,
+ 32,113,129,191,239,220,244, 10,160,190, 1,238, 55,153,166,105,252,105,195,237,232, 24, 0,254, 87, 73, 37,190,172,190,170,156,
+219,189,255, 71, 48,199, 25, 92,126,175,173,107, 16,223,157,239,193, 75,251,234,112,164,230,154,223,148,169, 22, 80,187, 82, 90,
+167, 56,135, 74,127,106,117, 13,129,100,117, 66, 33, 54, 33,191, 39,104, 95, 4,146,173,139,252,144, 3, 94,134, 97,208,209,209,
+ 1,214,217,131, 23, 30,204,113, 57,183,179,163, 3,237,237,237,232,232,232, 64,103,103, 39,186,186,186, 16,195,216, 49,239, 86,
+ 19, 62, 47, 41,196,242,217,233,126, 7,156,180,136, 1,180, 28,213, 13,134,252,122, 21,195, 69,138,252, 55,107, 44,224, 83, 1,
+134,242,221, 69, 81, 68, 70,162,251,205,242, 78,104, 65, 16, 96,183,217,240,220, 3,183,250,253, 15,173,160, 21,249, 3, 77,143,
+234, 85, 16, 71,200, 31, 5, 23,200, 87,208,232, 77, 17,226, 88,215, 27,206,120, 33,132,250,253,237,147, 76, 88,124,219,104, 93,
+201,239, 79,126, 45, 21, 67,175, 58, 32,119,191, 62, 28,242, 7, 26, 71,144, 44, 80,144, 46,132,175,238,158,166,135,174,243, 57,
+252,234,124, 8,130,160, 43,249,135,122,232,161, 24,122,129,144, 63, 10, 61,128,123, 16, 25,232,192, 21,195, 12,237, 58,233, 73,
+126, 95,242,235, 29, 11, 16,242,255, 55,139, 1, 66, 29,184,162,189,156,247, 96,201, 49,175,196,209,139,252,122,184, 60,145, 38,
+191, 58, 11, 71,200, 63, 76, 98,128, 64, 6,174, 24,198,245,152,213, 46,226,179,170,171, 17, 35,191,187,252,122,250,251,122, 90,
+126, 45,130, 89, 66,126, 13, 99,128, 64,235,247,153, 27, 89, 19,135, 32,161,165,221,138,205,255,126, 14, 22,155, 16,113,242,171,
+ 21, 64,175, 64, 56,146,196, 39,228,143, 98, 12, 16, 76, 9,115,194,221,159,249, 37,165,222,228, 15, 38, 11, 20,205, 73, 47,129,
+248,253,132,252, 81,238, 1, 2, 73,131,186,147, 65, 58,124, 15, 0,192,238, 20,113,233,170, 5,191,249,176, 30, 59, 63,187, 16,
+ 81,242, 7,146, 9,138,102,173, 79,168, 10, 65,200, 31,161, 32, 56, 80,203,239,141, 16, 86,171, 21, 54,155, 13, 16,157,200, 28,
+109,196, 27,143, 76, 71, 44,207, 16,242, 19,242,143, 60, 5, 8,165,126,223, 93, 49, 98,121, 6, 63,252,193,152,136, 95, 20, 33,
+ 63, 33,127, 84,210,160,222,206,251,243,115,115,163, 78,254,112,102,124, 17,242,223,164,105,208, 80,234,247,189, 29, 83, 47,158,
+ 21, 13, 37, 8,135,248,209, 32,127, 48,196, 38, 19,220,117, 10,130, 67,157,194,168,231, 18,129,161, 40, 0, 33, 63, 65,216, 49,
+ 64, 80, 35,193,132,252,218, 90, 39, 66,254,232,198, 0, 67,145,191,215,226,116, 57,215,253,125,212, 46,106, 4,147, 95, 38, 53,
+ 33,127,148,123,128, 64,252,255, 51, 45, 3, 46,231,213, 94,236,141,250, 5,133, 90,219, 79, 44, 63, 81, 0,175, 22,212, 23,249,
+ 47,180, 90,240,236,238, 90,151,243,214,191, 95,131,186,166,225,167, 4,129, 16,127,184,144,223, 23,177, 9,249, 35, 24, 4, 15,
+ 69,254, 5, 79,126,141,163,117,157, 30, 63,246,117, 77, 59,166,254,252, 16,242,191,103,198,161,223, 22, 97,116, 34, 31,117, 5,
+ 32,228, 39, 8, 74, 1, 2,201, 4,149,189,185,100,200, 31,142, 70,250,147,144,159, 64,147, 30, 96,168,165, 66,228, 37, 83,134,
+173, 95, 23, 0,241, 35, 89,158, 17,174, 34, 16,242, 71, 33, 8,142,196, 58,254,145, 12,130, 9,249, 9, 2, 82,128,145, 76,254,
+ 64,148,128,144,159, 32,172, 24, 96,184,195,110,183,227,236,217,179, 94,253,124,189,201,111, 48, 24,194,254, 13,167,211,137,134,
+134, 6,175, 10,160, 55,220,247,124,184, 41, 21,192,225,112,224,220,185,115, 81, 9, 22,195, 37, 16,207,243,109,243,231,207, 79,
+139,102,131,242, 60,223, 22,234,185, 49, 49, 49,182,130,130,130,168,238,211, 27, 19, 19, 99,187,153, 20,192,133,213, 5, 5, 5,
+173, 54,155, 45,234, 4, 42, 45, 45, 77, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,129, 38,
+ 8, 42,185,127, 99, 31,225,195, 0,242,244, 18,136,227,184,182,178,178, 50, 93,210,160,179,102,205,202, 23, 69,177, 28,128, 81,
+ 71,249,197,178,178, 50, 70, 39,249, 71,122,251, 15, 59,249,217, 32,133,255,242,198, 62,194,168,170,170,194,184,113,227,192,243,
+188,178, 85,170,251,128, 89,176,175,173, 86, 43,150, 44, 89,146,166, 35,249, 43,183,110,221, 74,233, 44, 63,173, 35,121,148,246,
+175,172,172, 68, 70, 70,134,135,252,190,228,243, 54,127,219,253,243,190,190, 62, 44, 95,190, 60, 77, 79,249,111,108,100, 62,108,
+248,195, 6, 35,252,150, 45, 91,248, 5, 11, 22, 76, 4,128,170,170, 42,216,108, 54,152,205,102,101,235, 36,127, 19,105, 2, 41,
+ 83, 62,127,254, 60,244, 36,255,230,205,155,233, 5, 11, 22,176, 35, 80,254,116, 81, 20,191,220,188,121,179,210,254,229,229,229,
+152, 58,117, 42, 18, 18, 18,188,202, 31,202,242,143, 23, 46, 92,208, 85,254, 45, 91,182,240, 69, 69, 69,195,138, 63,108, 48,194,
+ 47, 92,184,112,162,114, 34,203,186,212,252, 7, 34, 96, 36,118, 89,244, 71,254, 69,139, 22,177, 35, 80,254,116, 81, 20,191,124,
+245,213, 87,249, 69,139, 22, 41,237,207, 48,140,178,149,173, 86,107,159,234, 77,254,225,200, 31, 54, 64,203, 99, 92,184,112, 97,
+150,250,152, 92, 88,230,190, 21,105,184, 59,174,235, 65,254,146,146, 18, 23,242,143, 32,249,101,242, 27,151, 44, 89,226,209,254,
+238,174, 64,160,147,128, 34,181,240,239, 72,224, 15, 29,136,240,139, 22, 45,202,242,208,156, 27,126, 91, 32,141, 31, 76,119,166,
+ 7,249, 23, 47, 94,204,142, 64,249,125,146, 95,238, 1, 2,149, 63, 26,171,224,141, 20,254,176,161, 8,175,190, 0, 45,133,215,
+234, 6, 12, 69,254, 17, 32,191, 95,242,123, 35,144, 22,228,215,170, 92, 60, 16,254, 28, 56,112, 0,102,179, 25, 70,163, 17, 44,
+203,186,244,104,238,138,225, 45,104,151,229,125,250,233,167,181, 85, 0, 55,159, 45,203,215,137,114,233,178,183,110, 56, 28, 82,
+233,229,243,123,147,223, 91,214, 97, 24,200,175,248,252,190,200,175,110,127,111,132, 9,101, 85, 12,173, 98,152, 64,249,115,223,
+125,247, 33, 35, 35, 3,102,179, 25, 28,199,193, 96, 48, 40,189, 90, 36,219,159, 13, 36, 96, 1, 0,155,205,134,198,198, 70, 52,
+ 53, 53,161,171,171, 75,209,220, 96, 27, 93,207, 46,216, 31,249,189,201,207, 48, 12,174, 94,189,170,108, 6, 62,126,252,248, 33,
+229, 60,119,238,156,226,187,222,122,235,173, 90,203,175,100,123,212, 1,175, 44,255,133, 11, 23,112,241,226, 69,180,183,183, 35,
+ 38, 38,198,107,230, 39, 28,242,107, 37,191, 55,254,244,247,247,163,186,186, 26,199,142, 29,195,201,147, 39, 49, 48, 48,128,184,
+184, 56,151, 13,216, 3,181,252,234, 9, 78,235,215,175,215, 78, 1, 68, 81, 60,124, 35, 79, 59, 81, 20, 69,180,180,180,160,190,
+190, 30,167, 79,159, 70, 71, 71, 7,226,227,227,145,146,146, 2,179,217,140,132,132, 4, 69,232, 64,211,111,122,103, 81, 68, 81,
+ 44,191,145,231,103, 3,149,191,170,170, 10, 63,254,241,143,113,240,224, 65,165, 87,240,230, 87,202,159,151,150,150,226,167, 63,
+253, 41,118,237,218,133,220,220, 92,173,229, 63,124, 35,207, 63, 81, 20, 69, 52, 55, 55,163,174,174, 14,245,245,245,104,111,111,
+ 71,124,124, 60,146,146,146,144,148,148,132,184,184, 56, 15,139, 25, 77,242, 7,195,159,229,203,151, 35, 41, 41, 9, 38,147, 9,
+177,177,177,202, 88,128, 47, 62, 69, 50, 11,148,151,155,155,139,237,219,183,227,236,217,179, 96, 24, 6,163, 71,143, 70,106,106,
+ 42,198,142, 29, 11,142,227,192,178, 44,120,158, 87,122, 0,117, 47,160,197, 70,116, 97,194, 56,117,234,212,160,228, 63,118,236,
+ 24,142, 31, 63, 14,138,162,144,158,158,238,211,250, 40, 75,194,148,149,161,180,180, 20,146, 36,225,231, 63,255,185,214,242,231,
+229,230,230,226,173,183,222, 66, 67, 67, 3,104,154, 86,228,207,203,203, 83,172, 37,207,243,136,137,137, 81,222, 15,163, 93, 47,
+125,242,231,155,111,190, 1, 69, 81,202, 70,224, 44,203, 42,110,143, 58, 6, 8,196,242,171,123,128, 13, 27, 54,132,213,254, 30,
+ 62,114,127,127, 63, 76, 38, 19, 22, 44, 88,128,196,196, 68, 23, 63, 83, 94, 94,208, 96, 48,192, 96, 48,128,231,121,208, 52,173,
+108,235,169,133, 59, 20, 46,130,149,191,178,178, 82,249,206,209,163, 71, 21,247, 70,126,200,239,213,159,203,175,245,144,191,175,
+175, 15,177,177,177, 40, 44, 44,132,217,108,246, 32,128, 76, 24,142,227,192,113,156,210,246,129, 14, 34,233, 29,195,248,106,255,
+181,107,215,122,180,191,209,104, 84, 94,187, 43, 65,164,248,227,161, 0,113,113,113,152, 62,125, 58, 4, 65, 80,114,180,234,220,
+173, 76,120,131,193,160, 92,140, 63, 95, 52,216,207,195, 69,176,242,159, 59,119, 14,205,205,205, 24, 55,110, 92, 80, 36, 53,153,
+ 76,186,200, 31, 27, 27,139,105,211,166, 65, 20, 69,143,129, 34,185,205,100,249,213,214, 83, 62, 22,110, 76,160, 87,251,255,254,
+247,191,247,112, 39,101,222,248,202, 0,249,139, 7,228,199,198,141, 27,181, 85, 0,185,107, 82,167,217,188,237, 28,175,182,252,
+222,172,191, 32, 8,104,105,105,193,165, 75,151,208,218,218,138,246,246,118,116,117,117, 97, 96, 96, 0, 91,183,110,213,237, 6,
+ 4, 43, 63, 0,133,252,197,197,197,160,105, 26, 5, 5, 5,200,205,205, 69, 74, 74, 10, 58, 58, 58, 80, 91, 91,139,210,210, 82,
+136,162,136,226,226, 98,152, 76, 38,159, 89, 23, 45,228,231, 56,206,101,241, 49, 95,139, 21,171, 13,207,156, 57,115,208,214,118,
+125, 62,126,122,122, 58, 42, 43, 43, 67, 42,141,208,171,253,127,245,171, 95, 5,197,159,168,100,129,228, 1, 22,121, 57, 14,111,
+221,188,250, 61,195, 48,232,237,237, 69, 83, 83, 19,174, 92,185,130,107,215,174,161,171,171, 11,189,189,189,176, 88, 44,232,237,
+237, 69, 79, 79, 15,186,187,187,209,211,211,163,188,126,237,181,215,116, 27,132, 9, 86,126,247,209,201,135, 30,122, 8,153,153,
+153,202,103, 99,198,140,193,152, 49, 99, 48,121,242,100,236,217,179,199,229,251,122,200, 47,251,199,178,187,229,111,165,110,153,
+ 72,221,221,221,200,202,202, 66,125,125, 61, 0, 96,249,242,229,232,237,237, 69,114,114,114,196,199, 0,124,181,255,182,109,219,
+188, 38, 22,220,173,251,186,117,235, 34,186,119,179,135, 2,200,141,170, 30,110,247, 39,200,203, 47,191,236, 65,240,158,158, 30,
+244,245,245, 65, 20, 69, 36, 36, 36, 96,202,148, 41,152, 57,115, 38,178,179,179,241,194, 11, 47,232,122, 19,130,149, 31, 0,218,
+218,218,144,150,150,134,130,130, 2, 23,242, 83, 20,165,184, 33,153,153,153, 40, 40, 40, 0,112,189,234, 48, 38, 38, 70, 23,249,
+229,223,241, 70,126, 81, 20,241,248,227,143,227,242,229,203,120,241,197, 23,145,151,151, 7,154,166,209,211,211,131,185,115,231,
+226,210,165, 75, 74,111,208,221,221,141,148,148, 20, 80, 20,133, 83,167, 78, 97,221,186,117,152, 48, 97, 2,222,125,247, 93,151,
+ 49, 16,173, 51, 65,190,218,255,241,199, 31,215,101,224, 49,220,246,247,187, 71, 88, 32,130,236,221,187, 23, 52, 77, 99,252,248,
+241,152, 50,101, 10,230,205,155,135, 41, 83,166, 32, 59, 59, 27,217,217,217, 74,102, 69, 62,199,151, 2,104,185,104, 85,176,169,
+191,180,180,235, 21,180,185,185,185, 30,131, 75,106,200,199, 99, 98, 98,188, 22,112,105, 37,187,175,209,221, 39,158,120, 2, 51,
+103,206,196,139, 47,190,136, 13, 27, 54, 32, 61, 61, 29,171, 87,175,198, 31,255,248, 71,204,153, 51, 7,253,253,253,160,105, 26,
+185,185,185,216,181,107, 23, 86,175, 94,141,125,251,246, 65, 16, 4,236,217,179, 7, 31,127,252, 49,214,174, 93,139,247,223,127,
+ 95,215, 82, 14,138,162, 80, 83, 83, 3,150,101, 49,109,218, 52, 77,139,221,180, 54,158, 67,238, 20, 31, 72,212,125,233,210, 37,
+ 24,141,198,128, 9,167,247,114,133,193,202, 47, 35, 37, 37, 69,121,237, 30, 64,187, 31,119,143, 41,180,132,175,118,148, 45,191,
+ 40,138,216,177, 99, 7,254,246,183,191, 97,211,166, 77, 88,179,102, 13, 86,172, 88,129,227,199,143,131,166,105,220,117,215, 93,
+ 72, 72, 72,192, 7, 31,124,128,181,107,215, 34, 53, 53, 21, 3, 3, 3,184,243,206, 59,113,224,192, 1,221, 75, 57,104,154, 6,
+207,243,184,229,150, 91,192,178, 44, 4, 65,208, 44, 77,174,181,241,244,187, 83,124,160, 89, 27, 95,228,247,213,192,122,146, 63,
+ 20,249, 59, 58, 58,148,128,119,204, 24,223,251, 26,119,116,116, 0,184,190,252, 34,199,113,186,173, 53,234, 75,129, 95,122,233,
+ 37,172, 95,191, 30,239,191,255, 62,190,249,230, 27,228,231,231,227,147, 79, 62,193,229,203,151, 81, 89, 89,137,193,193, 65, 24,
+141, 70,212,214,214, 98,234,212,169,152, 61,123, 54,218,218,218, 80, 87, 87,135,156,156, 28, 60,247,220,115, 74, 2, 66,175, 44,
+156,252, 59,185,185,185, 46,228,127,227,141, 55, 92,140, 74,176,163,190,190,142, 61,255,252,243,225,197, 92,129, 16,104,168,192,
+ 35,216, 52,167,158,245,243,161,200, 47, 91,246,218,218, 90, 69, 1,212,191, 33,199, 1,181,181,215,119,196,145,215,208,212,131,
+252,254,218, 53, 55, 55, 23,227,198,141,195, 23, 95,124,129, 25, 51,102,160,166,166, 6,181,181,181,168,175,175,199,161, 67,135,
+148,193,167,153, 51,103, 98,245,234,213,200,201,201,193,192,192, 0, 82, 82, 82,112,233,210, 37,196,199,199, 99,250,244,233,186,
+142, 3,168,127, 71,109,249,221, 99,128,112, 75,102,180,226, 15, 27,172, 31,234,205,122, 7, 27,169,235,189,208,110,176,242,203,
+ 40, 45, 45,197,228,201,147,145,153,153,233,177,193,199,197,139, 23, 81, 90, 90, 10,189, 49,148,171,120,255,253,247,163,184,184,
+ 24,251,247,239, 71,109,109, 45,246,239,223,143, 35, 71,142,224,217,103,159,197,220,185,215, 55, 37,175,168,168,192, 83, 79, 61,
+133, 95,255,250,215, 88,185,114, 37, 56,142,195,198,141, 27,241,232,163,143, 70,164, 28,218, 91,251,191,254,250,235, 30, 61, 64,
+ 56,150, 95,126,189,105,211, 38,253, 20, 32, 16,237, 12,212,213,240, 53,103, 85, 79, 5, 8, 84,126,249,198,136,162,136, 61,123,
+246,248, 29, 7,240, 21, 31,232,165,192,114, 15,212,219,219,139,174,174, 46,236,219,183, 15,107,214,172,193,149, 43, 87, 80, 95,
+ 95,143, 35, 71,142,224,171,175,190, 66, 98, 98,162,242,253,204,204, 76, 44, 91,182, 12,133,133,133, 40, 42, 42, 66, 90, 90, 26,
+150, 46, 93,138, 15, 62,248, 0,107,214,172, 65,106,106, 42,146,146,146,116,155,203,224,173,253,159,120,226, 9,205,252,125, 45,
+101,101,195,201,160, 4, 59, 33, 35, 18,107,243,135, 42,191, 60, 16, 22,204, 13,142,148, 2, 20, 20, 20, 32, 43, 43, 11,115,230,
+204, 65, 97, 97, 33, 86,172, 88,129,202,202, 74, 28, 62,124, 24,207, 62,251,172, 11,249,229,135,217,108,198,166, 77,155,176,111,
+223, 62,108,220,184, 17, 75,150, 44, 65,107,107, 43, 94,127,253,117, 28, 63,126, 28,237,237,237,184,112,225,130,110, 46,144,251,
+227,181,215, 94,115,153,253, 21,142,229, 87,255,151, 46, 61, 64,176, 89,148,104,104,174, 30, 89,160,225, 0,111,174, 98,107,107,
+ 43,234,235,235,209,220,220,140,254,254,126,156, 56,113, 2, 14,135, 3, 13, 13, 13,152, 59,119,174,207, 54, 47, 40, 40,192,219,
+111,191,141,146,146, 18,180,180,180,224,238,187,239, 6,207,243,136,139,139,195,232,209,163,117,115,129,188,181,255,147, 79, 62,
+ 57,172, 44,191,166, 89,160,225, 68,254, 80,228,183, 88, 44,136,141,141, 13,184, 20, 66, 20, 69, 93,123, 51, 95,164, 84,143,254,
+202,243, 1,134,234,245,212, 37,198,238, 50,235, 57, 6,227, 46,215,214,173, 91,189,246,112,161, 88,126,221,123,128, 96, 6, 46,
+134,186, 1,209,218, 89, 38, 24,249, 99, 99, 99,131, 42,133,208,155,252,238,237,154,158,158,142,101,203,150, 97,238,220,185,200,
+205,205,197, 93,119,221,133,179,103,207, 98,246,236,217,168,168,168, 64,102,102,166,215,107, 59,122,244, 40, 86,174, 92, 9,171,
+213,138,184,184, 56,236,222,189, 27, 13, 13, 13,168,169,169, 65, 70, 70,134,174,110,169,187, 44,235,214,173,139,234, 76,181,144,
+ 71,130,135, 10, 36,253,165, 65,171,171,171,241,209, 71, 31,225,242,229,203,184,120,241, 34,146,147,147,135, 21,249,221, 27, 86,
+ 93, 10,161, 14,144,221, 75, 33, 34, 33,191,250, 58, 42, 43, 43,209,219,219,139,238,238,110,252,225, 15,127, 0,199,113,152, 55,
+111, 30, 30,122,232, 33,252,242,151,191,196,178,101,203,148,210,105,249,218,250,250,250, 80, 92, 92,140,242,242,114,216,108, 54,
+ 28, 56,112, 0,221,221,221,216,180,105, 19, 82, 82, 82,144,156,156,172, 43,249, 43, 42, 42,192, 48, 12,230,204,153, 3, 0,216,
+188,121,179,207, 94, 34, 88,203,175,107, 15, 16,108,142,214,155, 2,136,162,136,157, 59,119,162,167,167, 7,113,113,113,176, 90,
+173,104,106,106, 82,234,237,135, 11,249,101,249,229,218, 30,117, 41,132, 76,124,245, 56,128,124, 92, 79, 23,200,151,251,150,156,
+156,140,212,212, 84, 60,240,192, 3, 88,191,126, 61, 86,174, 92,137,236,236,108,172, 91,183, 14,133,133,133,216,180,105, 19, 10,
+ 10, 10, 64, 81, 20,142, 30, 61,138,226,226, 98,188,247,222,123,136,143,143,135,197, 98,193,238,221,187,177,123,247,110,100,103,
+103, 71,196,242,115, 28,135,156,156, 28,165,174, 73, 61,121, 61,152,146,109,189,225, 51, 8,246, 38, 88, 77, 77, 13, 14, 30, 60,
+136, 43, 87,174,224,226,197,139, 72, 74, 74,242,122,179, 94,121,229, 21, 52, 54, 54, 98,194,132, 9,232,233,233, 65, 71, 71, 7,
+172, 86, 43, 4, 65, 64,122,186,254,187, 31, 5,187,140,134, 92,219,227,173,212, 65, 61, 30, 32, 31,215, 59,155,229, 79,238, 61,
+123,246,224,209, 71, 31, 69,103,103, 39, 58, 59, 59,177,114,229, 74,204,159, 63, 31,251,246,237,195,246,237,219,193, 48, 12, 86,
+174, 92,137,242,242,114,196,199,199, 43, 3, 96,171, 87,175,198,142, 29, 59,240,230,155,111,234, 46, 63, 77,211,152, 53,107,150,
+ 75, 81, 95, 73, 73,201,144, 22, 63, 80,203, 31,177, 30, 64, 93,219,255,225,135, 31,194, 98,177, 32, 33, 33, 1,141,141,141,104,
+110,110, 70, 69, 69,133, 11, 33,228,155,244,167, 63,253, 9, 6,131, 1,231,206,157,131,197, 98, 65, 91, 91, 27,186,187,187, 33,
+ 8, 2, 30,124,240,193,168,165, 65,135,202, 2,169, 75, 33,220,201, 47, 31,143,180, 11,167,150,251,228,201,147,104,110,110,198,
+146, 37, 75,112,250,244,105,140, 31, 63, 30, 38,147, 9, 70,163, 17,207, 60,243, 12, 94,121,229, 21, 80, 20, 5,139,197, 2,187,
+221, 14,171,213,170,244, 0,247,222,123, 47, 86,173, 90,133, 19, 39, 78, 96,198,140, 25, 17, 73, 66,168,211,158,235,215,175, 31,
+ 50, 22,139,164,229, 15, 56, 6,160, 40, 10,191,251,221,239,208,210,210,226,215,162,171,133, 55,153, 76, 74, 53,160, 32, 8,112,
+ 56, 28,144, 36, 9,207, 61,247, 28, 54,110,220, 24,149,177, 0,127, 89, 32,185,182, 71, 93, 10,225, 45, 14,144, 75, 33,244,118,
+129,124,201,253,244,211, 79,227,253,247,223, 71,111,111, 47, 38, 79,158,140,207, 62,251, 12,239,188,243, 14,126,246,179,159, 97,
+249,242,229,104,105,105, 81, 50, 68, 7, 14, 28, 80, 42, 66,239,189,247, 94,176, 44,139,226,226, 98, 60,246,216, 99,248,250,235,
+175, 35,222,254, 37, 37, 37, 62,107,129,130,181,252,186,103,129,220,133,255,232,163,143,192,113,156, 87,139,254,192, 3, 15,120,
+104,238,222,189,123,241,212, 83, 79,161,169,169, 9,241,241,241, 72, 78, 78,198,134, 13, 27, 48,107,214,172,168, 90, 80, 95,150,
+ 71,174,237, 9,180, 20, 34, 82, 46,144,187,220,227,199,143,199, 39,159,124,130, 21, 43, 86,224,225,135, 31,198,164, 73,147,176,
+109,219, 54,236,217,179, 7, 29, 29, 29,184,239,190,251, 64, 81, 20,118,237,218,133,238,238,110,236,222,189, 27, 59,118,236,192,
+170, 85,171, 80, 92, 92,140, 67,135, 14,185,100,184, 34,217,254, 27, 54,108, 24, 86,150, 63,168, 32, 56, 62, 62, 30,167, 78,157,
+242,176,232, 27, 55,110,116,153,147, 41, 99,210,164, 73,248,248,227,143,163, 58,144, 20,108, 29,144,108,217, 3, 41,133,136,196,
+ 53,120,147,253,221,119,223,197, 35,143, 60,130,131, 7, 15, 98,235,214,173,184,237,182,219, 64, 81, 20,214,172, 89,131,173, 91,
+183, 42,138,220,208,208,128, 77,155, 54, 33, 59, 59, 27,219,182,109, 67,117,117, 53, 30,123,236, 49,100,102,102, 98,247,238,221,
+ 81,105,255,223,254,246,183, 67, 86,131,134,242, 95,186,245, 0,106,225,119,238,220,137,103,158,121, 70, 9,168,212, 22,125, 56,
+142,168, 6,187, 12,139,236,210, 4, 90, 10,161,183, 11,228, 75,118,131,193,128, 29, 59,118,120, 28, 79, 77, 77, 69,117,117,181,
+ 50,158,241,221,119,223, 33, 37, 37, 69,249,222,140, 25, 51,116,119,123,134,186,134,103,158,121,102, 88,142,200, 7,148, 5,154,
+ 52,105, 18,254,252,231, 63,143,152,114,130, 96,179, 64,193,146, 57, 26, 89, 32,127,228, 73, 74, 74, 66, 71, 71, 7, 70,141, 26,
+ 5, 0,200,200,200, 80,166, 67, 14,151,246,255,205,111,126,227,115, 12, 32,146, 22, 63,164, 44,208, 72,172,165, 9, 69,254, 64,
+ 75, 33,134,147,252,242,231,234,194,182,104,141,190,251,147,255,217,103,159, 29,150,252, 9, 40, 8,214,107,246, 80,180,131, 96,
+119,151, 38,208, 82,136, 72,215, 2, 5, 90, 54, 16,109,242,143, 68,254,208, 55, 59,249,213, 46,141,123, 41,132,250,123,234, 82,
+136, 72,186, 64,234,133,163, 8,249, 93,241,194, 11, 47,192,233,116,234,215, 3,140, 52,242,135, 43,127,160,165, 16,195, 33,139,
+ 53, 28,201, 31,105,254,132, 59, 31,216,107, 15, 48, 84, 38, 98, 36, 32, 88,249,229,244,102,160,165, 16,122,167, 67, 71, 50,249,
+ 71, 26,127, 60,122, 0,135,195,129,115,231,206,249, 92,193, 75, 79,168, 55,125, 8, 21,161,200, 47,187, 52,238,171, 66,200,121,
+107, 89, 9,228, 82, 8,249,251,103,206,156,209, 92,254,129,129, 1,156, 63,127, 62,160,149, 52,180, 38, 86,180,218, 63,154,252,
+113,145,170,160,160,160,213,102,179,165, 69, 83, 35,121,158,111, 43, 45, 45, 13,169, 98,110,238,220,185,130,221,110,167,163, 44,
+191, 88, 90, 90,202,132, 40,127,171,221,110, 31,177,237, 63,210,249, 67, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
+ 64, 64,240,223, 21, 20,105, 2,130, 72,225,198, 62,194,135, 1,228,233,245, 31, 28,199,181,149,149,149, 5,156, 6,101,201,109,
+ 33,136, 32,249,191,188,177,143, 48,170,170,170,144,145,145,161,108, 88,238, 62, 73,201,125, 65, 48,247,215,222,150, 73,180, 88,
+ 44, 88,186,116,105, 80,227, 16, 68, 1, 8, 34, 70,254, 45, 91,182,240, 69, 69, 69, 19, 1,160,170,170, 10,131,131,131, 72, 72,
+ 72, 80, 54,201, 14,164,240,207,223,241, 11, 23, 46, 4, 45,155,203,168,169,209,104, 44,166,105,218, 1, 64, 10,228, 65, 81,148,
+ 13,192, 6,114,139, 9,134, 34,255,230,205,155,249,133, 11, 23, 78, 84,136, 71,211, 46, 53, 85,129,204,226,211,125,167,120,187,
+221,190,177,166,166,134,157, 56, 81,145,211, 99,114,184, 26,205,205,205,214,156,156,156,231, 1,188, 66,110, 53,129, 47,242,151,
+148,148, 24, 23, 45, 90,148,165, 62,166,222,161, 83,171,237,147, 66,129,139, 2,136,162,200,102,101,101,161,183,183,215,163,226,
+209,155, 34,164,165,165, 93, 3, 48,153,220,106, 2,127,228, 95,188,120,113,150,251,113,245,222,192, 90,238, 29, 22,150, 2,168,
+ 20,193,239, 68, 3, 89, 25, 4, 65, 16,201,173, 38, 8,150,252, 0,148, 29,238,229, 30, 64,171,141,243,194,138, 1,124, 89,123,
+121,211,102,249,161,238, 49, 0, 12, 2,200, 32,183,157,192,221,231,247, 69,126, 0,224,121,222,227,179, 96,253,125, 93,118,138,
+111,110,110,198,145, 35, 71, 48, 48, 48,160,144, 93, 77,122,245,103, 44,203,166,254,226, 23,191,232,123,231,157,119, 46,250,136,
+ 21, 40, 47, 10, 69,121, 81, 56,151,207,104,154,118,114, 28,247,242,224,224, 96, 49,161,212,200,204,246,168, 3, 94, 0,176,217,
+108,104,108,108, 68, 83, 83, 19, 58, 59, 59, 93,210,159,195,106,163,108,134, 97, 16, 19, 19,227, 98,237,125, 41, 0,128,132,123,
+238,185, 7,143, 60,242,136, 18, 51,200, 19, 72,124,229,113,213, 83, 13,221,143,201,104,106,106, 98,151, 47, 95,190, 17, 0, 81,
+128, 17, 4, 81, 20, 15,223,200,243, 79, 20, 69, 17, 45, 45, 45,168,171,171,195,233,211,167,209,222,222,142,132,132, 4, 36, 39,
+ 39,195,108, 54,195,100, 50,121, 40, 64,184,177, 64,216, 65, 48, 0, 56,157, 78,244,247,247,163,191,191,223, 27,225, 61,148,161,
+172,172, 76,209,102,111,110,148,183,158,193,215,111,202,207, 61, 61, 61,178,123, 69, 48,178,144,151,155,155,139,237,219,183,163,
+161,161, 1, 12,195, 32, 45, 45, 13, 41, 41, 41, 24, 59,118, 44, 56,142, 3,203,178,224, 56, 14, 70,163, 17, 44,203, 42,177,128,
+ 86,129,176, 38, 61, 64,108,108,172,203,142,136, 67,244, 2,144, 36,201,231,247,135, 58,207,219,177, 72, 45, 65, 72,160, 61,250,
+250,250, 16, 31, 31,143,162,162, 34, 36, 38, 38,202, 46,173,242, 44,175,112,199,113, 28,120,158, 7,195, 48, 16,122,175,161,225,
+173,255,141,254,150,179,136, 73, 29,131, 49,119, 60,140,177,119,252,159,232,100,129,156, 78, 39,250,250,250,208,215,215, 23,176,
+ 5,215,138,248,242,179,197, 98, 33, 76, 26,161,136,139,139, 67,126,126, 62, 4, 65,240,234,234,210, 52, 13,134, 97, 96, 48, 24,
+148,231,150,175,246, 34, 65,186,134,249,247, 44,133,197, 98,199,241, 67,111, 97,160,177, 26,217,255,252, 6, 40, 47,113,130,150,
+ 89, 32, 15, 5,144,151,215, 22, 69, 81, 83, 82, 7,115, 44,220,181, 94, 8,162, 7,217,197,241,182, 16,174,154,180, 12,195, 40,
+229, 15,163,231,174,194,201,191,238, 68,231,229, 22,140,190,117, 38, 10, 87,164,225,196,223,171,112,226,133,229,152,246,244,191,
+129, 55,167, 6,181, 15,181,102, 49, 64, 36, 20,192, 91,207, 66,122,128,145,173, 0, 44,203, 42,247,211,215,174,149,234,116,103,
+220,184, 91, 48,245,233,127,199,177, 45,247, 35,207, 1,140,187,125, 62,110,191, 99, 9,206,125, 91,137,111,215,207,199,109, 27,
+247, 35,126,194,173,250,151, 66,200, 49,128,209,104,132, 32, 8, 97, 19, 62,212,243,237,118, 59, 97,210, 8,133,175,101, 91, 36,
+135, 13,151,246,174, 71,111,221,223, 33,216,108,144, 36, 17,144, 36, 72,162,120,253, 53, 0,138,166,241,221,183,103, 64,153, 51,
+ 48,238,214,169,152, 52,243, 7, 72, 72, 78,194,177,231,151, 97,234,163,239, 97,244,172,229, 67,238, 86,170, 73, 15, 48, 48, 48,
+224, 17, 3,132, 74,106,111,239,135, 58,207,106,181, 18, 38,141, 96, 5,240,182,150, 81,235, 95,222, 69,220, 96, 51,110,255,209,
+ 63,128,229, 56, 80, 52, 11,138, 97,111, 60, 51, 0,197, 0, 20,125,253,193,242,144,156, 54,192, 97,193,168,239,229,160, 48,105,
+ 20,202,255,245, 23, 24,184,180, 22,147,254,105,157,223, 77, 54, 52,235, 1,100, 63, 92, 38,103, 93, 93, 29,170,171,171, 49, 56,
+ 56, 8,187,221, 14,135,195, 1,187,221,238,242,218,225,112,104,150,193,161,105, 90, 20, 69, 81,242,209,200, 86, 73,146, 54, 2,
+120,157, 80,110,120, 42,129, 90, 1,104,154,134,104,183, 34, 54, 54, 6, 28,108,160, 4, 1,144, 88, 64, 50, 0, 52, 11, 9, 70,
+ 64, 24, 0,104,246,186, 34, 56, 44,128, 36, 1, 6, 35,224,180, 33, 46,209,140,249,247,172, 66,213,103, 31,160,191,177, 6,183,
+ 61,245, 1, 40,138,214, 47, 11,228,173, 7, 56,121,242, 36,246,238,221,139,212,212,212, 72,181,163,207, 97,189,150,150,150,152,
+217,179,103,191,234,116, 58,137, 2, 12, 99, 5, 80, 19, 52,109,209, 67,104,220,245,107,156, 62,118,200,165, 22,128,102, 12,184,
+117,217, 61,152, 48,214, 4, 26, 34, 40,134,189,113,235, 69, 72,130, 19, 0, 5, 8,118, 24, 40, 96,206,157,255,136,227,127,253,
+ 18,117,239, 61,137,105,107,223,208,100,217, 69,175, 89, 32,163,209, 8,135,195,225,226,150,112, 28,135,212,212, 84, 52, 53, 53,
+185, 28, 11, 7,254, 74,173,253,161,175,175, 15, 78,167,211, 64,168, 54,124, 93, 32,247, 71, 76, 90, 22,114, 55,236, 87,122, 4,
+123, 71, 11,106,183,254, 79,228,204,153,143,140,172, 81,144,108,189,160, 24, 14, 84,242, 36,208, 19,139, 64, 37,100, 0, 20, 13,
+169,251, 34,196,179,159, 67,188, 82, 13, 88, 59, 49,125,225, 2,124,179,255, 0, 46, 29,154,129,204,101, 63, 11,123,217, 69, 15,
+ 5, 16, 4,193,101, 36,216,221, 87,183,219,237,176,217,108, 81,109,100,185,119, 34, 24,158,240, 87,229, 73,211, 52,250,206,126,
+139,134,119, 30,198,237, 63,188, 11, 73,102, 14,210,192, 53,128, 53,130,154,184, 0, 76,246, 10, 80,234,169,145,105,121,160, 71,
+ 79,133,112,250, 63,225, 60,177, 15,204, 96, 59,102, 47, 91,130, 35,127,120, 6, 19,254,199,131,160, 13,124,120, 89, 43,111,194,
+199,196,196,192,233,116,186, 88,104,185,122,207,189, 34, 52, 26,136,246,255, 19, 4, 31, 4,203,228,191,250,247,127,195,229,131,
+175, 99,238,170, 31, 35,150,177, 0,150, 94,128,225,129,132,113,160, 38,255, 3, 4, 81,196,153,166, 78,212, 54,118,194, 50,232,
+196,196,177, 9,152,153, 61, 26,252,148,101,144,202,182, 65,104,248, 11,184, 81, 57, 24, 53,126, 2,174, 30,251, 28, 99,126,240,
+ 67,109, 21, 64, 16, 4, 12, 12, 12,184,140, 3,184,247, 2,132,128, 4,193, 4,193, 20, 69,129,166, 40, 52,126, 88,140,193,179,
+101,152,183,234, 71,224,108, 87, 33, 57,132,235,214,158, 18, 32,101, 21, 65, 16, 37,156,187,220,141,191, 84, 52,193, 41,136, 56,
+118,230, 42,206,182,116,227,159,255,113, 42, 30,186,227, 22, 72,115, 31, 7, 26,254, 2,169,255, 42,198,140,189, 13,151, 14,239,
+210, 94, 1,228, 24, 64,206,197,203,100,231,121,222,235,156, 0,210, 3, 16,248,235, 1,228, 12, 80,237,155, 63,131,137, 19, 48,
+251,142,133, 96,196, 1, 88,185,116, 56, 41, 30,241,150, 6, 80,160, 32,198,141,129,228,116,162,236, 84, 43, 46,119, 12,160,170,
+190, 21,253,214,235,177,230,159,191,108,192,143, 11,179,192,143,206, 7, 77,209,144,172, 93, 48,103, 36,160,174,186, 50,108,121,
+253,246, 0,106,178,169,139,221,136, 2, 16, 4,154, 5,114,116,181,226, 84,201, 63, 33, 51, 39, 27,147,110,153, 0, 56, 7,208,
+221,231, 64,233,199,251, 48,239,254,135, 0,138,129, 36,216, 33, 56,157,144, 4, 1, 45,215,250,240, 85,245, 37,168,111,177,145,
+ 99, 0, 73,132,195,233, 0,127,253, 15,192, 24, 56, 56,172,253,218, 43, 0, 77,211,224,121, 30, 70,163,209,174,244, 93,155, 0,
+ 0, 4,137, 73, 68, 65, 84,133,112,242,123,162, 0, 4,129,246, 2,131, 87, 47,226,228,203,119, 34,191,168, 16,233,163,227, 1,
+209,137,182,214, 30,156,248,219, 87,136, 31,151, 3,199, 64, 15, 40, 51, 3,105,112, 0, 98,199, 89, 88, 17,139, 41, 99, 99,225,
+126,123, 23, 79, 31, 3, 65,112, 2, 45,223, 2,146, 8, 24, 98, 97,119, 72,136, 73, 14,127, 43, 2,143, 92,187, 60, 14, 32,247,
+ 2,253,253,253,202,236,176,225,244, 32, 24,222,228,167, 40, 10, 13,255,250, 47,200,159, 63, 15,105,137, 20, 36,198,128,198,243,
+173, 56, 89, 86,137, 89,175,124,137,180,194,123,208,121,249, 50,192, 39, 92, 31,248,250,250, 21,216,172, 22,204,201, 78,194,125,
+ 69,153, 24,101, 54,194, 28,103,192,178,239,143,197,157,115,198,194,225,112,128,173,120,227, 58,105, 19, 51,209,221,213,135,164,
+ 91,230,106,223, 3,200, 35,193,118,187,221, 37,240,245, 54,135, 51, 90, 86,153, 40,192,200, 80, 2,103,239, 53, 36,143,155, 7,
+ 73,178,227,244,137,211,104,191,218,141,217,175, 30,129, 33, 62, 17,227, 22,175, 70,217,255,123, 27, 89,121,121,160, 91,190, 5,
+107,237,130,177,244, 37,244,205,122, 26,119, 23,140,197,221, 5, 99,255, 43,150,128, 8, 67,197, 27, 48, 52,253, 13,160, 89,136,
+ 99,102,226,204,127,124,133,121,175,188,169,189, 2, 56,157, 78, 88, 44, 22, 12, 12, 12,184,144, 77,174,239, 38, 22,152, 32,208,
+ 30, 32,225,150, 2,148,127,250, 57, 28,150,126,152, 38,127, 31,183,255,223, 63,129, 49,240,215, 39,197,196,153, 49,126,249, 26,
+156, 59,245, 53,110,201,248, 62,132,115,159, 35,254,228, 78,112,173, 85,232,207, 95, 3,123,106, 62, 68,138, 1,215, 81,131,248,
+ 83,127, 0,127,165,236,186,245, 31, 55, 27,205, 45, 93, 24,117,219, 18,196,103, 76,209, 39, 6,144,103,235,168, 21,128,196, 0,
+ 4,193, 42,193, 45, 15,191, 5, 75,115, 61, 56, 83, 50,140, 41, 99, 61,198, 5, 38,174,252, 23,124,245,200,187, 48, 39, 23, 96,
+ 76,222, 61, 16, 78,255, 39,184,246,239,144,252,197, 47, 60,127,148,225,192, 76, 94,138, 46,167, 25,167, 43,190,192,226,237,199,
+ 53,145,213,107, 22,200,106,181,122,237, 1,252,213,242, 19, 5, 32,112, 87, 0,154,166, 97,202,156,234,187,126,159,143, 65,225,
+230,175, 81,245,210, 42,116,143, 78, 70,206,109, 15,129,106, 61, 6,169,175, 21, 82,223, 21, 64, 20, 64,197,167,129, 50,141, 1,
+149,158,143,198,243, 87,208,120,178, 12,133,175,254, 21,198,228,116,125, 20,192,189, 7,144, 9, 23, 19, 19, 67,122, 0,130,160,
+200, 31,200, 92,222,152,212, 12,204,127,173, 12,167,222,123, 2,127, 63,240, 23,140,157, 50, 5, 73,163, 38,195,148,147, 14,138,
+166,209,223,126, 13, 61,215,218,113,249,175, 21, 48,142,202,194,226,119,190, 3, 27, 19,175,153,188, 94,123, 0,139,197, 2,139,
+197,226, 98,241, 29, 14,135, 50, 97, 93,239, 73,235, 67, 17,156, 76,154, 31,222, 8,122,133, 7,214,128,252, 71,182,161,239, 82,
+ 61, 58, 78,254, 29,205,213,135,209,241,197, 62, 72,130, 19, 73,217,223, 71,202,140, 59, 48,253,174, 66, 36, 77,153,169,185,172,
+ 62,199, 1,228,145, 95,181, 98, 72,146, 4,167,211,169,217,156,221, 80, 45, 57,153, 51, 60, 50,130,224, 96, 22,181,162, 40, 10,
+230,204, 92,152, 51,115,241,189, 31,174,137,152,188, 94,123, 0,155,205,230,210, 3,200,100, 21, 69, 17, 14,135, 67,119, 2, 14,
+165, 24, 54,155, 13, 20, 69,137,196, 21, 26, 25, 74, 16, 8,249, 35,177,147,252,144, 10,192,178,108,255,213,171, 87,227, 71,143,
+ 30,237, 82, 10, 33,138, 34,210,210,210,148, 50,137,104, 90,127, 73,146,112,229,202, 21,240, 60,127,105,112,112,144,176,109,152,
+ 43,192,112, 38,191,135, 2, 24,141,198,147,135, 15, 31,158,179,116,233, 82,212,213,213, 65, 16, 4,101,121,148,217,179,103,163,
+171,171, 43,104,235,175,181,149,150, 36, 9, 53, 53, 53,131,162, 40,150, 17,170, 17,242,107,170, 0, 14,135, 99,211,206,157, 59,
+255, 99,213,170, 85,134,159,252,228, 39, 56,115,230, 12, 40,138, 66, 78, 78, 14,210,211,211,113,252,248,241,168,251,255,151, 47,
+ 95,198,167,159,126,234,176,219,237,207, 19,186,141,188, 32, 56,156,133,108,117, 87, 0,155,205,118,152,231,249,119, 86,174, 92,
+185,118,237,218,181,134, 69,139, 22, 33, 61, 61, 29, 61, 61, 61, 40, 47, 47, 15,105,185, 18, 45,122, 0, 65, 16,208,214,214,134,
+154,154, 26,235,193,131, 7, 5, 81, 20,127, 13,224, 12,161,218,200, 9,130,135, 35,249,125,107, 5,203, 46,141,141,141, 61,202,
+178,108, 63, 2,220, 47, 76,207, 7, 69, 81, 2,207,243,141, 6,131,225, 67, 0,217,132,102,195, 19, 51,103,206,148,156, 78,167,
+100,177, 88, 36,171,213, 42, 13, 14, 14, 74, 54,155, 77,178,219,237,146,195,225,144,156, 78,167, 36,138,162,110,143,250,250,122,
+105,230,204,153, 65, 89, 92,175, 43, 48, 59,157,206,207,157, 78,231,231,195,165, 97, 37, 73,138,250, 60,100,130,192, 96,183,219,
+113,246,236, 89,175,126,190,222,150,223, 96, 8,126,157, 4,178, 4, 57,129,102,224,121,190,109,254,252,249,105,209,150,129,220,
+ 9, 2, 2, 2, 2, 2, 2, 2, 2,191,248,255, 88,111,246,205,191, 63,162, 3, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130,
+ 0};
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 4375bd027d7..d16ac563eb3 100644
--- a/source/blender/editors/include/BIF_transform.h
+++ b/source/blender/editors/include/BIF_transform.h
@@ -56,7 +56,6 @@ enum {
TFM_WARP,
TFM_SHRINKFATTEN,
TFM_TILT,
- TFM_LAMP_ENERGY,
TFM_TRACKBALL,
TFM_PUSHPULL,
TFM_CREASE,
@@ -96,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);
@@ -131,5 +131,35 @@ 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 peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, short mval[2]);
+int peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, short mval[2]);
+int snapObjectsTransform(struct TransInfo *t, short mval[2], int *dist, float *loc, float *no, SnapMode mode);
+int snapObjectsContext(struct bContext *C, short mval[2], int *dist, float *loc, float *no, SnapMode mode);
+
#endif
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 08c5f752fd1..0210e3d6a85 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -149,12 +149,13 @@ typedef enum eAnim_KeyType {
typedef enum eAnimFilter_Flags {
ANIMFILTER_VISIBLE = (1<<0), /* should channels be visible (in terms of hierarchy only) */
ANIMFILTER_SEL = (1<<1), /* should channels be selected */
- ANIMFILTER_FOREDIT = (1<<2), /* does editable status matter */
- ANIMFILTER_CURVESONLY = (1<<3), /* don't include summary-channels, etc. */
- ANIMFILTER_CHANNELS = (1<<4), /* make list for interface drawing */
- ANIMFILTER_ACTGROUPED = (1<<5), /* belongs to the active actiongroup */
- ANIMFILTER_CURVEVISIBLE = (1<<6), /* F-Curve is visible for editing/viewing in Graph Editor */
- ANIMFILTER_ACTIVE = (1<<7), /* channel should be 'active' */ // FIXME: this is only relevant for F-Curves for now
+ ANIMFILTER_UNSEL = (1<<2), /* should channels be NOT selected */
+ ANIMFILTER_FOREDIT = (1<<3), /* does editable status matter */
+ ANIMFILTER_CURVESONLY = (1<<4), /* don't include summary-channels, etc. */
+ ANIMFILTER_CHANNELS = (1<<5), /* make list for interface drawing */
+ ANIMFILTER_ACTGROUPED = (1<<6), /* belongs to the active actiongroup */
+ ANIMFILTER_CURVEVISIBLE = (1<<7), /* F-Curve is visible for editing/viewing in Graph Editor */
+ ANIMFILTER_ACTIVE = (1<<8), /* channel should be 'active' */ // FIXME: this is only relevant for F-Curves for now
} eAnimFilter_Flags;
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 290c7bfbcad..0f2ac6e3027 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -37,6 +37,7 @@ struct bPoseChannel;
struct wmWindowManager;
struct ListBase;
struct View3D;
+struct ViewContext;
struct RegionView3D;
typedef struct EditBone
@@ -111,8 +112,8 @@ 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 armature_bone_rename(Object *ob, char *oldnamep, char *newnamep);
+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(struct Object *ob, char *oldnamep, char *newnamep);
void undo_push_armature(struct bContext *C, char *name);
@@ -122,6 +123,27 @@ void ED_armature_enter_posemode(struct bContext *C, struct Base *base);
int ED_pose_channel_in_IK_chain(struct Object *ob, struct bPoseChannel *pchan);
void ED_pose_deselectall(struct Object *ob, int test, int doundo);
+/* sketch */
+
+int ED_operator_sketch_mode_active_stroke(struct bContext *C);
+int ED_operator_sketch_full_mode(struct bContext *C);
+int ED_operator_sketch_mode(struct bContext *C);
+
+void BIF_freeSketch(struct bContext *C);
+void BIF_convertSketch(struct bContext *C);
+void BIF_deleteSketch(struct bContext *C);
+void BIF_selectAllSketch(struct bContext *C, int mode); /* -1: deselect, 0: select, 1: toggle */
+
+void BIF_makeListTemplates(struct bContext *C);
+char *BIF_listTemplates(struct bContext *C);
+int BIF_currentTemplate(struct bContext *C);
+void BIF_freeTemplates(struct bContext *C);
+void BIF_setTemplate(struct bContext *C, int index);
+int BIF_nbJointsTemplate(struct bContext *C);
+char * BIF_nameBoneTemplate(struct bContext *C);
+
+void BDR_drawSketch(struct bContext *vc);
+int BDR_drawSketchNames(struct ViewContext *vc);
#endif /* ED_ARMATURE_H */
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index df5cf13df55..bb5ced66428 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -59,6 +59,28 @@ typedef struct FileSelectParams {
/* XXX --- end unused -- */
} FileSelectParams;
+#define FILE_LAYOUT_HOR 1
+#define FILE_LAYOUT_VER 2
+
+typedef struct FileLayout
+{
+ /* view settings - XXX - move into own struct */
+ short prv_w;
+ short prv_h;
+ short tile_w;
+ short tile_h;
+ short tile_border_x;
+ short tile_border_y;
+ short prv_border_x;
+ short prv_border_y;
+ short rows;
+ short columns;
+ short width;
+ short height;
+ short flag;
+
+} FileLayout;
+
FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile);
short ED_fileselect_set_params(struct SpaceFile *sfile, int type, const char *title, const char *path,
@@ -66,5 +88,16 @@ short ED_fileselect_set_params(struct SpaceFile *sfile, int type, const char *ti
void ED_fileselect_reset_params(struct SpaceFile *sfile);
+
+void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar);
+
+
+FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar);
+
+int ED_fileselect_layout_offset(FileLayout* layout, int x, int y);
+
+void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, short *x, short *y);
+
+
#endif /* ED_FILES_H */
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index f431b5d5f84..22a13f7123e 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -86,6 +86,12 @@ void ED_keymap_mesh(struct wmWindowManager *wm);
/* editmesh.c */
+
+/*accessor functions for editmesh, all access to editmesh must
+ go through them!*/
+struct EditMesh *EM_GetEditMesh(struct Mesh *me);
+void EM_EndEditMesh(struct Mesh *me, struct EditMesh *em);
+
void ED_spacetypes_init(void);
void ED_keymap_mesh(struct wmWindowManager *wm);
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 0433bf3f235..847120a5804 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -73,6 +73,7 @@ void ED_area_do_refresh(struct bContext *C, ScrArea *sa);
void ED_area_headerprint(ScrArea *sa, const char *str);
void ED_area_newspace(struct bContext *C, ScrArea *sa, int type);
void ED_area_prevspace(struct bContext *C);
+void ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2);
/* screens */
void ED_screens_initialize(struct wmWindowManager *wm);
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/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 60d504c21fe..f7d21d0374c 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -36,11 +36,13 @@ struct ID;
struct Main;
struct ListBase;
struct ARegion;
+struct ScrArea;
struct wmWindow;
struct wmWindowManager;
struct wmOperator;
struct AutoComplete;
struct bContext;
+struct Panel;
struct PointerRNA;
struct PropertyRNA;
struct ReportList;
@@ -85,6 +87,7 @@ typedef struct uiPopupBlockHandle uiPopupBlockHandle;
#define UI_BLOCK_MOVEMOUSE_QUIT 128
#define UI_BLOCK_KEEP_OPEN 256
#define UI_BLOCK_POPUP 512
+#define UI_BLOCK_2_50 1024 /* XXX 2.5 migration flag */
/* uiPopupBlockHandle->menuretval */
#define UI_RETURN_CANCEL 1 /* cancel all menus cascading */
@@ -190,6 +193,7 @@ typedef struct uiPopupBlockHandle uiPopupBlockHandle;
void uiEmboss(float x1, float y1, float x2, float y2, int sel);
void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad);
void uiSetRoundBox(int type);
+int uiGetRoundBox(void);
void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad);
void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag, short direction);
void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy);
@@ -302,7 +306,7 @@ void uiTextBoundsBlock(uiBlock *block, int addval);
void uiPopupBoundsBlock(uiBlock *block, int addval, int mx, int my);
void uiMenuPopupBoundsBlock(uiBlock *block, int addvall, int mx, int my);
-int uiBlocksGetYMin (ListBase *lb);
+int uiBlocksGetYMin (struct ListBase *lb);
int uiBlockGetCol (uiBlock *block);
void uiBlockSetCol (uiBlock *block, int col);
@@ -310,6 +314,7 @@ void uiBlockSetEmboss (uiBlock *block, int emboss);
void uiBlockSetDirection (uiBlock *block, int direction);
void uiBlockFlipOrder (uiBlock *block);
void uiBlockSetFlag (uiBlock *block, int flag);
+void uiBlockClearFlag (uiBlock *block, int flag);
void uiBlockSetXOfs (uiBlock *block, int xofs);
int uiButGetRetVal (uiBut *but);
@@ -429,8 +434,8 @@ void uiDefKeyevtButS(uiBlock *block, int retval, char *str, short x1, short y1,
void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval);
-uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int x1, int y1, int x2, int y2);
-int uiDefAutoButsRNA(uiBlock *block, struct PointerRNA *ptr);
+uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2);
+int uiDefAutoButsRNA(const struct bContext *C, uiBlock *block, struct PointerRNA *ptr);
/* Links
*
@@ -499,11 +504,13 @@ extern void uiMatchPanelsView2d(struct ARegion *ar);
extern void uiNewPanelHeight(struct uiBlock *block, int sizey);
extern void uiNewPanelTitle(struct uiBlock *block, char *str);
-extern uiBlock *uiFindOpenPanelBlockName(ListBase *lb, char *name);
+extern uiBlock *uiFindOpenPanelBlockName(struct ListBase *lb, char *name);
extern int uiAlignPanelStep(struct ScrArea *sa, struct ARegion *ar, float fac);
extern void uiPanelControl(int);
extern void uiSetPanelHandler(int);
+struct Panel *uiPanelFromBlock(struct uiBlock *block);
+
/* Handlers
*
* Handlers that can be registered in regions, areas and windows for
@@ -512,22 +519,22 @@ extern void uiSetPanelHandler(int);
void UI_add_region_handlers(struct ListBase *handlers);
void UI_add_area_handlers(struct ListBase *handlers);
-void UI_add_popup_handlers(struct ListBase *handlers, uiPopupBlockHandle *menu);
+void UI_add_popup_handlers(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *menu);
/* Legacy code
* Callbacks and utils to get 2.48 work */
void test_idbutton_cb(struct bContext *C, void *namev, void *arg2);
-void test_scriptpoin_but(struct bContext *C, char *name, ID **idpp);
-void test_actionpoin_but(struct bContext *C, char *name, ID **idpp);
-void test_obpoin_but(struct bContext *C, char *name, ID **idpp);
-void test_meshobpoin_but(struct bContext *C, char *name, ID **idpp);
-void test_meshpoin_but(struct bContext *C, char *name, ID **idpp);
-void test_matpoin_but(struct bContext *C, char *name, ID **idpp);
-void test_scenepoin_but(struct bContext *C, char *name, ID **idpp);
-void test_grouppoin_but(struct bContext *C, char *name, ID **idpp);
-void test_texpoin_but(struct bContext *C, char *name, ID **idpp);
-void test_imapoin_but(struct bContext *C, char *name, ID **idpp);
+void test_scriptpoin_but(struct bContext *C, char *name, struct ID **idpp);
+void test_actionpoin_but(struct bContext *C, char *name, struct ID **idpp);
+void test_obpoin_but(struct bContext *C, char *name, struct ID **idpp);
+void test_meshobpoin_but(struct bContext *C, char *name, struct ID **idpp);
+void test_meshpoin_but(struct bContext *C, char *name, struct ID **idpp);
+void test_matpoin_but(struct bContext *C, char *name, struct ID **idpp);
+void test_scenepoin_but(struct bContext *C, char *name, struct ID **idpp);
+void test_grouppoin_but(struct bContext *C, char *name, struct ID **idpp);
+void test_texpoin_but(struct bContext *C, char *name, struct ID **idpp);
+void test_imapoin_but(struct bContext *C, char *name, struct ID **idpp);
void autocomplete_bone(struct bContext *C, char *str, void *arg_v);
void autocomplete_vgroup(struct bContext *C, char *str, void *arg_v);
@@ -552,5 +559,74 @@ uiBut *uiDefMenuSep(uiBlock *block);
uiBut *uiDefMenuSub(uiBlock *block, uiBlockCreateFunc func, char *name);
uiBut *uiDefMenuTogR(uiBlock *block, struct PointerRNA *ptr, char *propname, char *propvalue, char *name);
+/* Layout
+ *
+ * More automated layout of buttons. Has three levels:
+ * - Layout: contains a number templates, within a bounded width or height.
+ * - Template: predefined layouts for buttons with a number of slots, each
+ * slot can contain multiple items.
+ * - Item: item to put in a template slot, being either an RNA property,
+ * operator, label or menu currently. */
+
+/* layout */
+#define UI_LAYOUT_HORIZONTAL 0
+#define UI_LAYOUT_VERTICAL 1
+
+typedef struct uiLayout uiLayout;
+
+uiLayout *uiLayoutBegin(int dir, int x, int y, int w, int h);
+void uiLayoutContext(uiLayout *layout, int opcontext);
+void uiLayoutEnd(const struct bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y);
+
+/* vertical button templates */
+#define UI_TSLOT_COLUMN_1 0
+#define UI_TSLOT_COLUMN_2 1
+#define UI_TSLOT_COLUMN_3 2
+#define UI_TSLOT_COLUMN_4 3
+#define UI_TSLOT_COLUMN_5 4
+#define UI_TSLOT_COLUMN_MAX 5
+
+#define UI_TSLOT_LR_LEFT 0
+#define UI_TSLOT_LR_RIGHT 1
+
+void uiTemplateLeftRight(uiLayout *layout);
+void uiTemplateColumn(uiLayout *layout);
+uiLayout *uiTemplateStack(uiLayout *layout);
+
+/* horizontal header templates */
+#define UI_TSLOT_HEADER 0
+
+void uiTemplateHeaderMenus(uiLayout *layout);
+void uiTemplateHeaderButtons(uiLayout *layout);
+void uiTemplateHeaderID(uiLayout *layout, struct PointerRNA *ptr, char *propname, int flag, uiIDPoinFunc func);
+void uiTemplateSetColor(uiLayout *layout, int color);
+
+/* items */
+void uiItemO(uiLayout *layout, int slot, const char *name, int icon, char *opname);
+void uiItemEnumO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, int value);
+void uiItemsEnumO(uiLayout *layout, int slot, char *opname, char *propname);
+void uiItemBooleanO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, int value);
+void uiItemIntO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, int value);
+void uiItemFloatO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, float value);
+void uiItemStringO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, char *value);
+void uiItemFullO(uiLayout *layout, int slot, const char *name, int icon, char *idname, IDProperty *properties, int context);
+
+void uiItemR(uiLayout *layout, int slot, const char *name, int icon, struct PointerRNA *ptr, char *propname);
+void uiItemFullR(uiLayout *layout, int slot, const char *name, int icon, struct PointerRNA *ptr, char *propname, int index);
+
+void uiItemLabel(uiLayout *layout, int slot, const char *name, int icon);
+
+void uiItemMenu(uiLayout *layout, int slot, const char *name, int icon, uiMenuCreateFunc func);
+
+/* utilities */
+#define UI_PANEL_WIDTH 340
+#define UI_COMPACT_PANEL_WIDTH 160
+
+typedef void (*uiHeaderCreateFunc)(const struct bContext *C, uiLayout *layout);
+typedef void (*uiPanelCreateFunc)(const struct bContext *C, uiLayout *layout);
+
+void uiRegionPanelLayout(const struct bContext *C, struct ARegion *ar, int vertical, char *context);
+void uiRegionHeaderLayout(const struct bContext *C, struct ARegion *ar);
+
#endif /* UI_INTERFACE_H */
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 9387eabbae6..bf160b4ad68 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -44,6 +44,7 @@ typedef struct IconFile {
} IconFile;
#define ICON_DEFAULT_HEIGHT 16
+#define ICON_DEFAULT_WIDTH 16
#define PREVIEW_DEFAULT_HEIGHT 96
/*
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index e644c0aa019..e6c2dfb31e7 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -609,21 +609,21 @@ typedef enum {
ICON_IMGDISPLAY,
ICON_BLANK284,
ICON_BLANK285,
- ICON_FOLDER_DEHLT,
- ICON_FOLDER_HLT,
- ICON_BLUEIMAGE_DEHLT,
- ICON_BLUEIMAGE_HLT,
- ICON_BPIBFOLDER_DEHLT,
- ICON_BPIBFOLDER_HLT,
- ICON_BPIBFOLDER_ERR,
ICON_BOOKMARKS,
ICON_FONTPREVIEW,
- ICON_BLANK286,
- ICON_BLANK287,
- ICON_BLANK288,
- ICON_BLANK289,
- ICON_BLANK290,
- ICON_BLANK291,
+ ICON_FILTER,
+ ICON_BLANK285E,
+ ICON_BLANK285F,
+ ICON_FILE_PARENT,
+ ICON_FILE_REFRESH,
+ ICON_FILE_FOLDER,
+ ICON_FILE_BLANK,
+ ICON_FILE_BLEND,
+ ICON_FILE_IMAGE,
+ ICON_FILE_MOVIE,
+ ICON_FILE_SCRIPT,
+ ICON_FILE_SOUND,
+ ICON_FILE_FONT,
ICON_BLANK291b,
/* available */
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index cdb69477f12..0650a5611dc 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -56,6 +56,8 @@ enum {
V2D_COMMONVIEW_HEADER,
/* ui listviews, tries to wrap tot inside region width */
V2D_COMMONVIEW_LIST_UI,
+ /* ui region containing panels */
+ V2D_COMMONVIEW_PANELS_UI,
} eView2D_CommonViewTypes;
/* ---- Defines for Scroller/Grid Arguments ----- */
@@ -68,6 +70,7 @@ enum {
/* for drawing time */
V2D_UNIT_SECONDS = 0,
V2D_UNIT_FRAMES,
+ V2D_UNIT_FRAMESCALE,
/* for drawing values */
V2D_UNIT_VALUES,
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index d1c4447f215..7396edd3025 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -538,6 +538,8 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut
but->editcumap= oldbut->editcumap;
but->selsta= oldbut->selsta;
but->selend= oldbut->selend;
+ but->softmin= oldbut->softmin;
+ but->softmax= oldbut->softmax;
found= 1;
oldbut->active= NULL;
@@ -600,11 +602,15 @@ void uiEndBlock(const bContext *C, uiBlock *block)
/* temp? Proper check for greying out */
if(but->opname) {
wmOperatorType *ot= WM_operatortype_find(but->opname);
- if(ot==NULL || ot->poll((bContext *)C)==0) {
+ if(ot==NULL || (ot->poll && ot->poll((bContext *)C)==0)) {
but->flag |= UI_BUT_DISABLED;
but->lock = 1;
}
}
+
+ /* only update soft range while not editing */
+ if(but->rnaprop && !(but->editval || but->editstr || but->editvec))
+ ui_set_but_soft_range(but, ui_get_but_val(but));
}
if(block->oldblock) {
@@ -634,9 +640,14 @@ void uiEndBlock(const bContext *C, uiBlock *block)
void uiDrawBlock(const bContext *C, uiBlock *block)
{
- ARegion *ar= CTX_wm_region(C);
+ ARegion *ar;
uiBut *but;
+ /* get menu region or area region */
+ ar= CTX_wm_menu(C);
+ if(!ar)
+ ar= CTX_wm_region(C);
+
if(!block->endblock)
uiEndBlock(C, block);
@@ -646,11 +657,11 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
if(block->flag & UI_BLOCK_LOOP)
uiDrawMenuBox(block->minx, block->miny, block->maxx, block->maxy, block->flag, block->direction);
else if(block->panel)
- ui_draw_panel(CTX_wm_region(C), block);
+ ui_draw_panel(ar, block);
if(block->drawextra) block->drawextra(C, block);
- for (but= block->buttons.first; but; but= but->next)
+ for(but= block->buttons.first; but; but= but->next)
ui_draw_but(ar, but);
ui_draw_links(block);
@@ -686,14 +697,14 @@ static void ui_is_but_sel(uiBut *but)
case TOG3:
case BUT_TOGDUAL:
case ICONTOG:
- if(value!=but->min) push= 1;
+ if(value!=but->hardmin) push= 1;
break;
case ICONTOGN:
case TOGN:
if(value==0.0) push= 1;
break;
case ROW:
- if(value == but->max) push= 1;
+ if(value == but->hardmax) push= 1;
break;
case COL:
push= 1;
@@ -728,7 +739,7 @@ static uiBut *ui_get_valid_link_button(uiBlock *block, uiBut *but, short *mval)
}
}
else if(but->type==INLINK && bt->type==LINK) {
- if( bt->link->tocode == (int)but->min ) {
+ if( bt->link->tocode == (int)but->hardmin ) {
return bt;
}
}
@@ -1415,7 +1426,92 @@ void ui_set_but_string(uiBut *but, const char *str)
RNA_property_string_set(&but->rnapoin, but->rnaprop, str);
}
else
- BLI_strncpy(but->poin, str, but->max);
+ BLI_strncpy(but->poin, str, but->hardmax);
+}
+
+static double soft_range_round_up(double value, double max)
+{
+ /* round up to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, .. */
+ double newmax= pow(10.0, ceil(log(value)/log(10.0)));
+
+ if(newmax*0.2 >= max && newmax*0.2 >= value)
+ return newmax*0.2;
+ else if(newmax*0.5 >= max && newmax*0.5 >= value)
+ return newmax*0.5;
+ else
+ return newmax;
+}
+
+static double soft_range_round_down(double value, double max)
+{
+ /* round down to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, .. */
+ double newmax= pow(10.0, floor(log(value)/log(10.0)));
+
+ if(newmax*5.0 <= max && newmax*5.0 <= value)
+ return newmax*5.0;
+ else if(newmax*2.0 <= max && newmax*2.0 <= value)
+ return newmax*2.0;
+ else
+ return newmax;
+}
+
+void ui_set_but_soft_range(uiBut *but, double value)
+{
+ PropertyType type;
+ double softmin, softmax, step, precision;
+
+ if(but->rnaprop) {
+ type= RNA_property_type(&but->rnapoin, but->rnaprop);
+
+ if(type == PROP_INT) {
+ int imin, imax, istep;
+
+ RNA_property_int_ui_range(&but->rnapoin, but->rnaprop, &imin, &imax, &istep);
+ softmin= imin;
+ softmax= imax;
+ step= istep;
+ precision= 1;
+ }
+ else if(type == PROP_FLOAT) {
+ float fmin, fmax, fstep, fprecision;
+
+ RNA_property_float_ui_range(&but->rnapoin, but->rnaprop, &fmin, &fmax, &fstep, &fprecision);
+ softmin= fmin;
+ softmax= fmax;
+ step= fstep;
+ precision= fprecision;
+ }
+ else
+ return;
+
+ /* clamp button range to something reasonable in case
+ * we get -inf/inf from RNA properties */
+ softmin= MAX2(softmin, -1e4);
+ softmax= MIN2(softmax, 1e4);
+
+ /* if the value goes out of the soft/max range, adapt the range */
+ if(value+1e-10 < softmin) {
+ if(value < 0.0)
+ softmin= -soft_range_round_up(-value, -softmin);
+ else
+ softmin= soft_range_round_down(value, softmin);
+
+ if(softmin < but->hardmin)
+ softmin= but->hardmin;
+ }
+ else if(value-1e-10 > softmax) {
+ if(value < 0.0)
+ softmax= -soft_range_round_down(-value, -softmax);
+ else
+ softmax= soft_range_round_up(value, softmax);
+
+ if(softmax > but->hardmax)
+ softmax= but->hardmax;
+ }
+
+ but->softmin= softmin;
+ but->softmax= softmax;
+ }
}
/* ******************* Font ********************/
@@ -1676,14 +1772,14 @@ void ui_check_but(uiBut *but)
case NUMSLI:
case HSVSLI:
value= ui_get_but_val(but);
- if(value < but->min) ui_set_but_val(but, but->min);
- else if(value > but->max) ui_set_but_val(but, but->max);
+ if(value < but->hardmin) ui_set_but_val(but, but->hardmin);
+ else if(value > but->hardmax) ui_set_but_val(but, but->hardmax);
break;
case NUMABS:
value= fabs( ui_get_but_val(but) );
- if(value < but->min) ui_set_but_val(but, but->min);
- else if(value > but->max) ui_set_but_val(but, but->max);
+ if(value < but->hardmin) ui_set_but_val(but, but->hardmin);
+ else if(value > but->hardmax) ui_set_but_val(but, but->hardmax);
break;
case ICONTOG:
@@ -1694,21 +1790,18 @@ void ui_check_but(uiBut *but)
case ICONROW:
value= ui_get_but_val(but);
- but->iconadd= (int)value- (int)(but->min);
+ but->iconadd= (int)value- (int)(but->hardmin);
break;
case ICONTEXTROW:
value= ui_get_but_val(but);
- but->iconadd= (int)value- (int)(but->min);
+ but->iconadd= (int)value- (int)(but->hardmin);
break;
}
/* safety is 4 to enable small number buttons (like 'users') */
- if(but->type==NUMSLI || but->type==HSVSLI)
- okwidth= -4 + (but->x2 - but->x1)/2.0;
- else
- okwidth= -4 + (but->x2 - but->x1);
+ okwidth= -4 + (but->x2 - but->x1);
/* name: */
switch( but->type ) {
@@ -1739,13 +1832,20 @@ void ui_check_but(uiBut *but)
else sprintf(but->drawstr, "%s%.4f", but->str, value);
}
else {
- if(but->max<10.001) sprintf(but->drawstr, "%s%.3f", but->str, value);
+ if(but->hardmax<10.001) sprintf(but->drawstr, "%s%.3f", but->str, value);
else sprintf(but->drawstr, "%s%.2f", but->str, value);
}
}
else {
sprintf(but->drawstr, "%s%d", but->str, (int)value);
}
+
+ if(but->rnaprop) {
+ PropertySubType pstype = RNA_property_subtype(&but->rnapoin, but->rnaprop);
+
+ if (pstype == PROP_PERCENTAGE)
+ strcat(but->drawstr, "%");
+ }
break;
case LABEL:
@@ -2124,8 +2224,8 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
but->y2= (y1+y2);
}
but->poin= poin;
- but->min= min;
- but->max= max;
+ but->hardmin= but->softmin= min;
+ but->hardmax= but->softmax= max;
but->a1= a1;
but->a2= a2;
but->tip= tip;
@@ -2258,13 +2358,14 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
if(min == max || a1 == -1 || a2 == -1) {
if(proptype == PROP_INT) {
- int softmin, softmax, step;
+ int hardmin, hardmax, softmin, softmax, step;
+ RNA_property_int_range(ptr, prop, &hardmin, &hardmax);
RNA_property_int_ui_range(ptr, prop, &softmin, &softmax, &step);
if(min == max) {
- min= softmin;
- max= softmax;
+ min= hardmin;
+ max= hardmax;
}
if(a1 == -1)
a1= step;
@@ -2272,13 +2373,14 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
a2= 0;
}
else if(proptype == PROP_FLOAT) {
- float softmin, softmax, step, precision;
+ float hardmin, hardmax, softmin, softmax, step, precision;
+ RNA_property_float_range(ptr, prop, &hardmin, &hardmax);
RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision);
if(min == max) {
- min= softmin;
- max= softmax;
+ min= hardmin;
+ max= hardmax;
}
if(a1 == -1)
a1= step;
@@ -2302,7 +2404,11 @@ uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, char *str, short x1,
if(prop) {
but->rnapoin= *ptr;
but->rnaprop= prop;
- but->rnaindex= index;
+
+ if(RNA_property_array_length(&but->rnapoin, but->rnaprop))
+ but->rnaindex= index;
+ else
+ but->rnaindex= 0;
}
if (!prop || !RNA_property_editable(&but->rnapoin, prop)) {
@@ -2420,12 +2526,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);
}
@@ -2846,7 +2953,11 @@ void uiBlockFlipOrder(uiBlock *block)
void uiBlockSetFlag(uiBlock *block, int flag)
{
- block->flag= flag;
+ block->flag|= flag;
+}
+void uiBlockClearFlag(uiBlock *block, int flag)
+{
+ block->flag&= ~flag;
}
void uiBlockSetXOfs(uiBlock *block, int xofs)
{
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 5be578c4d50..fc2f5a15122 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -81,6 +81,14 @@ void uiSetRoundBox(int type)
}
+int uiGetRoundBox(void)
+{
+ if (ELEM3(UI_GetThemeValue(TH_BUT_DRAWTYPE), TH_MINIMAL, TH_SHADED, TH_OLDSKOOL))
+ return 0;
+ else
+ return roundboxtype;
+}
+
void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad)
{
float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
@@ -442,8 +450,8 @@ void uiRoundRectFakeAA(float minx, float miny, float maxx, float maxy, float rad
/* get the colour and divide up the alpha */
glGetFloatv(GL_CURRENT_COLOR, color);
- alpha = color[3];
- color[3]= alpha/(float)passes;
+ alpha = 1; //color[3];
+ color[3]= 0.5*alpha/(float)passes;
glColor4fv(color);
/* set the 'jitter amount' */
@@ -565,36 +573,6 @@ void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad,
glDisable( GL_BLEND );
}
-/* plain antialiased filled box */
-#if 0
-void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad)
-{
- float color[4];
-
- if(roundboxtype & UI_RB_ALPHA) {
- glGetFloatv(GL_CURRENT_COLOR, color);
- color[3]= 0.5;
- glColor4fv(color);
- glEnable( GL_BLEND );
- }
-
- /* solid part */
- gl_round_box(GL_POLYGON, minx, miny, maxx, maxy, rad);
-
- /* set antialias line */
- if (UI_GetThemeValue(TH_BUT_DRAWTYPE) != TH_MINIMAL) {
- glEnable( GL_LINE_SMOOTH );
- glEnable( GL_BLEND );
- }
-
- gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
-
- glDisable( GL_BLEND );
- glDisable( GL_LINE_SMOOTH );
-}
-#endif
-
-
/* ************** safe rasterpos for pixmap alignment with pixels ************* */
void ui_rasterpos_safe(float x, float y, float aspect)
@@ -652,7 +630,7 @@ void uiEmboss(float x1, float y1, float x2, float y2, int sel)
/* icons have been standardized... and this call draws in untransformed coordinates */
#define ICON_HEIGHT 16.0f
-static void ui_draw_icon(uiBut *but, BIFIconID icon, int blend)
+void ui_draw_icon(uiBut *but, BIFIconID icon, int blend)
{
float xs=0, ys=0, aspect, height;
@@ -918,6 +896,10 @@ static void round_button_shaded(int type, int colorid, float asp, float x1, floa
int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
float shadefac;
+ /* emboss */
+ glColor4f(1.0f, 1.0f, 1.0f, 0.08f);
+ uiRoundRectFakeAA(x1+1, y1-1, x2, y2-1, rad, asp);
+
/* colour shading */
if (flag & UI_SELECT) {
shadefac = -0.05;
@@ -946,25 +928,26 @@ static void round_button_flat(int colorid, float asp, float x1, float y1, float
{
int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
+ /* emboss */
+ //glColor4f(1.0f, 1.0f, 1.0f, 0.08f);
+ //uiRoundRectFakeAA(x1+1, y1-1, x2, y2-1, rad, asp);
+
/* colour shading */
if(flag & UI_SELECT) {
- if (flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -20);
+ if (flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -30);
else UI_ThemeColorShade(colorid, -45);
}
else {
if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, 35);
else UI_ThemeColorShade(colorid, 25);
}
- /* end colour shading */
/* the solid base */
gl_round_box(GL_POLYGON, x1, y1, x2, y2, rad);
/* outline */
UI_ThemeColorBlendShadeAlpha(TH_BUT_OUTLINE, TH_BACK, 0.1, -30, alpha_offs);
-
uiRoundRectFakeAA(x1, y1, x2, y2, rad, asp);
- /* end outline */
}
static void ui_checkmark_box(int colorid, float x1, float y1, float x2, float y2)
@@ -1214,11 +1197,14 @@ static void ui_roundshaded_button(int type, int colorid, float asp, float x1, fl
static void ui_roundshaded_flat(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
{
- float rad, maxrad=10.0;
+ float rad, maxrad;
int align= (flag & UI_BUT_ALIGN);
int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
/* rounded corners */
+ if (type == TEX) maxrad = 5.0;
+ else maxrad= 10.0;
+
rad= (y2-y1)/2.0;
if (rad>(x2-x1)/2) rad = (x2-x1)/2;
if (maxrad) {
@@ -1658,83 +1644,6 @@ static void ui_default_flat(int type, int colorid, float asp, float x1, float y1
}
}
-#if 0
-static void ui_default_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
-{
- float ymid, yc;
-
- /* the slider background line */
- ymid= (y1+y2)/2.0;
- //yc= 2.5*aspect; // height of center line
- yc = 2.3; // height of center line
-
- if(flag & UI_SELECT)
- UI_ThemeColorShade(TH_BUT_NUM, -5);
- else {
- if(flag & UI_ACTIVE)
- UI_ThemeColorShade(TH_BUT_NUM, +35);
- else
- UI_ThemeColorShade(TH_BUT_NUM, +25);
- }
-
- glRectf(x1, ymid-yc, x2, ymid+yc);
-
- /* top inner bevel */
- if(flag & UI_SELECT) UI_ThemeColorShade(TH_BUT_NUM, -40);
- else UI_ThemeColorShade(TH_BUT_NUM, -5);
- fdrawline(x1+1, ymid+yc, x2, ymid+yc);
-
- /* bottom inner bevel */
- if(flag & UI_SELECT) UI_ThemeColorShade(TH_BUT_NUM, +15);
- else UI_ThemeColorShade(TH_BUT_NUM, +45);
- fdrawline(x1+1, ymid-yc, x2, ymid-yc);
-
-
- /* the movable slider */
- if(flag & UI_SELECT) UI_ThemeColorShade(TH_BUT_NUM, +80);
- else UI_ThemeColorShade(TH_BUT_NUM, -45);
-
- glShadeModel(GL_SMOOTH);
- glBegin(GL_QUADS);
-
- UI_ThemeColorShade(TH_BUT_NUM, -45);
-
- glVertex2f(x1, y1+2.5);
- glVertex2f(x1+fac, y1+2.5);
-
- UI_ThemeColor(TH_BUT_NUM);
-
- glVertex2f(x1+fac, y2-2.5);
- glVertex2f(x1, y2-2.5);
-
- glEnd();
-
-
- /* slider handle center */
- glShadeModel(GL_SMOOTH);
- glBegin(GL_QUADS);
-
- UI_ThemeColor(TH_BUT_NUM);
- glVertex2f(x1+fac-3, y1+2);
- glVertex2f(x1+fac, y1+4);
- UI_ThemeColorShade(TH_BUT_NUM, +80);
- glVertex2f(x1+fac, y2-2);
- glVertex2f(x1+fac-3, y2-2);
-
- glEnd();
-
- /* slider handle left bevel */
- UI_ThemeColorShade(TH_BUT_NUM, +70);
- fdrawline(x1+fac-3, y2-2, x1+fac-3, y1+2);
-
- /* slider handle right bevel */
- UI_ThemeColorShade(TH_BUT_NUM, -35);
- fdrawline(x1+fac, y2-2, x1+fac, y1+2);
-
- glShadeModel(GL_FLAT);
-}
-#endif
-
/* default theme callback */
static void ui_draw_default(int type, int colorid, float aspect, float x1, float y1, float x2, float y2, int flag)
{
@@ -2078,27 +1987,74 @@ static void ui_draw_minimal(int type, int colorid, float asp, float x1, float y1
/* fac is the slider handle position between x1 and x2 */
static void ui_draw_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
{
- float ymid, yc;
-
- /* the slider background line */
- ymid= (y1+y2)/2.0;
- yc= 1.7*aspect;
-
- if(flag & UI_ACTIVE)
- UI_ThemeColorShade(colorid, -50);
- else
- UI_ThemeColorShade(colorid, -40);
+ int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
+ float maxrad= 10.0;
+ float rad;
+ int origround, round = uiGetRoundBox();
+
+ rad= (y2-y1)/2.0;
+ if (rad>(x2-x1)/2) rad = (x2-x1)/2;
+ if (rad > maxrad) rad = maxrad;
- /* left part */
- glRectf(x1, ymid-2.0*yc, x1+fac, ymid+2.0*yc);
- /* right part */
- glRectf(x1+fac, ymid-yc, x2, ymid+yc);
+ if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -75);
+ else UI_ThemeColorShade(colorid, -45);
- /* the movable slider */
+ origround = round;
+ round &= ~(2|4);
+ uiSetRoundBox(round);
+
+ if (fac < rad) {
+ /* if slider end is in the left end cap */
+ float ofsy;
+ float start_rad;
+
+ start_rad = fac;
+ ofsy = (origround!=0) ? ((rad - fac) * 0.5) : 0.f; /* shrink in Y if rounded but */
+
+ gl_round_box(GL_POLYGON, x1, y1+ofsy, x1+fac, y2-ofsy, start_rad);
+
+ } else if ( (fac >= rad) && (x1+fac < x2 - rad) ) {
+ /* if the slider is in the middle */
+
+ gl_round_box(GL_POLYGON, x1, y1, x1+fac, y2, rad);
+
+ } else if (x1+fac >= x2-rad) {
+ /* if the slider is in the right end cap */
+ float extx, ofsy;
+ float end_rad;
+
+ /* draw the full slider area at 100% */
+ uiSetRoundBox(origround);
+ gl_round_box(GL_POLYGON, x1, y1, x2, y2, rad);
+
+ /* don't draw anything else if the slider is completely full */
+ if (x2 - (x1+fac) < 0.05f)
+ return;
+
+ /* tricky to trim off right end curve by drawing over it */
+ extx = ((x1 + fac) - (x2 - rad)) * aspect; /* width of extension bit */
+ end_rad = rad - extx - 1.0;
+ ofsy = (origround!=0) ? (extx * 0.4) : 0.f; /* shrink in Y if rounded but */
+
+ if (end_rad > 1.0) {
+
+ if(flag & UI_SELECT) UI_ThemeColorShade(colorid, -20);
+ else UI_ThemeColorShade(colorid, -0);
+
+ round = origround;
+ round &= ~(1|8);
+ uiSetRoundBox(round);
+ gl_round_box(GL_POLYGON, x1+fac-1.0, y1+ofsy, x2-1.0, y2-ofsy, end_rad);
+ }
+
+ /* trace over outline again, to cover up inaccuracies */
+ UI_ThemeColorBlendShadeAlpha(TH_BUT_OUTLINE, TH_BACK, 0.1, -30, alpha_offs);
+ uiSetRoundBox(origround);
+ uiRoundRectFakeAA(x1, y1, x2, y2, rad, aspect);
+ }
+
+
- UI_ThemeColorShade(colorid, +70);
- glRectf(x1+fac-aspect, ymid-2.0*yc, x1+fac+aspect, ymid+2.0*yc);
-
}
/* ************** STANDARD MENU DRAWING FUNCTION ************* */
@@ -2246,17 +2202,79 @@ static void ui_draw_pulldown_round(int type, int colorid, float asp, float x1, f
/* ************** TEXT AND ICON DRAWING FUNCTIONS ************* */
+#define BUT_TEXT_NORMAL 0
+#define BUT_TEXT_SUNKEN 1
-
-/* draws text and icons for buttons */
-static void ui_draw_text_icon(uiBut *but)
+void ui_draw_text(uiBut *but, float x, float y, int sunken)
{
- float x;
+ int alpha_offs= (but->flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
+ int transopts;
int len;
+ float ypos = (sunken==BUT_TEXT_SUNKEN) ? (y-1) : y;
char *cpoin;
+
+ if(but->type==LABEL && but->hardmin!=0.0) {
+ UI_ThemeColor(TH_BUT_TEXT_HI);
+ }
+ else if(but->dt==UI_EMBOSSP) {
+ if((but->flag & UI_ACTIVE) && but->type!=LABEL) { // LABEL = title in pulldowns
+ UI_ThemeColorShadeAlpha(TH_MENU_TEXT_HI, 0, alpha_offs);
+ } else {
+ UI_ThemeColorShadeAlpha(TH_MENU_TEXT, 0, alpha_offs);
+ }
+ }
+ else {
+ if(but->flag & UI_SELECT) {
+ UI_ThemeColorShadeAlpha(TH_BUT_TEXT_HI, 0, alpha_offs);
+ } else {
+ UI_ThemeColorShadeAlpha(TH_BUT_TEXT, 0, alpha_offs);
+ }
+ }
+
+ if (sunken == BUT_TEXT_SUNKEN) {
+ float curcol[4];
+
+ glGetFloatv(GL_CURRENT_COLOR, curcol); /* returns four components: r,g,b,a */
+
+ /* only draw embossed text if the text color is darker than 0.5 mid-grey */
+ if ((curcol[0] + curcol[1] + curcol[2]) * 0.3f < 0.5f)
+ glColor4f(0.6f, 0.6f, 0.6f, 0.3f);
+ else
+ return;
+ }
+
+ ui_rasterpos_safe(x, ypos, but->aspect);
+ if(but->type==IDPOIN) transopts= 0; // no translation, of course!
+ else transopts= ui_translate_buttons();
+
+ /* cut string in 2 parts */
+ cpoin= strchr(but->drawstr, '|');
+ if(cpoin) *cpoin= 0;
+
+#ifdef INTERNATIONAL
+ if (but->type == FTPREVIEW)
+ FTF_DrawNewFontString (but->drawstr+but->ofs, FTF_INPUT_UTF8);
+ else
+ UI_DrawString(but->font, but->drawstr+but->ofs, transopts);
+#else
+ UI_DrawString(but->font, but->drawstr+but->ofs, transopts);
+#endif
+
+ /* part text right aligned */
+ if(cpoin) {
+ len= UI_GetStringWidth(but->font, cpoin+1, ui_translate_buttons());
+ ui_rasterpos_safe( but->x2 - len*but->aspect-3, ypos, but->aspect);
+ UI_DrawString(but->font, cpoin+1, ui_translate_buttons());
+ *cpoin= '|';
+ }
+}
+
+/* draws text and icons for buttons */
+void ui_draw_text_icon(uiBut *but)
+{
+ float x, y;
short t, pos, ch;
short selsta_tmp, selend_tmp, selsta_draw, selwidth_draw;
- int alpha_offs= (but->flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
/* check for button text label */
if (but->type == ICONTEXTROW) {
@@ -2322,13 +2340,8 @@ static void ui_draw_text_icon(uiBut *but)
}
if(but->drawstr[0]!=0) {
- int transopts;
int tog3= 0;
- // cut string in 2 parts
- cpoin= strchr(but->drawstr, '|');
- if(cpoin) *cpoin= 0;
-
/* If there's an icon too (made with uiDefIconTextBut) then draw the icon
and offset the text label to accomodate it */
@@ -2364,46 +2377,14 @@ static void ui_draw_text_icon(uiBut *but)
if (tog3) glColor3ub(255, 255, 0);
}
- /* text color, with pulldown item exception */
- if(tog3); // color already set
- else if(but->dt==UI_EMBOSSP) {
- if((but->flag & UI_ACTIVE) && but->type!=LABEL) { // LABEL = title in pulldowns
- UI_ThemeColorShadeAlpha(TH_MENU_TEXT_HI, 0, alpha_offs);
- } else {
- UI_ThemeColorShadeAlpha(TH_MENU_TEXT, 0, alpha_offs);
- }
- }
- else {
- if(but->flag & UI_SELECT) {
- UI_ThemeColorShadeAlpha(TH_BUT_TEXT_HI, 0, alpha_offs);
- } else {
- UI_ThemeColorShadeAlpha(TH_BUT_TEXT, 0, alpha_offs);
- }
- }
-
- /* LABEL button exception */
- if(but->type==LABEL && but->min!=0.0) UI_ThemeColor(TH_BUT_TEXT_HI);
-
- ui_rasterpos_safe(x, (but->y1+but->y2- 9.0)/2.0, but->aspect);
- if(but->type==IDPOIN) transopts= 0; // no translation, of course!
- else transopts= ui_translate_buttons();
+ /* position and draw */
+ y = (but->y1+but->y2- 9.0)/2.0;
+
+ if (ELEM(but->type, LABEL, PULLDOWN) && !(but->flag & UI_ACTIVE))
+ ui_draw_text(but, x, y, BUT_TEXT_SUNKEN);
+
+ ui_draw_text(but, x, y, BUT_TEXT_NORMAL);
- #ifdef INTERNATIONAL
- if (but->type == FTPREVIEW)
- FTF_DrawNewFontString (but->drawstr+but->ofs, FTF_INPUT_UTF8);
- else
- UI_DrawString(but->font, but->drawstr+but->ofs, transopts);
- #else
- UI_DrawString(but->font, but->drawstr+but->ofs, transopts);
- #endif
-
- /* part text right aligned */
- if(cpoin) {
- len= UI_GetStringWidth(but->font, cpoin+1, ui_translate_buttons());
- ui_rasterpos_safe( but->x2 - len*but->aspect-3, (but->y1+but->y2- 9.0)/2.0, but->aspect);
- UI_DrawString(but->font, cpoin+1, ui_translate_buttons());
- *cpoin= '|';
- }
}
/* if there's no text label, then check to see if there's an icon only and draw it */
else if( but->flag & UI_HAS_ICON ) {
@@ -3141,7 +3122,7 @@ static void ui_draw_roundbox(uiBut *but)
UI_ThemeColorShadeAlpha(but->themecol, but->a2, but->a2);
uiSetRoundBox(but->a1);
- gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, but->min);
+ gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, but->hardmin);
glDisable(GL_BLEND);
}
@@ -3261,30 +3242,31 @@ void ui_draw_but(ARegion *ar, uiBut *but)
int type;
if(but==NULL) return;
+
+ if(but->block->flag & UI_BLOCK_2_50) {
+ extern void ui_draw_but_new(ARegion *ar, uiBut *but); // XXX
+
+ ui_draw_but_new(ar, but);
+ return;
+ }
- /* XXX 2.50 no frontbuffer drawing allowed */
-#if 0
- /* signal for frontbuf flush buttons and menus, not when normal drawing */
- if(but->block->in_use) ui_block_set_flush(but->block, but);
-#endif
-
switch (but->type) {
case NUMSLI:
case HSVSLI:
type= (but->editstr)? TEX: but->type;
but->embossfunc(type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
- ui_draw_text_icon(but);
-
- x1= (but->x1+but->x2)/2;
- x2= but->x2 - 5.0*but->aspect;
- y1= but->y1 + 2.0*but->aspect;
- y2= but->y2 - 2.0*but->aspect;
+
+ x1= but->x1;
+ x2= but->x2;
+ y1= but->y1;
+ y2= but->y2;
value= ui_get_but_val(but);
- fac= (value-but->min)*(x2-x1)/(but->max - but->min);
+ fac= (value-but->softmin)*(x2-x1)/(but->softmax - but->softmin);
but->sliderfunc(but->themecol, fac, but->aspect, x1, y1, x2, y2, but->flag);
+ ui_draw_text_icon(but);
break;
case SEPR:
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 588615675cf..4220d9c2781 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -101,7 +101,7 @@ typedef struct uiHandleButtonData {
/* edited value */
char *str, *origstr;
- double value, origvalue;
+ double value, origvalue, startvalue;
float vec[3], origvec[3];
int togdual, togonly;
ColorBand *coba;
@@ -300,7 +300,7 @@ static void ui_apply_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data)
static void ui_apply_but_BUTM(bContext *C, uiBut *but, uiHandleButtonData *data)
{
- ui_set_but_val(but, but->min);
+ ui_set_but_val(but, but->hardmin);
ui_apply_but_func(C, but);
data->retval= but->retval;
@@ -381,7 +381,7 @@ static void ui_apply_but_TOG(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data)
{
- ui_set_but_val(but, but->max);
+ ui_set_but_val(but, but->hardmax);
ui_apply_but_func(C, but);
data->retval= but->retval;
@@ -426,8 +426,10 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data)
if(!ui_is_but_float(but)) data->value= (int)data->value;
if(but->type==NUMABS) data->value= fabs(data->value);
- if(data->value<but->min) data->value= but->min;
- if(data->value>but->max) data->value= but->max;
+
+ /* not that we use hard limits here */
+ if(data->value<but->hardmin) data->value= but->hardmin;
+ if(data->value>but->hardmax) data->value= but->hardmax;
}
ui_set_but_val(but, data->value);
@@ -1138,7 +1140,7 @@ static void ui_textedit_begin(uiBut *but, uiHandleButtonData *data)
/* retrieve string */
if(but->type == TEX) {
- data->maxlen= but->max;
+ data->maxlen= but->hardmax;
data->str= MEM_callocN(sizeof(char)*(data->maxlen+1), "textedit str");
ui_get_but_string(but, data->str, data->maxlen+1);
@@ -1389,18 +1391,9 @@ static void ui_do_but_textedit_select(bContext *C, uiBlock *block, uiBut *but, u
/* ************* number editing for various types ************* */
-static void but_clamped_range(uiBut *but, float *butmin, float *butmax, float *butrange)
-{
- /* clamp button range to something reasonable in case
- * we get -inf/inf from RNA properties */
- *butmin= MAX2(but->min, -1e4f);
- *butmax= MIN2(but->max, 1e4f);
- *butrange= *butmax - *butmin;
-}
-
static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
{
- float butrange, butmin, butmax;
+ float softrange, softmin, softmax;
if(but->type == BUT_CURVE) {
data->cumap= (CurveMapping*)but->poin;
@@ -1416,13 +1409,16 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
but->editvec= data->vec;
}
else {
- data->origvalue= ui_get_but_val(but);
+ data->startvalue= ui_get_but_val(but);
+ data->origvalue= data->startvalue;
data->value= data->origvalue;
but->editval= &data->value;
- but_clamped_range(but, &butmin, &butmax, &butrange);
+ softmin= but->softmin;
+ softmax= but->softmax;
+ softrange= softmax - softmin;
- data->dragfstart= (butrange == 0.0)? 0.0f: (data->value - butmin)/butrange;
+ data->dragfstart= (softrange == 0.0)? 0.0: (data->value - softmin)/softrange;
data->dragf= data->dragfstart;
}
@@ -1629,7 +1625,7 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, wmE
static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx)
{
- float deler, tempf, butmin, butmax, butrange;
+ float deler, tempf, softmin, softmax, softrange;
int lvalue, temp, changed= 0;
if(mx == data->draglastx)
@@ -1645,19 +1641,21 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
data->dragstartx= mx; /* ignore mouse movement within drag-lock */
}
- but_clamped_range(but, &butmin, &butmax, &butrange);
+ softmin= but->softmin;
+ softmax= but->softmax;
+ softrange= softmax - softmin;
deler= 500;
if(!ui_is_but_float(but)) {
- if((butrange)<100) deler= 200.0;
- if((butrange)<25) deler= 50.0;
+ if((softrange)<100) deler= 200.0;
+ if((softrange)<25) deler= 50.0;
}
deler /= fac;
- if(ui_is_but_float(but) && butrange > 11) {
+ if(ui_is_but_float(but) && softrange > 11) {
/* non linear change in mouse input- good for high precicsion */
data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.002);
- } else if (!ui_is_but_float(but) && butrange > 129) { /* only scale large int buttons */
+ } else if (!ui_is_but_float(but) && softrange > 129) { /* only scale large int buttons */
/* non linear change in mouse input- good for high precicsionm ints need less fine tuning */
data->dragf+= (((float)(mx-data->draglastx))/deler) * (fabs(data->dragstartx-mx)*0.004);
} else {
@@ -1668,51 +1666,50 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
if(data->dragf>1.0) data->dragf= 1.0;
if(data->dragf<0.0) data->dragf= 0.0;
data->draglastx= mx;
- tempf= (butmin + data->dragf*butrange);
+ tempf= (softmin + data->dragf*softrange);
if(!ui_is_but_float(but)) {
-
temp= floor(tempf+.5);
- if(tempf==but->min || tempf==but->max);
+ if(tempf==softmin || tempf==softmax);
else if(snap) {
if(snap == 2) temp= 100*(temp/100);
else temp= 10*(temp/10);
}
- if( temp>=but->min && temp<=but->max) {
- lvalue= (int)data->value;
+
+ CLAMP(temp, softmin, softmax);
+ lvalue= (int)data->value;
- if(temp != lvalue ) {
- data->dragchange= 1;
- data->value= (double)temp;
- changed= 1;
- }
+ if(temp != lvalue) {
+ data->dragchange= 1;
+ data->value= (double)temp;
+ changed= 1;
}
-
}
else {
temp= 0;
+
if(snap) {
if(snap == 2) {
- if(tempf==but->min || tempf==but->max);
- else if(butrange < 2.10) tempf= 0.01*floor(100.0*tempf);
- else if(butrange < 21.0) tempf= 0.1*floor(10.0*tempf);
+ if(tempf==softmin || tempf==softmax);
+ else if(softrange < 2.10) tempf= 0.01*floor(100.0*tempf);
+ else if(softrange < 21.0) tempf= 0.1*floor(10.0*tempf);
else tempf= floor(tempf);
}
else {
- if(tempf==but->min || tempf==but->max);
- else if(butrange < 2.10) tempf= 0.1*floor(10*tempf);
- else if(butrange < 21.0) tempf= floor(tempf);
+ if(tempf==softmin || tempf==softmax);
+ else if(softrange < 2.10) tempf= 0.1*floor(10*tempf);
+ else if(softrange < 21.0) tempf= floor(tempf);
else tempf= 10.0*floor(tempf/10.0);
}
}
- if( tempf>=but->min && tempf<=but->max) {
- if(tempf != data->value) {
- data->dragchange= 1;
- data->value= tempf;
- changed= 1;
- }
+ CLAMP(tempf, softmin, softmax);
+
+ if(tempf != data->value) {
+ data->dragchange= 1;
+ data->value= tempf;
+ changed= 1;
}
}
@@ -1786,15 +1783,18 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
if(click) {
/* we can click on the side arrows to increment/decrement,
* or click inside to edit the value directly */
- float tempf;
+ float tempf, softmin, softmax;
int temp;
+ softmin= but->softmin;
+ softmax= but->softmax;
+
if(!ui_is_but_float(but)) {
if(mx < (but->x1 + (but->x2 - but->x1)/3 - 3)) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
temp= (int)data->value - 1;
- if(temp>=but->min && temp<=but->max)
+ if(temp>=softmin && temp<=softmax)
data->value= (double)temp;
else
data->cancel= 1;
@@ -1805,7 +1805,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
temp= (int)data->value + 1;
- if(temp>=but->min && temp<=but->max)
+ if(temp>=softmin && temp<=softmax)
data->value= (double)temp;
else
data->cancel= 1;
@@ -1820,7 +1820,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
tempf= data->value - 0.01*but->a1;
- if (tempf < but->min) tempf = but->min;
+ if (tempf < softmin) tempf = softmin;
data->value= tempf;
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -1829,7 +1829,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
tempf= data->value + 0.01*but->a1;
- if (tempf < but->min) tempf = but->min;
+ if (tempf > softmax) tempf = softmax;
data->value= tempf;
button_activate_state(C, but, BUTTON_STATE_EXIT);
@@ -1846,12 +1846,14 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, int ctrl, int mx)
{
- float deler, f, tempf, butmin, butmax, butrange;
+ float deler, f, tempf, softmin, softmax, softrange;
int temp, lvalue, changed= 0;
- but_clamped_range(but, &butmin, &butmax, &butrange);
+ softmin= but->softmin;
+ softmax= but->softmax;
+ softrange= softmax - softmin;
- if(but->type==NUMSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
+ if(but->type==NUMSLI) deler= ((but->x2-but->x1) - 5.0*but->aspect);
else if(but->type==HSVSLI) deler= ((but->x2-but->x1)/2 - 5.0*but->aspect);
else deler= (but->x2-but->x1- 5.0*but->aspect);
@@ -1861,22 +1863,22 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, i
f= (f-data->dragfstart)/10.0 + data->dragfstart;
CLAMP(f, 0.0, 1.0);
- tempf= butmin + f*butrange;
+ tempf= softmin + f*softrange;
temp= floor(tempf+.5);
if(ctrl) {
- if(tempf==but->min || tempf==but->max);
+ if(tempf==softmin || tempf==softmax);
else if(ui_is_but_float(but)) {
if(shift) {
- if(tempf==but->min || tempf==but->max);
- else if(but->max-but->min < 2.10) tempf= 0.01*floor(100.0*tempf);
- else if(but->max-but->min < 21.0) tempf= 0.1*floor(10.0*tempf);
+ if(tempf==softmin || tempf==softmax);
+ else if(softmax-softmin < 2.10) tempf= 0.01*floor(100.0*tempf);
+ else if(softmax-softmin < 21.0) tempf= 0.1*floor(10.0*tempf);
else tempf= floor(tempf);
}
else {
- if(but->max-but->min < 2.10) tempf= 0.1*floor(10*tempf);
- else if(but->max-but->min < 21.0) tempf= floor(tempf);
+ if(softmax-softmin < 2.10) tempf= 0.1*floor(10*tempf);
+ else if(softmax-softmin < 21.0) tempf= floor(tempf);
else tempf= 10.0*floor(tempf/10.0);
}
}
@@ -1889,6 +1891,8 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, i
if(!ui_is_but_float(but)) {
lvalue= floor(data->value+0.5);
+ CLAMP(temp, softmin, softmax);
+
if(temp != lvalue) {
data->value= temp;
data->dragchange= 1;
@@ -1896,6 +1900,8 @@ static int ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, int shift, i
}
}
else {
+ CLAMP(tempf, softmin, softmax);
+
if(tempf != data->value) {
data->value= tempf;
data->dragchange= 1;
@@ -1916,21 +1922,19 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_window_to_block(data->region, block, &mx, &my);
if(data->state == BUTTON_STATE_HIGHLIGHT) {
- if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val==KM_PRESS) {
- /* start either dragging as slider, or editing as text */
- if(mx>= -6+(but->x1+but->x2)/2) {
- if(event->type == LEFTMOUSE) {
- data->dragstartx= mx;
- data->draglastx= mx;
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
- }
- else
- click= 1;
- }
- else
+ if(event->val==KM_PRESS) {
+ if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->shift) {
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
-
- retval= WM_UI_HANDLER_BREAK;
+ retval= WM_UI_HANDLER_BREAK;
+ }
+ else if(event->type == LEFTMOUSE) {
+ data->dragstartx= mx;
+ data->draglastx= mx;
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+ retval= WM_UI_HANDLER_BREAK;
+ }
+ else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS)
+ click= 1;
}
}
else if(data->state == BUTTON_STATE_NUM_EDITING) {
@@ -1956,45 +1960,52 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
}
if(click) {
- float f, h;
- float tempf, butmin, butmax, butrange;
- int temp;
-
- button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
-
- but_clamped_range(but, &butmin, &butmax, &butrange);
-
- tempf= data->value;
- temp= (int)data->value;
-
- h= but->y2-but->y1;
-
- if(but->type==SLI) f= (float)(mx-but->x1)/(but->x2-but->x1-h);
- else f= (float)(mx- (but->x1+but->x2)/2)/((but->x2-but->x1)/2 - h);
-
- f= butmin + f*butrange;
-
- if(!ui_is_but_float(but)) {
- if(f<temp) temp--;
- else temp++;
-
- if(temp>=but->min && temp<=but->max)
- data->value= temp;
- else
- data->cancel= 1;
- }
+ if (event->ctrl) {
+ /* nudge slider to the left or right */
+ float f, tempf, softmin, softmax, softrange;
+ int temp;
+
+ button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
+
+ softmin= but->softmin;
+ softmax= but->softmax;
+ softrange= softmax - softmin;
+
+ tempf= data->value;
+ temp= (int)data->value;
+
+ if(but->type==SLI) f= (float)(mx-but->x1)/(but->x2-but->x1);
+ else f= (float)(mx- but->x1)/(but->x2-but->x1);
+
+ f= softmin + f*softrange;
+
+ if(!ui_is_but_float(but)) {
+ if(f<temp) temp--;
+ else temp++;
+
+ if(temp>=softmin && temp<=softmax)
+ data->value= temp;
+ else
+ data->cancel= 1;
+ }
+ else {
+ if(f<tempf) tempf-=.01;
+ else tempf+=.01;
+
+ if(tempf>=softmin && tempf<=softmax)
+ data->value= tempf;
+ else
+ data->cancel= 1;
+ }
+
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ retval= WM_UI_HANDLER_BREAK;
+ }
else {
- if(f<tempf) tempf-=.01;
- else tempf+=.01;
-
- if(tempf>=but->min && tempf<=but->max)
- data->value= tempf;
- else
- data->cancel= 1;
+ /* edit the value directly */
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ retval= WM_UI_HANDLER_BREAK;
}
-
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- retval= WM_UI_HANDLER_BREAK;
}
return retval;
@@ -2638,16 +2649,17 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
/* verify if we can edit this button */
if(ELEM(event->type, LEFTMOUSE, RETKEY)) {
+ /* this should become disabled button .. */
if(but->lock) {
if(but->lockstr) {
- BKE_report(CTX_reports(C), RPT_WARNING, but->lockstr);
+ BKE_report(NULL, RPT_WARNING, but->lockstr);
button_activate_state(C, but, BUTTON_STATE_EXIT);
return WM_UI_HANDLER_BREAK;
}
}
else if(but->pointype && but->poin==0) {
/* there's a pointer needed */
- BKE_reportf(CTX_reports(C), RPT_WARNING, "DoButton pointer error: %s", but->str);
+ BKE_reportf(NULL, RPT_WARNING, "DoButton pointer error: %s", but->str);
button_activate_state(C, but, BUTTON_STATE_EXIT);
return WM_UI_HANDLER_BREAK;
}
@@ -2957,6 +2969,8 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
data->state= state;
+ ui_check_but(but);
+
/* redraw */
ED_region_tag_redraw(data->region);
}
@@ -3046,6 +3060,7 @@ static void button_activate_exit(bContext *C, uiHandleButtonData *data, uiBut *b
MEM_freeN(but->active);
but->active= NULL;
but->flag &= ~(UI_ACTIVE|UI_SELECT);
+ ui_check_but(but);
/* adds empty mousemove in queue for re-init handler, in case mouse is
* still over a button. we cannot just check for this ourselfs because
@@ -3274,62 +3289,63 @@ static void ui_handle_button_closed_submenu(bContext *C, wmEvent *event, uiBut *
* - only for 1 second
*/
-static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, int mx, int my)
+static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, int mx, int my, int force)
{
- if(!menu->dotowards) {
+ if(!menu->dotowards || force) {
menu->dotowards= 1;
menu->towardsx= mx;
menu->towardsy= my;
- menu->towardstime= PIL_check_seconds_timer();
+
+ if(force)
+ menu->towardstime= DBL_MAX; /* unlimited time */
+ else
+ menu->towardstime= PIL_check_seconds_timer();
}
}
static int ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, int mx, int my)
{
- int fac, dx, dy, domx, domy;
+ float p1[2], p2[2], p3[2], p4[2], oldp[2], newp[2];
+ int closer;
if(!menu->dotowards) return 0;
if((block->direction & UI_TOP) || (block->direction & UI_DOWN)) {
menu->dotowards= 0;
return menu->dotowards;
}
+
+ /* verify that we are moving towards one of the edges of the
+ * menu block, in other words, in the triangle formed by the
+ * initial mouse location and two edge points. */
+ p1[0]= block->minx-20;
+ p1[1]= block->miny-20;
+
+ p2[0]= block->maxx+20;
+ p2[1]= block->miny-20;
- /* calculate dominant direction */
- domx= (-menu->towardsx + (block->maxx+block->minx)/2);
- domy= (-menu->towardsy + (block->maxy+block->miny)/2);
+ p3[0]= block->maxx+20;
+ p3[1]= block->maxy+20;
- /* we need some accuracy */
- if(abs(domx) < 4) {
- menu->dotowards= 0;
+ p4[0]= block->minx-20;
+ p4[1]= block->maxy+20;
+
+ oldp[0]= menu->towardsx;
+ oldp[1]= menu->towardsy;
+
+ newp[0]= mx;
+ newp[1]= my;
+
+ if(Vec2Lenf(oldp, newp) < 4.0f)
return menu->dotowards;
- }
-
- /* check direction */
- dx= mx - menu->towardsx;
- dy= my - menu->towardsy;
-
- /* threshold */
- if(abs(dx)+abs(dy) > 4) {
- /* menu to right */
- if(domx>0) {
- fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->maxy+20)) +
- (my - menu->towardsy)*(-menu->towardsx + (int)block->minx);
- if(fac>0) menu->dotowards= 0;
-
- fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->miny-20)) +
- (my - menu->towardsy)*(-menu->towardsx + (int)block->minx);
- if(fac<0) menu->dotowards= 0;
- }
- else {
- fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->maxy+20)) +
- (my - menu->towardsy)*(-menu->towardsx + (int)block->maxx);
- if(fac<0) menu->dotowards= 0;
-
- fac= (mx - menu->towardsx)*( menu->towardsy - (int)(block->miny-20)) +
- (my - menu->towardsy)*(-menu->towardsx + (int)block->maxx);
- if(fac>0) menu->dotowards= 0;
- }
- }
+
+ closer= 0;
+ closer |= IsectPT2Df(newp, oldp, p1, p2);
+ closer |= IsectPT2Df(newp, oldp, p2, p3);
+ closer |= IsectPT2Df(newp, oldp, p3, p4);
+ closer |= IsectPT2Df(newp, oldp, p4, p1);
+
+ if(!closer)
+ menu->dotowards= 0;
/* 1 second timer */
if(PIL_check_seconds_timer() - menu->towardstime > BUTTON_MOUSE_TOWARDS_THRESH)
@@ -3361,10 +3377,16 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu,
if(block->miny <= my && block->maxy >= my)
inside= 1;
- if(topmenu && event->type != TIMER) {
+ if((but=ui_but_find_activated(ar)) && button_modal_state(but->active->state)) {
+ /* if a button is activated modal, always reset the start mouse
+ * position of the towards mechanism to avoid loosing focus,
+ * and don't handle events */
+ ui_mouse_motion_towards_init(menu, mx, my, 1);
+ }
+ else if(event->type != TIMER) {
/* for ui_mouse_motion_towards_block */
if(event->type == MOUSEMOVE)
- ui_mouse_motion_towards_init(menu, mx, my);
+ ui_mouse_motion_towards_init(menu, mx, my, 0);
switch(event->type) {
/* closing sublevels of pulldowns */
@@ -3387,7 +3409,7 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu,
else but= ui_but_first(block);
}
- if(but && but->type==BLOCK)
+ if(but && ELEM(but->type, BLOCK, HMENU))
ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE_OPEN);
}
@@ -3579,6 +3601,7 @@ static int ui_handle_menu_closed_submenu(bContext *C, wmEvent *event, uiPopupBlo
uiBlock *block;
uiHandleButtonData *data;
uiPopupBlockHandle *submenu;
+ int mx, my;
ar= menu->region;
block= ar->uiblocks.first;
@@ -3602,6 +3625,13 @@ static int ui_handle_menu_closed_submenu(bContext *C, wmEvent *event, uiPopupBlo
ui_handle_button_closed_submenu(C, event, but);
}
+ /* for cases where close does not cascade, allow the user to
+ * move the mouse back towards the menu without closing */
+ mx= event->x;
+ my= event->y;
+ ui_window_to_block(ar, block, &mx, &my);
+ ui_mouse_motion_towards_init(menu, mx, my, 1);
+
if(menu->menuretval)
return WM_UI_HANDLER_CONTINUE;
else
@@ -3701,7 +3731,10 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata)
/* here we handle buttons at the window level, modal, for example
* while number sliding, text editing, or when a menu block is open */
- ar= CTX_wm_region(C);
+ ar= CTX_wm_menu(C);
+ if(!ar)
+ ar= CTX_wm_region(C);
+
but= ui_but_find_activated(ar);
if(but) {
@@ -3792,8 +3825,8 @@ void UI_add_region_handlers(ListBase *handlers)
WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region, NULL);
}
-void UI_add_popup_handlers(ListBase *handlers, uiPopupBlockHandle *menu)
+void UI_add_popup_handlers(bContext *C, ListBase *handlers, uiPopupBlockHandle *menu)
{
- WM_event_add_ui_handler(NULL, handlers, ui_handler_popup, ui_handler_remove_popup, menu);
+ WM_event_add_ui_handler(C, handlers, ui_handler_popup, ui_handler_remove_popup, menu);
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 8e1e8fad4ce..7f26f4fa89e 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -55,7 +55,7 @@ struct wmWindow;
#define UI_MOUSE_OVER 2
#define UI_ACTIVE 4
#define UI_HAS_ICON 8
-/* warn: rest of uiBut->flag in BIF_interface.c */
+/* warn: rest of uiBut->flag in UI_interface.h */
/* internal panel drawing defines */
#define PNL_GRID 4
@@ -117,7 +117,7 @@ struct uiBut {
float x1, y1, x2, y2;
char *poin;
- float min, max;
+ float hardmin, hardmax, softmin, softmax;
float a1, a2, hsv[3]; // hsv is temp memory for hsv buttons
float aspect;
@@ -261,6 +261,8 @@ extern void ui_set_but_vectorf(uiBut *but, float *vec);
extern void ui_get_but_string(uiBut *but, char *str, int maxlen);
extern void ui_set_but_string(uiBut *but, const char *str);
+extern void ui_set_but_soft_range(uiBut *but, double value);
+
extern void ui_check_but(uiBut *but);
extern void ui_autofill(uiBlock *block);
extern int ui_is_but_float(uiBut *but);
@@ -334,6 +336,9 @@ extern void gl_round_box(int mode, float minx, float miny, float maxx, float max
extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown);
extern void gl_round_box_vertical_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight);
+void ui_draw_icon(uiBut *but, BIFIconID icon, int blend);
+void ui_draw_text(uiBut *but, float x, float y, int sunken);
+
/* interface_handlers.c */
extern void ui_button_active_cancel(const struct bContext *C, uiBut *but);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
new file mode 100644
index 00000000000..f6f5bae5fa5
--- /dev/null
+++ b/source/blender/editors/interface/interface_layout.c
@@ -0,0 +1,1004 @@
+
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_ID.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_listbase.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_idprop.h"
+#include "BKE_screen.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "BIF_gl.h"
+
+#include "ED_util.h"
+#include "ED_types.h"
+#include "ED_screen.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+/************************ Structs and Defines *************************/
+
+#define COLUMN_SPACE 5
+#define TEMPLATE_SPACE 5
+#define STACK_SPACE 5
+#define BUTTON_SPACE_X 5
+#define BUTTON_SPACE_Y 2
+
+#define RNA_NO_INDEX -1
+
+/* Item */
+
+typedef enum uiItemType {
+ ITEM_OPERATOR,
+ ITEM_RNA_PROPERTY,
+ ITEM_MENU,
+ ITEM_LABEL
+} uiItemType;
+
+enum uiItemFlag {
+ ITEM_ICON,
+ ITEM_TEXT
+};
+
+typedef struct uiItem {
+ struct uiItem *next, *prev;
+ uiItemType type;
+ int slot;
+
+ const char *name;
+ int icon;
+} uiItem;
+
+typedef struct uiItemRNA {
+ uiItem item;
+
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+} uiItemRNA;
+
+typedef struct uiItemOp {
+ uiItem item;
+
+ wmOperatorType *ot;
+ IDProperty *properties;
+ int context;
+} uiItemOp;
+
+typedef struct uiItemLMenu {
+ uiItem item;
+
+ uiMenuCreateFunc func;
+} uiItemLMenu;
+
+/* Template */
+
+typedef enum uiTemplateType {
+ TEMPLATE_COLUMN,
+ TEMPLATE_LR,
+ TEMPLATE_STACK,
+
+ TEMPLATE_HEADER_MENUS,
+ TEMPLATE_HEADER_BUTTONS,
+ TEMPLATE_HEADER_ID
+} uiTemplateType;
+
+typedef struct uiTemplate {
+ struct uiTemplate *next, *prev;
+ uiTemplateType type;
+
+ ListBase items;
+ int color;
+} uiTemplate;
+
+typedef struct uiTemplateStck {
+ uiTemplate template;
+ uiLayout *sublayout;
+} uiTemplateStck;
+
+typedef struct uiTemplateHeadID {
+ uiTemplate template;
+
+ PointerRNA ptr;
+ char *propname;
+ int flag;
+ uiIDPoinFunc func;
+} uiTemplateHeadID;
+
+/* Layout */
+
+struct uiLayout {
+ ListBase templates;
+ int opcontext;
+ int dir;
+ int x, y, w, h;
+};
+
+void ui_layout_free(uiLayout *layout);
+void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y);
+
+/************************** Item ***************************/
+
+static int ui_item_fit(int item, int all, int available)
+{
+ if(all > available)
+ return (item*available)/all;
+
+ return all;
+}
+
+/* create buttons for an item with an RNA array */
+static void ui_item_array(uiBlock *block, uiItemRNA *rnaitem, int len, int x, int y, int w, int h)
+{
+ PropertyType type;
+ PropertySubType subtype;
+ char *name;
+ int a;
+
+ /* retrieve type and subtype */
+ type= RNA_property_type(&rnaitem->ptr, rnaitem->prop);
+ subtype= RNA_property_subtype(&rnaitem->ptr, rnaitem->prop);
+
+ /* create label */
+ if(rnaitem->item.name)
+ name= (char*)rnaitem->item.name;
+ else
+ name= (char*)RNA_property_ui_name(&rnaitem->ptr, rnaitem->prop);
+
+ if(strcmp(name, "") != 0)
+ uiDefBut(block, LABEL, 0, name, x, y + h - YIC, w, YIC, NULL, 0.0, 0.0, 0, 0, "");
+
+ /* create buttons */
+ uiBlockBeginAlign(block);
+
+ if(type == PROP_BOOLEAN && len == 20) {
+ /* special check for layer layout */
+ int butw, buth;
+
+ butw= ui_item_fit(XIC, XIC*10 + BUTTON_SPACE_X, w);
+ buth= MIN2(YIC, butw);
+
+ y += 2*(YIC - buth);
+
+ uiBlockBeginAlign(block);
+ for(a=0; a<5; a++)
+ uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth);
+ for(a=0; a<5; a++)
+ uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a+10, "", ICON_BLANK1, x + butw*a, y, butw, buth);
+ uiBlockEndAlign(block);
+
+ x += 5*butw + BUTTON_SPACE_X;
+
+ uiBlockBeginAlign(block);
+ for(a=0; a<5; a++)
+ uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a+5, "", ICON_BLANK1, x + butw*a, y+buth, butw, buth);
+ for(a=0; a<5; a++)
+ uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a+15, "", ICON_BLANK1, x + butw*a, y, butw, buth);
+ uiBlockEndAlign(block);
+ }
+ else if(subtype == PROP_MATRIX) {
+ /* matrix layout */
+ int row, col;
+
+ len= ceil(sqrt(len));
+
+ h /= len;
+ w /= len;
+
+ // XXX test
+ for(a=0; a<len; a++) {
+ col= a%len;
+ row= a/len;
+
+ uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, "", 0, x + w*col, y+(row-a-1)*YIC, w, YIC);
+ }
+ }
+ else if(len <= 4 && ELEM3(subtype, PROP_ROTATION, PROP_VECTOR, PROP_COLOR)) {
+ /* layout for known array subtypes */
+ static char vectoritem[4]= {'X', 'Y', 'Z', 'W'};
+ static char quatitem[4]= {'W', 'X', 'Y', 'Z'};
+ static char coloritem[4]= {'R', 'G', 'B', 'A'};
+ char str[3];
+
+ for(a=0; a<len; a++) {
+ if(len == 4 && subtype == PROP_ROTATION)
+ str[0]= quatitem[a];
+ else if(subtype == PROP_VECTOR || subtype == PROP_ROTATION)
+ str[0]= vectoritem[a];
+ else
+ str[0]= coloritem[a];
+
+ if(type == PROP_BOOLEAN) {
+ str[1]= '\0';
+ }
+ else {
+ str[1]= ':';
+ str[2]= '\0';
+ }
+
+ uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, str, 0, x, y+(len-a-1)*YIC, w, YIC);
+ }
+ }
+ else {
+ /* default array layout */
+ for(a=0; a<len; a++)
+ uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, a, "", 0, x, y+(len-a-1)*YIC, w, YIC);
+ }
+
+ uiBlockEndAlign(block);
+}
+
+/* create lable + button for RNA property */
+static void ui_item_with_label(uiBlock *block, uiItemRNA *rnaitem, int x, int y, int w, int h)
+{
+ char *name;
+ int butw;
+
+ if(rnaitem->item.name)
+ name= (char*)rnaitem->item.name;
+ else
+ name= (char*)RNA_property_ui_name(&rnaitem->ptr, rnaitem->prop);
+
+ if(strcmp(name, "") != 0) {
+ butw= GetButStringLength(name);
+ uiDefBut(block, LABEL, 0, name, x, y, butw, h, NULL, 0.0, 0.0, 0, 0, "");
+
+ x += butw;
+ w -= butw;
+ }
+
+ uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, rnaitem->index, "", rnaitem->item.icon, x, y, w, h);
+}
+
+/* create buttons for an arbitrary item */
+static void ui_item_buts(uiBlock *block, uiItem *item, int x, int y, int w, int h)
+{
+ if(item->type == ITEM_RNA_PROPERTY) {
+ /* RNA property */
+ uiItemRNA *rnaitem= (uiItemRNA*)item;
+ PropertyType type;
+ int len;
+
+ /* retrieve info */
+ type= RNA_property_type(&rnaitem->ptr, rnaitem->prop);
+ len= RNA_property_array_length(&rnaitem->ptr, rnaitem->prop);
+
+ /* array property */
+ if(rnaitem->index == RNA_NO_INDEX && len > 0)
+ ui_item_array(block, rnaitem, len, x, y, w, h);
+ /* property with separate label */
+ else if(type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER)
+ ui_item_with_label(block, rnaitem, x, y, w, h);
+ /* single button */
+ else
+ uiDefAutoButR(block, &rnaitem->ptr, rnaitem->prop, rnaitem->index, (char*)item->name, item->icon, x, y, w, h);
+ }
+ else if(item->type == ITEM_OPERATOR) {
+ /* operator */
+ uiItemOp *opitem= (uiItemOp*)item;
+
+ if(item->icon && item->name)
+ uiDefIconTextButO(block, BUT, opitem->ot->idname, opitem->context, item->icon, (char*)item->name, x, y, w, h, NULL);
+ else if(item->icon)
+ uiDefIconButO(block, BUT, opitem->ot->idname, opitem->context, item->icon, x, y, w, h, NULL);
+ /* text only */
+ else
+ uiDefButO(block, BUT, opitem->ot->idname, opitem->context, (char*)item->name, x, y, w, h, NULL);
+ }
+ else if(item->type == ITEM_MENU) {
+ /* menu */
+ uiItemLMenu *menuitem= (uiItemLMenu*)item;
+
+ uiDefMenuBut(block, menuitem->func, NULL, (char*)item->name, x, y-2, w-3, h+4, "");
+ }
+ else if(item->type == ITEM_LABEL) {
+ /* label */
+
+ if(item->icon && item->name)
+ uiDefIconTextBut(block, LABEL, 0, item->icon, (char*)item->name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
+ else if(item->icon)
+ uiDefIconBut(block, LABEL, 0, item->icon, x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
+ else if((char*)item->name)
+ uiDefBut(block, LABEL, 0, (char*)item->name, x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
+ }
+ else {
+ /* separator */
+ uiDefBut(block, SEPR, 0, "", x, y, w, h, NULL, 0.0, 0.0, 0, 0, "");
+ }
+}
+
+/* estimated size of text + icon */
+static int ui_text_icon_width(const char *name, int icon)
+{
+ if(icon && name && strcmp(name, "") == 0)
+ return XIC; /* icon only */
+ else if(icon && name)
+ return XIC + GetButStringLength((char*)name); /* icon + text */
+ else if(name)
+ return GetButStringLength((char*)name); /* text only */
+ else
+ return 0;
+}
+
+/* estimated size of an item */
+static void ui_item_size(uiItem *item, int *r_w, int *r_h)
+{
+ const char *name;
+ int w, h;
+
+ if(item->type == ITEM_RNA_PROPERTY) {
+ /* RNA property */
+ uiItemRNA *rnaitem= (uiItemRNA*)item;
+ PropertyType type;
+ PropertySubType subtype;
+ int len;
+
+ name= item->name;
+ if(!name)
+ name= RNA_property_ui_name(&rnaitem->ptr, rnaitem->prop);
+
+ w= ui_text_icon_width(name, item->icon);
+ h= YIC;
+
+ /* arbitrary extended width by type */
+ type= RNA_property_type(&rnaitem->ptr, rnaitem->prop);
+ subtype= RNA_property_subtype(&rnaitem->ptr, rnaitem->prop);
+ len= RNA_property_array_length(&rnaitem->ptr, rnaitem->prop);
+
+ if(type == PROP_BOOLEAN && !item->icon)
+ w += XIC;
+ else if(type == PROP_INT || type == PROP_FLOAT)
+ w += 2*XIC;
+ else if(type == PROP_STRING)
+ w += 8*XIC;
+
+ /* increase height for arrays */
+ if(rnaitem->index == RNA_NO_INDEX && len > 0) {
+ if(name && strcmp(name, "") == 0 && item->icon == 0)
+ h= 0;
+
+ if(type == PROP_BOOLEAN && len == 20)
+ h += 2*YIC;
+ else if(subtype == PROP_MATRIX)
+ h += ceil(sqrt(len))*YIC;
+ else
+ h += len*YIC;
+ }
+ }
+ else if(item->type == ITEM_OPERATOR) {
+ /* operator */
+ uiItemOp *opitem= (uiItemOp*)item;
+
+ name= item->name;
+ if(!name)
+ name= opitem->ot->name;
+
+ w= ui_text_icon_width(name, item->icon);
+ h= YIC;
+ }
+ else {
+ /* other */
+ w= ui_text_icon_width(item->name, item->icon);
+ h= YIC;
+ }
+
+ if(r_w) *r_w= w;
+ if(r_h) *r_h= h;
+}
+
+static void ui_item_free(uiItem *item)
+{
+ if(item->type == ITEM_OPERATOR) {
+ uiItemOp *opitem= (uiItemOp*)item;
+
+ if(opitem->properties) {
+ IDP_FreeProperty(opitem->properties);
+ MEM_freeN(opitem->properties);
+ }
+ }
+}
+
+/* operator items */
+void uiItemFullO(uiLayout *layout, int slot, const char *name, int icon, char *idname, IDProperty *properties, int context)
+{
+ uiTemplate *template= layout->templates.last;
+ wmOperatorType *ot= WM_operatortype_find(idname);
+ uiItemOp *opitem;
+
+ if(!ot)
+ return;
+
+ opitem= MEM_callocN(sizeof(uiItemOp), "uiItemOp");
+
+ opitem->item.name= name;
+ opitem->item.icon= icon;
+ opitem->item.type= ITEM_OPERATOR;
+ opitem->item.slot= slot;
+
+ opitem->ot= ot;
+ opitem->properties= properties;
+ opitem->context= context;
+
+ BLI_addtail(&template->items, opitem);
+}
+
+void uiItemEnumO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, int value)
+{
+ PointerRNA ptr;
+
+ WM_operator_properties_create(&ptr, opname);
+ RNA_enum_set(&ptr, propname, value);
+
+ uiItemFullO(layout, slot, name, icon, opname, ptr.data, layout->opcontext);
+}
+
+void uiItemsEnumO(uiLayout *layout, int slot, char *opname, char *propname)
+{
+ wmOperatorType *ot= WM_operatortype_find(opname);
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ if(!ot || !ot->srna)
+ return;
+
+ RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
+ prop= RNA_struct_find_property(&ptr, propname);
+
+ if(prop && RNA_property_type(&ptr, prop) == PROP_ENUM) {
+ const EnumPropertyItem *item;
+ int totitem, i;
+
+ RNA_property_enum_items(&ptr, prop, &item, &totitem);
+
+ for(i=0; i<totitem; i++)
+ uiItemEnumO(layout, slot, "", 0, opname, propname, item[i].value);
+ }
+}
+
+void uiItemBooleanO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, int value)
+{
+ PointerRNA ptr;
+
+ WM_operator_properties_create(&ptr, opname);
+ RNA_boolean_set(&ptr, propname, value);
+
+ uiItemFullO(layout, slot, name, icon, opname, ptr.data, layout->opcontext);
+}
+
+void uiItemIntO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, int value)
+{
+ PointerRNA ptr;
+
+ WM_operator_properties_create(&ptr, opname);
+ RNA_int_set(&ptr, propname, value);
+
+ uiItemFullO(layout, slot, name, icon, opname, ptr.data, layout->opcontext);
+}
+
+void uiItemFloatO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, float value)
+{
+ PointerRNA ptr;
+
+ WM_operator_properties_create(&ptr, opname);
+ RNA_float_set(&ptr, propname, value);
+
+ uiItemFullO(layout, slot, name, icon, opname, ptr.data, layout->opcontext);
+}
+
+void uiItemStringO(uiLayout *layout, int slot, const char *name, int icon, char *opname, char *propname, char *value)
+{
+ PointerRNA ptr;
+
+ WM_operator_properties_create(&ptr, opname);
+ RNA_string_set(&ptr, propname, value);
+
+ uiItemFullO(layout, slot, name, icon, opname, ptr.data, layout->opcontext);
+}
+
+void uiItemO(uiLayout *layout, int slot, const char *name, int icon, char *opname)
+{
+ uiItemFullO(layout, slot, name, icon, opname, NULL, layout->opcontext);
+}
+
+/* RNA property items */
+void uiItemFullR(uiLayout *layout, int slot, const char *name, int icon, PointerRNA *ptr, char *propname, int index)
+{
+ uiTemplate *template= layout->templates.last;
+ PropertyRNA *prop;
+ uiItemRNA *rnaitem;
+
+ prop= RNA_struct_find_property(ptr, propname);
+ if(!prop)
+ return;
+
+ rnaitem= MEM_callocN(sizeof(uiItemRNA), "uiItemRNA");
+
+ rnaitem->item.name= name;
+ rnaitem->item.icon= icon;
+ rnaitem->item.type= ITEM_RNA_PROPERTY;
+ rnaitem->item.slot= slot;
+
+ rnaitem->ptr= *ptr;
+ rnaitem->prop= prop;
+ rnaitem->index= index;
+
+ BLI_addtail(&template->items, rnaitem);
+}
+
+void uiItemR(uiLayout *layout, int slot, const char *name, int icon, PointerRNA *ptr, char *propname)
+{
+ uiItemFullR(layout, slot, name, icon, ptr, propname, RNA_NO_INDEX);
+}
+
+/* menu item */
+void uiItemMenu(uiLayout *layout, int slot, const char *name, int icon, uiMenuCreateFunc func)
+{
+ uiTemplate *template= layout->templates.last;
+ uiItemLMenu *menuitem= MEM_callocN(sizeof(uiItemLMenu), "uiItemLMenu");
+
+ menuitem->item.name= name;
+ menuitem->item.icon= icon;
+ menuitem->item.type= ITEM_MENU;
+ menuitem->item.slot= slot;
+
+ menuitem->func= func;
+
+ BLI_addtail(&template->items, menuitem);
+}
+
+/* label item */
+void uiItemLabel(uiLayout *layout, int slot, const char *name, int icon)
+{
+ uiTemplate *template= layout->templates.last;
+ uiItem *item= MEM_callocN(sizeof(uiItem), "uiItem");
+
+ item->name= name;
+ item->icon= icon;
+ item->type= ITEM_LABEL;
+ item->slot= slot;
+
+ BLI_addtail(&template->items, item);
+}
+
+/**************************** Template ***************************/
+
+/* multi-column layout */
+static void ui_layout_column(uiLayout *layout, uiBlock *block, uiTemplate *template, int *x, int *y, int w, int h)
+{
+ uiItem *item;
+ int col, totcol= 0, colx, coly, colw, miny, itemw, itemh;
+
+ /* compute number of columns */
+ for(item=template->items.first; item; item=item->next)
+ totcol= MAX2(item->slot+1, totcol);
+
+ if(totcol == 0)
+ return;
+
+ colx= *x;
+ colw= (w - (totcol-1)*COLUMN_SPACE)/totcol;
+ miny= *y;
+
+ /* create column per column */
+ for(col=0; col<totcol; col++) {
+ coly= *y;
+
+ for(item=template->items.first; item; item=item->next) {
+ if(item->slot != col)
+ continue;
+
+ ui_item_size(item, &itemw, &itemh);
+
+ coly -= itemh + BUTTON_SPACE_Y;
+ ui_item_buts(block, item, colx, coly, colw, itemh);
+ }
+
+ colx += colw + COLUMN_SPACE;
+ miny= MIN2(miny, coly);
+ }
+
+ *y= miny;
+}
+
+/* left-right layout, with buttons aligned on both sides */
+static void ui_layout_lr(uiLayout *layout, uiBlock *block, uiTemplate *template, int *x, int *y, int w, int h)
+{
+ uiItem *item;
+ int totw= 0, maxh= 0, itemw, itemh, leftx, rightx;
+
+ /* estimate total width of buttons */
+ for(item=template->items.first; item; item=item->next) {
+ ui_item_size(item, &itemw, &itemh);
+ totw += itemw;
+ maxh= MAX2(maxh, itemh);
+ }
+
+ if(totw == 0)
+ return;
+
+ /* create buttons starting from left and right */
+ leftx= *x;
+ rightx= *x + w;
+
+ for(item=template->items.first; item; item=item->next) {
+ ui_item_size(item, &itemw, &itemh);
+ itemw= ui_item_fit(itemw, totw+BUTTON_SPACE_X, w);
+
+ if(item->slot == UI_TSLOT_LR_LEFT) {
+ ui_item_buts(block, item, leftx, *y-itemh, itemw, itemh);
+ leftx += itemw;
+ }
+ else {
+ rightx -= itemw;
+ ui_item_buts(block, item, rightx, *y-itemh, itemw, itemh);
+ }
+ }
+
+ *y -= maxh;
+}
+
+/* element in a stack layout */
+static void ui_layout_stack(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template, int *x, int *y, int w, int h)
+{
+ uiTemplateStck *stack= (uiTemplateStck*)template;
+ int starty, startx;
+
+ startx= *x;
+ starty= *y;
+
+ /* some extra padding */
+ stack->sublayout->x= *x + STACK_SPACE;
+ stack->sublayout->w= w - 2*STACK_SPACE;
+ stack->sublayout->y= *y - STACK_SPACE;
+ stack->sublayout->h= h;
+
+ /* do layout for elements in sublayout */
+ ui_layout_end(C, block, stack->sublayout, NULL, y);
+
+ /* roundbox around the sublayout */
+ uiDefBut(block, ROUNDBOX, 0, "", startx, *y, w, starty - *y, NULL, 7.0, 0.0, 3, 20, "");
+}
+
+static void ui_layout_header_buttons(uiLayout *layout, uiBlock *block, uiTemplate *template, int *x, int *y, int w, int h)
+{
+ uiItem *item;
+ int itemw, itemh;
+
+ uiBlockBeginAlign(block);
+
+ for(item=template->items.first; item; item=item->next) {
+ ui_item_size(item, &itemw, &itemh);
+ ui_item_buts(block, item, *x, *y, itemw, itemh);
+ *x += itemw;
+ }
+
+ uiBlockEndAlign(block);
+}
+
+static void ui_layout_header_menus(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template, int *x, int *y, int w, int h)
+{
+ ScrArea *sa= CTX_wm_area(C);
+
+ *x= ED_area_header_standardbuttons(C, block, *y);
+
+ if((sa->flag & HEADER_NO_PULLDOWN)==0) {
+ uiBlockSetEmboss(block, UI_EMBOSSP);
+ ui_layout_header_buttons(layout, block, template, x, y, w, h);
+ }
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+}
+
+static void ui_layout_header_id(const bContext *C, uiLayout *layout, uiBlock *block, uiTemplate *template, int *x, int *y, int w, int h)
+{
+ uiTemplateHeadID *idtemplate= (uiTemplateHeadID*)template;
+ PointerRNA idptr;
+
+ idptr= RNA_pointer_get(&idtemplate->ptr, idtemplate->propname);
+
+ *x= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)idptr.data, ID_TXT, NULL, *x, *y,
+ idtemplate->func, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE);
+}
+
+void ui_template_free(uiTemplate *template)
+{
+ uiItem *item;
+
+ if(template->type == TEMPLATE_STACK) {
+ uiTemplateStck *stack= (uiTemplateStck*)template;
+ ui_layout_free(stack->sublayout);
+ }
+
+ for(item=template->items.first; item; item=item->next)
+ ui_item_free(item);
+
+ BLI_freelistN(&template->items);
+}
+
+/* template create functions */
+void uiTemplateColumn(uiLayout *layout)
+{
+ uiTemplate *template;
+
+ template= MEM_callocN(sizeof(uiTemplate), "uiTemplate");
+ template->type= TEMPLATE_COLUMN;
+
+ BLI_addtail(&layout->templates, template);
+}
+
+
+void uiTemplateLeftRight(uiLayout *layout)
+{
+ uiTemplate *template;
+
+ template= MEM_callocN(sizeof(uiTemplate), "uiTemplate");
+ template->type= TEMPLATE_LR;
+
+ BLI_addtail(&layout->templates, template);
+}
+
+uiLayout *uiTemplateStack(uiLayout *layout)
+{
+ uiTemplateStck *stack;
+
+ stack= MEM_callocN(sizeof(uiTemplateStck), "uiTemplateStck");
+ stack->template.type= TEMPLATE_STACK;
+ stack->sublayout= uiLayoutBegin(layout->dir, 0, 0, 0, 0);
+ BLI_addtail(&layout->templates, stack);
+
+ return stack->sublayout;
+}
+
+void uiTemplateHeaderMenus(uiLayout *layout)
+{
+ uiTemplate *template;
+
+ template= MEM_callocN(sizeof(uiTemplate), "uiTemplate");
+ template->type= TEMPLATE_HEADER_MENUS;
+
+ BLI_addtail(&layout->templates, template);
+}
+
+void uiTemplateHeaderButtons(uiLayout *layout)
+{
+ uiTemplate *template;
+
+ template= MEM_callocN(sizeof(uiTemplate), "uiTemplate");
+ template->type= TEMPLATE_HEADER_BUTTONS;
+
+ BLI_addtail(&layout->templates, template);
+}
+
+void uiTemplateHeaderID(uiLayout *layout, PointerRNA *ptr, char *propname, int flag, uiIDPoinFunc func)
+{
+ uiTemplateHeadID *idtemplate;
+
+ idtemplate= MEM_callocN(sizeof(uiTemplateHeadID), "uiTemplateHeadID");
+ idtemplate->template.type= TEMPLATE_HEADER_ID;
+ idtemplate->ptr= *ptr;
+ idtemplate->propname= propname;
+ idtemplate->flag= flag;
+ idtemplate->func= func;
+
+ BLI_addtail(&layout->templates, idtemplate);
+}
+
+void uiTemplateSetColor(uiLayout *layout, int color)
+{
+ uiTemplate *template= layout->templates.last;
+
+ template->color= color;
+}
+
+/********************** Layout *******************/
+
+static void ui_layout_templates(const bContext *C, uiBlock *block, uiLayout *layout)
+{
+ uiTemplate *template;
+ int oldcolor= 0;
+
+ for(template=layout->templates.first; template; template=template->next) {
+ if(template->color) {
+ oldcolor= uiBlockGetCol(block);
+ uiBlockSetCol(block, template->color);
+ }
+
+ switch(template->type) {
+ case TEMPLATE_COLUMN:
+ ui_layout_column(layout, block, template, &layout->x, &layout->y, layout->w, layout->h);
+ break;
+ case TEMPLATE_LR:
+ ui_layout_lr(layout, block, template, &layout->x, &layout->y, layout->w, layout->h);
+ break;
+ case TEMPLATE_STACK:
+ ui_layout_stack(C, layout, block, template, &layout->x, &layout->y, layout->w, layout->h);
+ break;
+ case TEMPLATE_HEADER_MENUS:
+ ui_layout_header_menus(C, layout, block, template, &layout->x, &layout->y, layout->w, layout->h);
+ break;
+ case TEMPLATE_HEADER_BUTTONS:
+ ui_layout_header_buttons(layout, block, template, &layout->x, &layout->y, layout->w, layout->h);
+ break;
+ case TEMPLATE_HEADER_ID:
+ ui_layout_header_id(C, layout, block, template, &layout->x, &layout->y, layout->w, layout->h);
+ break;
+ }
+
+ if(template->color)
+ uiBlockSetCol(block, oldcolor);
+
+ if(layout->dir == UI_LAYOUT_HORIZONTAL)
+ layout->x += TEMPLATE_SPACE;
+ else
+ layout->y -= TEMPLATE_SPACE;
+ }
+}
+
+void ui_layout_end(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y)
+{
+ ui_layout_templates(C, block, layout);
+
+ if(x) *x= layout->x;
+ if(y) *y= layout->y;
+
+ /* XXX temp, migration flag for drawing code */
+ uiBlockSetFlag(block, UI_BLOCK_2_50);
+}
+
+void ui_layout_free(uiLayout *layout)
+{
+ uiTemplate *template;
+
+ for(template=layout->templates.first; template; template=template->next)
+ ui_template_free(template);
+
+ BLI_freelistN(&layout->templates);
+ MEM_freeN(layout);
+}
+
+uiLayout *uiLayoutBegin(int dir, int x, int y, int w, int h)
+{
+ uiLayout *layout;
+
+ layout= MEM_callocN(sizeof(uiLayout), "uiLayout");
+ layout->opcontext= WM_OP_INVOKE_REGION_WIN;
+ layout->dir= dir;
+ layout->x= x;
+ layout->y= y;
+ layout->w= w;
+ layout->h= h;
+
+ return layout;
+}
+
+void uiLayoutContext(uiLayout *layout, int opcontext)
+{
+ layout->opcontext= opcontext;
+}
+
+void uiLayoutEnd(const bContext *C, uiBlock *block, uiLayout *layout, int *x, int *y)
+{
+ ui_layout_end(C, block, layout, x, y);
+ ui_layout_free(layout);
+}
+
+/* Utilities */
+
+void uiRegionPanelLayout(const bContext *C, ARegion *ar, int vertical, char *context)
+{
+ uiBlock *block;
+ PanelType *pt;
+ Panel *panel;
+ float col[3];
+ int xco, yco, x=0, y=0, w;
+
+ // XXX this only hides cruft
+
+ /* clear */
+ UI_GetThemeColor3fv(TH_HEADER, col);
+ glClearColor(col[0], col[1], col[2], 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* set view2d view matrix for scrolling (without scrollers) */
+ UI_view2d_view_ortho(C, &ar->v2d);
+
+ for(pt= ar->type->paneltypes.first; pt; pt= pt->next) {
+ if(context)
+ if(!pt->context || strcmp(context, pt->context) != 0)
+ continue;
+
+ if(pt->draw && (!pt->poll || pt->poll(C))) {
+ w= (ar->type->minsizex)? ar->type->minsizex-22: UI_PANEL_WIDTH-22;
+
+ block= uiBeginBlock(C, ar, pt->idname, UI_EMBOSS, UI_HELV);
+ if(uiNewPanel(C, ar, block, pt->name, pt->name, x, y, w, 0)==0) return;
+
+ panel= uiPanelFromBlock(block);
+ panel->type= pt;
+ panel->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, x, y, w, 0);
+
+ pt->draw(C, panel);
+
+ uiLayoutEnd(C, block, panel->layout, &xco, &yco);
+ uiEndBlock(C, block);
+
+ panel->layout= NULL;
+ uiNewPanelHeight(block, y - yco + 6);
+
+ if(vertical)
+ y += yco;
+ else
+ x += xco;
+ }
+ }
+
+ uiDrawPanels(C, 1);
+ uiMatchPanelsView2d(ar);
+
+ /* restore view matrix? */
+ UI_view2d_view_restore(C);
+}
+
+void uiRegionHeaderLayout(const bContext *C, ARegion *ar)
+{
+ uiBlock *block;
+ uiLayout *layout;
+ HeaderType *ht;
+ float col[3];
+ int xco, yco;
+
+ // XXX this only hides cruft
+
+ /* clear */
+ if(ED_screen_area_active(C))
+ UI_GetThemeColor3fv(TH_HEADER, col);
+ else
+ UI_GetThemeColor3fv(TH_HEADERDESEL, col);
+
+ glClearColor(col[0], col[1], col[2], 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* set view2d view matrix for scrolling (without scrollers) */
+ UI_view2d_view_ortho(C, &ar->v2d);
+
+ xco= 8;
+ yco= 3;
+
+ /* draw all headers types */
+ for(ht= ar->type->headertypes.first; ht; ht= ht->next) {
+ block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS, UI_HELV);
+ layout= uiLayoutBegin(UI_LAYOUT_HORIZONTAL, xco, yco, 0, 24);
+
+ if(ht->draw)
+ ht->draw(C, layout);
+
+ uiLayoutEnd(C, block, layout, &xco, &yco);
+ uiEndBlock(C, block);
+ uiDrawBlock(C, block);
+ }
+
+ /* always as last */
+ UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
+
+ /* restore view matrix? */
+ UI_view2d_view_restore(C);
+}
+
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 6775f6362b8..17a58f8b616 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -236,6 +236,11 @@ int uiNewPanel(const bContext *C, ARegion *ar, uiBlock *block, char *panelname,
return 1;
}
+Panel *uiPanelFromBlock(uiBlock *block)
+{
+ return block->panel;
+}
+
void uiFreePanels(ListBase *lb)
{
BLI_freelistN(lb);
@@ -932,8 +937,7 @@ int uiAlignPanelStep(ScrArea *sa, ARegion *ar, float fac)
if(align==BUT_VERTICAL)
ps->pa->ofsy= -ps->pa->sizey-PNL_HEADER-PNL_DIST;
else
- ps->pa->ofsy= 0;
-
+ ps->pa->ofsy= -ps->pa->sizey-PNL_HEADER-PNL_DIST; // XXX was 0;
for(a=0 ; a<tot-1; a++, ps++) {
psnext= ps+1;
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 5365c3e09f0..d64ad75a48a 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -261,7 +261,7 @@ static void ui_tooltip_region_draw(const bContext *C, ARegion *ar)
{
uiTooltipData *data;
int x1, y1, x2, y2;
-
+
data= ar->regiondata;
x1= ar->winrct.xmin;
@@ -269,34 +269,21 @@ static void ui_tooltip_region_draw(const bContext *C, ARegion *ar)
x2= ar->winrct.xmax;
y2= ar->winrct.ymax;
- /* draw drop shadow */
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ /* draw background */
glEnable(GL_BLEND);
-
- glColor4ub(0, 0, 0, 20);
-
- gl_round_box(GL_POLYGON, 3, 3, x2-x1-3, y2-y1-2, 2.0);
- gl_round_box(GL_POLYGON, 3, 2, x2-x1-2, y2-y1-2, 3.0);
+ glColor4f(0.15f, 0.15f, 0.15f, 0.85f);
- glColor4ub(0, 0, 0, 8);
-
- gl_round_box(GL_POLYGON, 3, 1, x2-x1-1, y2-y1-3, 4.0);
- gl_round_box(GL_POLYGON, 3, 0, x2-x1-0, y2-y1-3, 5.0);
-
- glDisable(GL_BLEND);
-
- /* draw background */
- glColor3f(1.0f, 1.0f, 0.8666f);
- glRectf(0, 4, x2-x1-4, y2-y1);
+ uiSetRoundBox(15);
+ uiRoundBox(data->bbox.xmin, 2, data->bbox.xmax+10, y2-y1-2, 5.0f);
/* draw text */
- glColor3ub(0,0,0);
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- /* set the position for drawing text +4 in from the left edge, and leaving
+ /* set the position for drawing text +6 in from the left edge, and leaving
* an equal gap between the top of the background box and the top of the
* string's bbox, and the bottom of the background box, and the bottom of
* the string's bbox */
- ui_rasterpos_safe(4, ((y2-data->bbox.ymax)+(y1+data->bbox.ymin))/2 - data->bbox.ymin - y1, data->aspect);
+ ui_rasterpos_safe(5, ((y2-data->bbox.ymax)+(y1+data->bbox.ymin))/2 - data->bbox.ymin - y1, data->aspect);
UI_SetScale(1.0);
UI_DrawString(data->font, data->tip, ui_translate_tooltips());
@@ -856,8 +843,8 @@ uiBlock *ui_block_func_ICONROW(bContext *C, uiPopupBlockHandle *handle, void *ar
block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT;
block->themecol= TH_MENU_ITEM;
- for(a=(int)but->min; a<=(int)but->max; a++) {
- uiDefIconButF(block, BUTM|FLO, B_NOP, but->icon+(a-but->min), 0, (short)(18*a), (short)(but->x2-but->x1-4), 18, &handle->retvalue, (float)a, 0.0, 0, 0, "");
+ for(a=(int)but->hardmin; a<=(int)but->hardmax; a++) {
+ uiDefIconButF(block, BUTM|FLO, B_NOP, but->icon+(a-but->hardmin), 0, (short)(18*a), (short)(but->x2-but->x1-4), 18, &handle->retvalue, (float)a, 0.0, 0, 0, "");
}
block->direction= UI_TOP;
@@ -905,7 +892,7 @@ uiBlock *ui_block_func_ICONTEXTROW(bContext *C, uiPopupBlockHandle *handle, void
ypos +=3;
}
else {
- uiDefIconTextButF(block, BUTM|FLO, B_NOP, (short)((but->icon)+(md->items[a].retval-but->min)), md->items[a].str, 0, ypos,(short)width, 19, &handle->retvalue, (float) md->items[a].retval, 0.0, 0, 0, "");
+ uiDefIconTextButF(block, BUTM|FLO, B_NOP, (short)((but->icon)+(md->items[a].retval-but->hardmin)), md->items[a].str, 0, ypos,(short)width, 19, &handle->retvalue, (float) md->items[a].retval, 0.0, 0, 0, "");
ypos += 20;
}
}
@@ -2236,7 +2223,7 @@ void uiPupMenuEnd(bContext *C, uiMenuItem *head)
menu= ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_MENU_ITEM, &info);
menu->popup= 1;
- UI_add_popup_handlers(&window->handlers, menu);
+ UI_add_popup_handlers(C, &window->handlers, menu);
WM_event_add_mousemove(C);
BLI_freelistN(&head->items);
@@ -2261,7 +2248,7 @@ static uiPopupBlockHandle *ui_pup_menu(bContext *C, int maxrow, uiMenuHandleFunc
menu= ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_PUPMENU, &info);
menu->popup= 1;
- UI_add_popup_handlers(&window->handlers, menu);
+ UI_add_popup_handlers(C, &window->handlers, menu);
WM_event_add_mousemove(C);
menu->popup_func= func;
@@ -2412,7 +2399,7 @@ void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, char *opname, i
handle->opname= opname;
handle->opcontext= opcontext;
- UI_add_popup_handlers(&window->handlers, handle);
+ UI_add_popup_handlers(C, &window->handlers, handle);
WM_event_add_mousemove(C);
}
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 58563166847..429b2de0227 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -217,7 +217,7 @@ int UI_GetIconRNA(PointerRNA *ptr)
return ICON_DOT;
}
-uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, char *name, int x1, int y1, int x2, int y2)
+uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2)
{
uiBut *but=NULL;
const char *propname= RNA_property_identifier(ptr, prop);
@@ -237,10 +237,12 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
else
value= RNA_property_boolean_get(ptr, prop);
- if(name && strcmp(name, "") == 0)
- name= (value)? "Enabled": "Disabled";
-
- but= uiDefButR(block, TOG, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ if(icon && name && strcmp(name, "") == 0)
+ but= uiDefIconButR(block, ICONTOG, 0, icon, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ else if(icon)
+ but= uiDefIconTextButR(block, ICONTOG, 0, icon, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
+ else
+ but= uiDefButR(block, TOG, 0, name, x1, y1, x2, y2, ptr, propname, index, 0, 0, -1, -1, NULL);
break;
}
case PROP_INT:
@@ -267,24 +269,29 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
int icon;
pptr= RNA_property_pointer_get(ptr, prop);
+ descr= (char*)RNA_property_ui_description(ptr, prop);
- if(!pptr.data)
- return NULL;
+ if(!pptr.type)
+ pptr.type= RNA_property_pointer_type(ptr, prop);
icon= UI_GetIconRNA(&pptr);
- nameprop= RNA_struct_name_property(&pptr);
-
- if(nameprop) {
- text= RNA_property_string_get_alloc(&pptr, nameprop, textbuf, sizeof(textbuf));
- descr= (char*)RNA_property_ui_description(&pptr, prop);
- but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
- if(text != textbuf)
- MEM_freeN(text);
+
+ if(pptr.data == NULL) {
+ but= uiDefIconTextBut(block, LABEL, 0, icon, "", x1, y1, x2, y2, NULL, 0, 0, 0, 0, "");
}
else {
- text= (char*)RNA_struct_ui_name(&pptr);
- descr= (char*)RNA_property_ui_description(&pptr, prop);
- but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
+ nameprop= RNA_struct_name_property(&pptr);
+
+ if(nameprop) {
+ text= RNA_property_string_get_alloc(&pptr, nameprop, textbuf, sizeof(textbuf));
+ but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
+ if(text != textbuf)
+ MEM_freeN(text);
+ }
+ else {
+ text= (char*)RNA_struct_ui_name(&pptr);
+ but= uiDefIconTextBut(block, LABEL, 0, icon, text, x1, y1, x2, y2, NULL, 0, 0, 0, 0, descr);
+ }
}
break;
}
@@ -303,22 +310,18 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
return but;
}
-int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
+int uiDefAutoButsRNA(const bContext *C, uiBlock *block, PointerRNA *ptr)
{
CollectionPropertyIterator iter;
PropertyRNA *iterprop, *prop;
- PropertySubType subtype;
- char *name, namebuf[128];
- int a= 0, length, x= 0, y= 0;
+ uiLayout *layout;
+ char *name;
+ int x= 0, y= 0;
- x= 0;
- y= 0;
+ layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, x, y, DEF_BUT_WIDTH*2, 0);
- /* create buttons */
- uiSetCurFont(block, UI_HELVB);
- uiDefBut(block, LABEL, 0, (char*)RNA_struct_ui_name(ptr), x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
- y -= DEF_BUT_HEIGHT;
- uiSetCurFont(block, UI_HELV);
+ uiTemplateColumn(layout);
+ uiItemLabel(layout, UI_TSLOT_COLUMN_1, (char*)RNA_struct_ui_name(ptr), 0);
iterprop= RNA_struct_iterator_property(ptr);
RNA_property_collection_begin(ptr, iterprop, &iter);
@@ -329,74 +332,15 @@ int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
if(strcmp(RNA_property_identifier(ptr, prop), "rna_type") == 0)
continue;
- if((length= RNA_property_array_length(ptr, prop))) {
- name= (char*)RNA_property_ui_name(ptr, prop);
- uiDefBut(block, LABEL, 0, name, x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
- }
- else
- length= 1;
-
- subtype= RNA_property_subtype(ptr, prop);
+ uiTemplateColumn(layout);
name= (char*)RNA_property_ui_name(ptr, prop);
- uiDefBut(block, LABEL, 0, name, x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
-
- uiBlockBeginAlign(block);
-
- if(length <= 16 && subtype == PROP_MATRIX) {
- /* matrix layout */
- int size, row, col, butwidth;
-
- size= ceil(sqrt(length));
- butwidth= DEF_BUT_WIDTH*2/size;
- y -= DEF_BUT_HEIGHT;
-
- for(a=0; a<length; a++) {
- col= a%size;
- row= a/size;
-
- uiDefAutoButR(block, ptr, prop, a, "", x+butwidth*col, y-row*DEF_BUT_HEIGHT, butwidth, DEF_BUT_HEIGHT-1);
- }
-
- y -= DEF_BUT_HEIGHT*(length/size);
- }
- else if(length <= 4 && ELEM3(subtype, PROP_ROTATION, PROP_VECTOR, PROP_COLOR)) {
- static char *vectoritem[4]= {"X:", "Y:", "Z:", "W:"};
- static char *quatitem[4]= {"W:", "X:", "Y:", "Z:"};
- static char *coloritem[4]= {"R:", "G:", "B:", "A:"};
- int butwidth;
-
- butwidth= DEF_BUT_WIDTH*2/length;
- y -= DEF_BUT_HEIGHT;
-
- for(a=0; a<length; a++) {
- if(length == 4 && subtype == PROP_ROTATION)
- name= quatitem[a];
- else if(subtype == PROP_VECTOR || subtype == PROP_ROTATION)
- name= vectoritem[a];
- else
- name= coloritem[a];
-
- uiDefAutoButR(block, ptr, prop, a, name, x+butwidth*a, y, butwidth, DEF_BUT_HEIGHT-1);
- }
- y -= DEF_BUT_HEIGHT;
- }
- else {
- if(RNA_property_array_length(ptr, prop)) {
- sprintf(namebuf, "%d:", a+1);
- name= namebuf;
- }
- else
- name= "";
-
- uiDefAutoButR(block, ptr, prop, 0, name, x+DEF_BUT_WIDTH, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1);
- y -= DEF_BUT_HEIGHT;
- }
-
- uiBlockEndAlign(block);
+ uiItemLabel(layout, UI_TSLOT_COLUMN_1, name, 0);
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "", 0, ptr, (char*)RNA_property_identifier(ptr, prop));
}
RNA_property_collection_end(&iter);
+ uiLayoutEnd(C, block, layout, &x, &y);
return -y;
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
new file mode 100644
index 00000000000..be7bb5c09d8
--- /dev/null
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -0,0 +1,1046 @@
+/**
+* ***** 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) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_ID.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_arithb.h"
+#include "BLI_listbase.h"
+#include "BLI_rect.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_idprop.h"
+#include "BKE_utildefines.h"
+
+#include "RNA_access.h"
+
+#include "BIF_gl.h"
+
+#include "UI_interface.h"
+#include "UI_interface_icons.h"
+#include "UI_resources.h"
+#include "UI_text.h"
+#include "UI_view2d.h"
+
+#include "ED_util.h"
+#include "ED_types.h"
+#include "ED_screen.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BMF_Api.h"
+#ifdef INTERNATIONAL
+#include "FTF_Api.h"
+#endif
+
+#include "interface_intern.h"
+
+/* ************** widget base functions ************** */
+/*
+ - in: roundbox codes for corner types and radius
+ - return: array of [size][2][x,y] points, the edges of the roundbox, + UV coords
+
+ - draw black box with alpha 0 on exact button boundbox
+ - for ever AA step:
+ - draw the inner part for a round filled box, with color blend codes or texture coords
+ - draw outline in outline color
+ - draw outer part, bottom half, extruded 1 pixel to bottom, for emboss shadow
+ - draw extra decorations
+ - draw background color box with alpha 1 on exact button boundbox
+
+ */
+
+/* fill this struct with polygon info to draw AA'ed */
+/* it has outline, back, and two optional tria meshes */
+
+typedef struct uiWidgetTrias {
+ int tot;
+
+ float vec[32][2];
+ int (*index)[3];
+
+} uiWidgetTrias;
+
+typedef struct uiWidgetColors {
+ float outline[3];
+ float inner[3];
+ float inner_sel[3];
+ float item[3];
+ float text[3];
+ float text_sel[3];
+ short shaded;
+ float shadetop, shadedown;
+
+} uiWidgetColors;
+
+typedef struct uiWidgetBase {
+
+ int totvert, halfwayvert;
+ float outer_v[64][2];
+ float inner_v[64][2];
+ float inner_uv[64][2];
+
+ uiWidgetTrias tria1;
+ uiWidgetTrias tria2;
+
+} uiWidgetBase;
+
+
+static float cornervec[9][2]= {{0.0, 0.0}, {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169},
+{0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}, {1.0, 1.0}};
+
+static float jit[8][2]= {{0.468813 , -0.481430}, {-0.155755 , -0.352820},
+{0.219306 , -0.238501}, {-0.393286 , -0.110949}, {-0.024699 , 0.013908},
+{0.343805 , 0.147431}, {-0.272855 , 0.269918}, {0.095909 , 0.388710}};
+
+static float num_tria_vert[19][2]= {
+{0.382684, 0.923879}, {0.000001, 1.000000}, {-0.382683, 0.923880}, {-0.707107, 0.707107},
+{-0.923879, 0.382684}, {-1.000000, 0.000000}, {-0.923880, -0.382684}, {-0.707107, -0.707107},
+{-0.382683, -0.923880}, {0.000000, -1.000000}, {0.382684, -0.923880}, {0.707107, -0.707107},
+{0.923880, -0.382684}, {1.000000, -0.000000}, {0.923880, 0.382683}, {0.707107, 0.707107},
+{-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.729843, -0.008353}};
+
+static int num_tria_face[19][3]= {
+{13, 14, 18}, {17, 5, 6}, {12, 13, 18}, {17, 6, 7}, {15, 18, 14}, {16, 4, 5}, {16, 5, 17}, {18, 11, 12},
+{18, 17, 10}, {18, 10, 11}, {17, 9, 10}, {15, 0, 18}, {18, 0, 16}, {3, 4, 16}, {8, 9, 17}, {8, 17, 7},
+{2, 3, 16}, {1, 2, 16}, {16, 0, 1}};
+
+static float menu_tria_vert[6][2]= {
+{-0.41, 0.16}, {0.41, 0.16}, {0, 0.82},
+{0, -0.82}, {-0.41, -0.16}, {0.41, -0.16}};
+
+static int menu_tria_face[2][3]= {{2, 0, 1}, {3, 5, 4}};
+
+static float check_tria_vert[6][2]= {
+{-0.578579, 0.253369}, {-0.392773, 0.412794}, {-0.004241, -0.328551},
+{-0.003001, 0.034320}, {1.055313, 0.864744}, {0.866408, 1.026895}};
+
+static int check_tria_face[4][3]= {
+{3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3}};
+
+
+
+static void widget_init(uiWidgetBase *wt)
+{
+ wt->totvert= wt->halfwayvert= 0;
+ wt->tria1.tot= 0;
+ wt->tria2.tot= 0;
+}
+
+
+static void round_box_edges(uiWidgetBase *wt, int roundboxtype, rcti *rect, float rad)
+{
+ float vec[9][2], veci[9][2];
+ float minx= rect->xmin, miny= rect->ymin, maxx= rect->xmax, maxy= rect->ymax;
+ float radi= rad - 1.0f; /* rad inner */
+ float minxi= minx + 1.0f; /* boundbox inner */
+ float maxxi= maxx - 1.0f;
+ float minyi= miny + 1.0f;
+ float maxyi= maxy - 1.0f;
+ float facxi= 1.0f/(maxxi-minxi); /* for uv */
+ float facyi= 1.0f/(maxyi-minyi);
+ int a, tot= 0;
+
+ /* mult */
+ for(a=0; a<9; a++) {
+ veci[a][0]= radi*cornervec[a][0];
+ veci[a][1]= radi*cornervec[a][1];
+ vec[a][0]= rad*cornervec[a][0];
+ vec[a][1]= rad*cornervec[a][1];
+ }
+
+ /* corner left-bottom */
+ if(roundboxtype & 8) {
+
+ for(a=0; a<9; a++, tot++) {
+ wt->inner_v[tot][0]= minxi+veci[a][1];
+ wt->inner_v[tot][1]= minyi+radi-veci[a][0];
+
+ wt->outer_v[tot][0]= minx+vec[a][1];
+ wt->outer_v[tot][1]= miny+rad-vec[a][0];
+
+ wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi);
+ wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi);
+ }
+ }
+ else {
+ wt->inner_v[tot][0]= minxi;
+ wt->inner_v[tot][1]= minyi;
+
+ wt->outer_v[tot][0]= minx;
+ wt->outer_v[tot][1]= miny;
+
+ wt->inner_uv[tot][0]= 0.0f;
+ wt->inner_uv[tot][1]= 0.0f;
+
+ tot++;
+ }
+
+ /* corner right-bottom */
+ if(roundboxtype & 4) {
+
+ for(a=0; a<9; a++, tot++) {
+ wt->inner_v[tot][0]= maxxi-radi+veci[a][0];
+ wt->inner_v[tot][1]= minyi+veci[a][1];
+
+ wt->outer_v[tot][0]= maxx-rad+vec[a][0];
+ wt->outer_v[tot][1]= miny+vec[a][1];
+
+ wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi);
+ wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi);
+ }
+ }
+ else {
+ wt->inner_v[tot][0]= maxxi;
+ wt->inner_v[tot][1]= minyi;
+
+ wt->outer_v[tot][0]= maxx;
+ wt->outer_v[tot][1]= miny;
+
+ wt->inner_uv[tot][0]= 1.0f;
+ wt->inner_uv[tot][1]= 0.0f;
+
+ tot++;
+ }
+
+ wt->halfwayvert= tot;
+
+ /* corner right-top */
+ if(roundboxtype & 2) {
+
+ for(a=0; a<9; a++, tot++) {
+ wt->inner_v[tot][0]= maxxi-veci[a][1];
+ wt->inner_v[tot][1]= maxyi-radi+veci[a][0];
+
+ wt->outer_v[tot][0]= maxx-vec[a][1];
+ wt->outer_v[tot][1]= maxy-rad+vec[a][0];
+
+ wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi);
+ wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi);
+ }
+ }
+ else {
+ wt->inner_v[tot][0]= maxxi;
+ wt->inner_v[tot][1]= maxyi;
+
+ wt->outer_v[tot][0]= maxx;
+ wt->outer_v[tot][1]= maxy;
+
+ wt->inner_uv[tot][0]= 1.0f;
+ wt->inner_uv[tot][1]= 1.0f;
+
+ tot++;
+ }
+
+ /* corner left-top */
+ if(roundboxtype & 1) {
+
+ for(a=0; a<9; a++, tot++) {
+ wt->inner_v[tot][0]= minxi+radi-veci[a][0];
+ wt->inner_v[tot][1]= maxyi-veci[a][1];
+
+ wt->outer_v[tot][0]= minx+rad-vec[a][0];
+ wt->outer_v[tot][1]= maxy-vec[a][1];
+
+ wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi);
+ wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi);
+ }
+
+ }
+ else {
+
+ wt->inner_v[tot][0]= minxi;
+ wt->inner_v[tot][1]= maxyi;
+
+ wt->outer_v[tot][0]= minx;
+ wt->outer_v[tot][1]= maxy;
+
+ wt->inner_uv[tot][0]= 0.0f;
+ wt->inner_uv[tot][1]= 1.0f;
+
+ tot++;
+ }
+
+ wt->totvert= tot;
+}
+
+/* based on button rect, return scaled array of triangles */
+static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, char where)
+{
+ float centx, centy, size;
+ int a;
+
+ /* center position and size */
+ centx= (float)rect->xmin + 0.5f*(rect->ymax-rect->ymin);
+ centy= (float)rect->ymin + 0.5f*(rect->ymax-rect->ymin);
+ size= -0.5f*triasize*(rect->ymax-rect->ymin);
+
+ if(where=='r') {
+ centx= (float)rect->xmax - 0.5f*(rect->ymax-rect->ymin);
+ size= -size;
+ }
+
+ for(a=0; a<19; a++) {
+ tria->vec[a][0]= size*num_tria_vert[a][0] + centx;
+ tria->vec[a][1]= size*num_tria_vert[a][1] + centy;
+ }
+
+ tria->tot= 19;
+ tria->index= num_tria_face;
+}
+
+static void widget_trias_draw(uiWidgetTrias *tria)
+{
+ int a;
+
+ glBegin(GL_TRIANGLES);
+ for(a=0; a<tria->tot; a++) {
+ glVertex2fv(tria->vec[ tria->index[a][0] ]);
+ glVertex2fv(tria->vec[ tria->index[a][1] ]);
+ glVertex2fv(tria->vec[ tria->index[a][2] ]);
+ }
+ glEnd();
+
+}
+
+static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect)
+{
+ float centx, centy, size;
+ int a;
+
+ /* center position and size */
+ centx= rect->xmax - 0.5f*(rect->ymax-rect->ymin);
+ centy= rect->ymin + 0.5f*(rect->ymax-rect->ymin);
+ size= 0.4f*(rect->ymax-rect->ymin);
+
+ for(a=0; a<6; a++) {
+ tria->vec[a][0]= size*menu_tria_vert[a][0] + centx;
+ tria->vec[a][1]= size*menu_tria_vert[a][1] + centy;
+ }
+
+ tria->tot= 2;
+ tria->index= menu_tria_face;
+}
+
+static void widget_check_trias(uiWidgetTrias *tria, rcti *rect)
+{
+ float centx, centy, size;
+ int a;
+
+ /* center position and size */
+ centx= rect->xmin + 0.5f*(rect->ymax-rect->ymin);
+ centy= rect->ymin + 0.5f*(rect->ymax-rect->ymin);
+ size= 0.5f*(rect->ymax-rect->ymin);
+
+ for(a=0; a<6; a++) {
+ tria->vec[a][0]= size*check_tria_vert[a][0] + centx;
+ tria->vec[a][1]= size*check_tria_vert[a][1] + centy;
+ }
+
+ tria->tot= 4;
+ tria->index= check_tria_face;
+}
+
+
+/* prepares shade colors */
+static void shadecolors(float *coltop, float *coldown, float *color, float shadetop, float shadedown)
+{
+ float hue, sat, val, valshade;
+
+ rgb_to_hsv(color[0], color[1], color[2], &hue, &sat, &val);
+
+ valshade= CLAMPIS(val+shadetop, 0.0f, 1.0f);
+ hsv_to_rgb(hue, sat, valshade, coltop, coltop+1, coltop+2);
+
+ valshade= CLAMPIS(val+shadedown, 0.0f, 1.0f);
+ hsv_to_rgb(hue, sat, valshade, coldown, coldown+1, coldown+2);
+}
+
+static void round_box_shade_col(float *col1, float *col2, float fac)
+{
+ float col[4];
+
+ col[0]= (fac*col1[0] + (1.0-fac)*col2[0]);
+ col[1]= (fac*col1[1] + (1.0-fac)*col2[1]);
+ col[2]= (fac*col1[2] + (1.0-fac)*col2[2]);
+ col[3]= 1;
+
+ glColor4fv(col);
+}
+
+static void widget_draw(uiWidgetBase *wt, uiWidgetColors *wcol, int state)
+{
+ float *inner= wcol->inner;
+ int j, a;
+
+ if(state & UI_SELECT)
+ inner= wcol->inner_sel;
+
+ glEnable(GL_BLEND);
+
+ /* backdrop non AA */
+ if(wcol->shaded==0) {
+ /* filled center, solid */
+ glColor3fv(inner);
+ glBegin(GL_POLYGON);
+ for(a=0; a<wt->totvert; a++)
+ glVertex2fv(wt->inner_v[a]);
+ glEnd();
+ }
+ else {
+ float col1[3], col2[3];
+
+ shadecolors(col1, col2, inner, wcol->shadetop, wcol->shadedown);
+
+ glShadeModel(GL_SMOOTH);
+ glBegin(GL_POLYGON);
+ for(a=0; a<wt->totvert; a++) {
+ round_box_shade_col(col1, col2, wt->inner_uv[a][1]);
+ glVertex2fv(wt->inner_v[a]);
+ }
+ glEnd();
+ glShadeModel(GL_FLAT);
+ }
+
+ /* for each AA step */
+ for(j=0; j<8; j++) {
+ glTranslatef(1.0*jit[j][0], 1.0*jit[j][1], 0.0f);
+
+ /* outline */
+ glColor4f(wcol->outline[0], wcol->outline[1], wcol->outline[0], 0.125);
+ glBegin(GL_QUAD_STRIP);
+ for(a=0; a<wt->totvert; a++) {
+ glVertex2fv(wt->outer_v[a]);
+ glVertex2fv(wt->inner_v[a]);
+ }
+ glVertex2fv(wt->outer_v[0]);
+ glVertex2fv(wt->inner_v[0]);
+ glEnd();
+
+ /* emboss bottom shadow */
+ glColor4f(1.0f, 1.0f, 1.0f, 0.02f);
+ glBegin(GL_QUAD_STRIP);
+ for(a=0; a<wt->halfwayvert; a++) {
+ glVertex2fv(wt->outer_v[a]);
+ glVertex2f(wt->outer_v[a][0], wt->outer_v[a][1]-1.0f);
+ }
+ glEnd();
+
+ glTranslatef(-1.0*jit[j][0], -1.0*jit[j][1], 0.0f);
+ }
+
+ /* decoration */
+ if(wt->tria1.tot || wt->tria2.tot) {
+ /* for each AA step */
+ for(j=0; j<8; j++) {
+ glTranslatef(1.0*jit[j][0], 1.0*jit[j][1], 0.0f);
+
+ if(wt->tria1.tot) {
+ glColor4f(wcol->item[0], wcol->item[1], wcol->item[2], 0.125);
+ widget_trias_draw(&wt->tria1);
+ }
+ if(wt->tria2.tot) {
+ glColor4f(wcol->item[0], wcol->item[1], wcol->item[2], 0.125);
+ widget_trias_draw(&wt->tria2);
+ }
+
+ glTranslatef(-1.0*jit[j][0], -1.0*jit[j][1], 0.0f);
+ }
+ }
+
+ glDisable(GL_BLEND);
+
+}
+
+/* *********************** text/icon ************************************** */
+
+static void widget_draw_text(uiBut *but, float x, float y)
+{
+ int transopts;
+ int len;
+ char *cpoin;
+
+ ui_rasterpos_safe(x, y, but->aspect);
+ if(but->type==IDPOIN) transopts= 0; // no translation, of course!
+ else transopts= ui_translate_buttons();
+
+ /* cut string in 2 parts */
+ cpoin= strchr(but->drawstr, '|');
+ if(cpoin) *cpoin= 0;
+
+#ifdef INTERNATIONAL
+ if (but->type == FTPREVIEW)
+ FTF_DrawNewFontString (but->drawstr+but->ofs, FTF_INPUT_UTF8);
+ else
+ UI_DrawString(but->font, but->drawstr+but->ofs, transopts);
+#else
+ UI_DrawString(but->font, but->drawstr+but->ofs, transopts);
+#endif
+
+ /* part text right aligned */
+ if(cpoin) {
+ len= UI_GetStringWidth(but->font, cpoin+1, ui_translate_buttons());
+ ui_rasterpos_safe( but->x2 - len*but->aspect-3, y, but->aspect);
+ UI_DrawString(but->font, cpoin+1, ui_translate_buttons());
+ *cpoin= '|';
+ }
+}
+
+/* draws text and icons for buttons */
+static void widget_draw_text_icon(uiBut *but, rcti *rect, float *col)
+{
+ float x, y;
+ short t, pos, ch;
+ short selsta_tmp, selend_tmp, selsta_draw, selwidth_draw;
+
+ if(but==NULL) return;
+
+ /* check for button text label */
+ if (but->type == ICONTEXTROW) {
+ ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0);
+ }
+ else {
+
+ /* text button selection and cursor */
+ if(but->editstr && but->pos != -1) {
+
+ if ((but->selend - but->selsta) > 0) {
+ /* text button selection */
+ selsta_tmp = but->selsta + strlen(but->str);
+ selend_tmp = but->selend + strlen(but->str);
+
+ if(but->drawstr[0]!=0) {
+ ch= but->drawstr[selsta_tmp];
+ but->drawstr[selsta_tmp]= 0;
+
+ selsta_draw = but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3;
+
+ but->drawstr[selsta_tmp]= ch;
+
+
+ ch= but->drawstr[selend_tmp];
+ but->drawstr[selend_tmp]= 0;
+
+ selwidth_draw = but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3;
+
+ but->drawstr[selend_tmp]= ch;
+
+ UI_ThemeColor(TH_BUT_TEXTFIELD_HI);
+ glRects(rect->xmin+selsta_draw+1, rect->ymin+2, rect->xmin+selwidth_draw+1, rect->ymax-2);
+ }
+ } else {
+ /* text cursor */
+ pos= but->pos+strlen(but->str);
+ if(pos >= but->ofs) {
+ if(but->drawstr[0]!=0) {
+ ch= but->drawstr[pos];
+ but->drawstr[pos]= 0;
+
+ t= but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3;
+
+ but->drawstr[pos]= ch;
+ }
+ else t= 3;
+
+ glColor3ub(255,0,0);
+ glRects(rect->xmin+t, rect->ymin+2, rect->xmin+t+2, rect->ymax-2);
+ }
+ }
+ }
+
+ if(but->type==BUT_TOGDUAL) {
+ int dualset= 0;
+ if(but->pointype==SHO)
+ dualset= BTST( *(((short *)but->poin)+1), but->bitnr);
+ else if(but->pointype==INT)
+ dualset= BTST( *(((int *)but->poin)+1), but->bitnr);
+
+ ui_draw_icon(but, ICON_DOT, dualset?0:-100);
+ }
+
+ if(but->drawstr[0]!=0) {
+
+ /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
+ and offset the text label to accomodate it */
+
+ if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) )
+ {
+ ui_draw_icon(but, but->icon, 0);
+
+ if(but->editstr || (but->flag & UI_TEXT_LEFT)) x= rect->xmin + but->aspect*UI_icon_get_width(but->icon)+5.0;
+ else x= (rect->xmin+rect->xmax-but->strwidth+1)/2.0;
+ }
+ else
+ {
+ if(but->editstr || (but->flag & UI_TEXT_LEFT))
+ x= rect->xmin+4.0;
+ else if ELEM3(but->type, TOG, TOGN, TOG3)
+ x= rect->xmin+28.0; /* offset for checkmark */
+ else
+ x= (rect->xmin+rect->xmax-but->strwidth+1)/2.0;
+ }
+
+ /* position and draw */
+ y = (rect->ymin+rect->ymax- 9.0)/2.0;
+
+ glColor3fv(col);
+ widget_draw_text(but, x, y);
+
+ }
+ /* if there's no text label, then check to see if there's an icon only and draw it */
+ else if( but->flag & UI_HAS_ICON ) {
+ ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0);
+ }
+ }
+}
+
+
+
+/* *********************** widget types ************************************* */
+
+/*
+ float outline[3];
+ float inner[3];
+ float select[3];
+ float item[3];
+ short shaded;
+ float shadetop, shadedown;
+*/
+
+static struct uiWidgetColors wcol_num= {
+ {0.1f, 0.1f, 0.1f},
+ {0.7f, 0.7f, 0.7f},
+ {0.6f, 0.6f, 0.6f},
+ {0.35f, 0.35f, 0.35f},
+
+ {0.0f, 0.0f, 0.0f},
+ {1.0f, 1.0f, 1.0f},
+
+ 1,
+ -0.08f, 0.0f
+};
+
+static struct uiWidgetColors wcol_text= {
+ {0.1f, 0.1f, 0.1f},
+ {0.6f, 0.6f, 0.6f},
+ {0.6f, 0.6f, 0.6f},
+ {0.35f, 0.35f, 0.35f},
+
+ {0.0f, 0.0f, 0.0f},
+ {1.0f, 1.0f, 1.0f},
+
+ 1,
+ 0.0f, 0.1f
+};
+
+static struct uiWidgetColors wcol_menu= {
+ {0.0f, 0.0f, 0.0f},
+ {0.25f, 0.25f, 0.25f},
+ {0.25f, 0.25f, 0.25f},
+ {1.0f, 1.0f, 1.0f},
+
+ {1.0f, 1.0f, 1.0f},
+ {0.0f, 0.0f, 0.0f},
+
+ 1,
+ 0.1f, -0.08f
+};
+
+static struct uiWidgetColors wcol_row= {
+ {0.0f, 0.0f, 0.0f},
+ {0.25f, 0.25f, 0.25f},
+ {0.34f, 0.5f, 0.76f},
+ {1.0f, 1.0f, 1.0f},
+
+ {1.0f, 1.0f, 1.0f},
+ {0.0f, 0.0f, 0.0f},
+
+ 1,
+ 0.1f, -0.1f
+};
+
+static struct uiWidgetColors wcol_regular= {
+ {0.1f, 0.1f, 0.1f},
+ {0.6f, 0.6f, 0.6f},
+ {0.4f, 0.4f, 0.4f},
+ {0.1f, 0.1f, 0.1f},
+
+ {0.0f, 0.0f, 0.0f},
+ {1.0f, 1.0f, 1.0f},
+
+ 0,
+ 0.0f, 0.0f
+};
+
+static struct uiWidgetColors wcol_regular2= {
+ {0.1f, 0.1f, 0.1f},
+ {0.6f, 0.6f, 0.6f},
+ {0.4f, 0.4f, 0.4f},
+ {0.1f, 0.1f, 0.1f},
+
+ {0.0f, 0.0f, 0.0f},
+ {1.0f, 1.0f, 1.0f},
+
+ 1,
+ 0.1f, -0.1f
+};
+
+
+static void widget_numbut(uiBut *but, rcti *rect, int state, int roundboxtype)
+{
+ uiWidgetBase wt;
+
+ widget_init(&wt);
+
+ /* fully rounded */
+ round_box_edges(&wt, roundboxtype, rect, 0.5f*(rect->ymax - rect->ymin));
+
+ /* decoration */
+ widget_num_tria(&wt.tria1, rect, 0.6f, 0);
+ widget_num_tria(&wt.tria2, rect, 0.6f, 'r');
+
+ widget_draw(&wt, &wcol_num, state);
+
+ if(state & UI_SELECT)
+ widget_draw_text_icon(but, rect, wcol_num.text_sel);
+ else
+ widget_draw_text_icon(but, rect, wcol_num.text);
+}
+
+static void widget_textbut(uiBut *but, rcti *rect, int state, int roundboxtype)
+{
+ uiWidgetBase wt;
+
+ widget_init(&wt);
+
+ /* half rounded */
+ round_box_edges(&wt, roundboxtype, rect, 4.0f);
+
+ /* XXX button state */
+ widget_draw(&wt, &wcol_text, state);
+
+ widget_draw_text_icon(but, rect, wcol_text.text);
+}
+
+
+static void widget_menubut(uiBut *but, rcti *rect, int state, int roundboxtype)
+{
+ uiWidgetBase wt;
+
+ widget_init(&wt);
+
+ /* half rounded */
+ round_box_edges(&wt, roundboxtype, rect, 4.0f);
+
+ /* XXX button state */
+
+ /* decoration */
+ widget_menu_trias(&wt.tria1, rect);
+
+ widget_draw(&wt, &wcol_menu, state);
+
+ widget_draw_text_icon(but, rect, wcol_menu.text);
+}
+
+static void widget_togbut(uiBut *but, rcti *rect, int state, int roundboxtype)
+{
+ uiWidgetBase wt;
+ rcti recttemp= *rect;
+ int delta;
+
+ widget_init(&wt);
+
+ /* square */
+ recttemp.xmax= recttemp.xmin + (recttemp.ymax-recttemp.ymin);
+
+ /* smaller */
+ delta= 1 + (recttemp.ymax-recttemp.ymin)/8;
+ recttemp.xmin+= delta;
+ recttemp.ymin+= delta;
+ recttemp.xmax-= delta;
+ recttemp.ymax-= delta;
+
+ /* half rounded */
+ round_box_edges(&wt, roundboxtype, &recttemp, 4.0f);
+
+ /* button state */
+
+ /* decoration */
+ if(state & UI_SELECT) {
+ widget_check_trias(&wt.tria1, &recttemp);
+ }
+
+ widget_draw(&wt, &wcol_menu, state);
+
+ if(state & UI_SELECT)
+ widget_draw_text_icon(but, rect, wcol_menu.text);
+ else
+ widget_draw_text_icon(but, rect, wcol_menu.text_sel);
+}
+
+
+static void widget_rowbut(uiBut *but, rcti *rect, int state, int roundboxtype)
+{
+ uiWidgetBase wt;
+
+ widget_init(&wt);
+
+ /* half rounded */
+ round_box_edges(&wt, roundboxtype, rect, 4.0f);
+
+ widget_draw(&wt, &wcol_row, state);
+
+ widget_draw_text_icon(but, rect, wcol_row.text);
+}
+
+static void widget_but(uiBut *but, rcti *rect, int state, int roundboxtype)
+{
+ uiWidgetBase wt;
+
+ widget_init(&wt);
+
+ /* half rounded */
+ round_box_edges(&wt, roundboxtype, rect, 4.0f);
+
+ widget_draw(&wt, &wcol_regular, state);
+
+ widget_draw_text_icon(but, rect, wcol_regular.text);
+}
+
+static void widget_roundbut(uiBut *but, rcti *rect, int state, int roundboxtype)
+{
+ uiWidgetBase wt;
+
+ widget_init(&wt);
+
+ /* fully rounded */
+ round_box_edges(&wt, roundboxtype, rect, 0.5f*(rect->ymax - rect->ymin));
+
+ widget_num_tria(&wt.tria1, rect, 0.6f, 0);
+
+ widget_draw(&wt, &wcol_regular2, state);
+
+ widget_draw_text_icon(but, rect, wcol_regular2.text);
+
+}
+
+/* test function only */
+void drawnewstuff()
+{
+ rcti rect;
+
+ rect.xmin= 10; rect.xmax= 10+100;
+ rect.ymin= -30; rect.ymax= -30+18;
+ widget_numbut(NULL, &rect, 0, 15);
+
+ rect.xmin= 120; rect.xmax= 120+100;
+ rect.ymin= -30; rect.ymax= -30+20;
+ widget_numbut(NULL, &rect, 0, 15);
+
+ rect.xmin= 10; rect.xmax= 10+100;
+ rect.ymin= -60; rect.ymax= -60+20;
+ widget_menubut(NULL, &rect, 0, 15);
+
+ rect.xmin= 120; rect.xmax= 120+100;
+ widget_but(NULL, &rect, 0, 15);
+
+ rect.xmin= 10; rect.xmax= 10+100;
+ rect.ymin= -90; rect.ymax= -90+20;
+ widget_rowbut(NULL, &rect, 1, 9);
+
+ rect.xmin= 109; rect.xmax= 110+100;
+ rect.ymin= -90; rect.ymax= -90+20;
+ widget_rowbut(NULL, &rect, 0, 6);
+
+ rect.xmin= 240; rect.xmax= 240+30;
+ rect.ymin= -90; rect.ymax= -90+30;
+ widget_roundbut(NULL, &rect, 0, 15);
+}
+
+/* ************ new color and style definition ********************* */
+/*
+
+- minimum width definition?
+
+- Types
+ * Icon toggle button
+ * Row button (exclusive "enum" values)
+ * Option button (also "bit flags")
+ * Tool/Operator button
+ * Number button
+ * Number slider
+
+ * Text string button (to rename data)
+ * File name button (separate design?)
+ * Linkage "Library" button (Object, Material, Parent, etc)
+ * Linkage data name button (Bone, Vgroup)
+
+ * Popup settings button, with optional text, icon or both.
+ * Popup linkage button (Materials, Bones, etc)
+ * Pulldown menu button (to invoke pulldown)
+ * Pulldown menu item (and menu backdrop + title)
+
+ * Button-less icons (open-close triangle, delete cross, ...)
+ * Color picker Swatch
+ * Color picker fields
+ * Normal button (rotatable sphere)
+
+*/
+
+static int widget_roundbox_set(uiBut *but, rcti *rect)
+{
+ /* alignment */
+ if(but->flag & UI_BUT_ALIGN) {
+
+ if(but->flag & UI_BUT_ALIGN_TOP)
+ rect->ymax+= 1;
+ if(but->flag & UI_BUT_ALIGN_LEFT)
+ rect->xmin-= 1;
+
+ switch(but->flag & UI_BUT_ALIGN) {
+ case UI_BUT_ALIGN_TOP:
+ return (12);
+ break;
+ case UI_BUT_ALIGN_DOWN:
+ return (3);
+ break;
+ case UI_BUT_ALIGN_LEFT:
+ return (6);
+ break;
+ case UI_BUT_ALIGN_RIGHT:
+ return (9);
+ break;
+
+ case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
+ return (1);
+ break;
+ case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
+ return (2);
+ break;
+ case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
+ return (8);
+ break;
+ case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
+ return (4);
+ break;
+
+ default:
+ return (0);
+ break;
+ }
+ }
+ return 15;
+}
+
+
+/* widget classification
+
+- state:
+ UI_MOUSE_OVER: on mouse over
+ UI_ACTIVE: while using it
+ UI_SELECT: internal state (toggle, row)
+
+- drawtype
+ CUSTOM: no widget class, entirely free within rect
+ WIDGET: part of the standard widget set
+
+- text placement, split?
+
+- widget color style hint
+ - outline
+ - interior col
+ - interior slider color?
+ - shade factors
+ - decoration color
+ - text colors
+
+- callbacks
+ - widget_draw()
+ - widget_text_icon()
+ -
+
+*/
+
+
+void ui_draw_but_new(ARegion *ar, uiBut *but)
+{
+ rcti rect;
+ int roundboxtype, state;
+
+ /* XXX project later */
+ rect.xmin= but->x1;
+ rect.xmax= but->x2;
+ rect.ymin= but->y1;
+ rect.ymax= but->y2;
+
+ roundboxtype= widget_roundbox_set(but, &rect);
+ state= but->flag;
+
+ switch (but->type) {
+ case LABEL:
+ widget_draw_text_icon(but, &rect, wcol_regular2.text);
+ break;
+ case NUM:
+ widget_numbut(but, &rect, state, roundboxtype);
+ break;
+ case ROW:
+ widget_rowbut(but, &rect, state, roundboxtype);
+ break;
+ case TEX:
+ widget_textbut(but, &rect, state, roundboxtype);
+ break;
+ case TOG:
+ case TOGN:
+ case TOG3:
+ if (!(state & UI_HAS_ICON))
+ widget_togbut(but, &rect, state, roundboxtype);
+ else
+ widget_but(but, &rect, state, roundboxtype);
+ break;
+ case MENU:
+ case BLOCK:
+ widget_menubut(but, &rect, state, roundboxtype);
+ break;
+
+ default:
+ widget_but(but, &rect, state, roundboxtype);
+ }
+
+}
+
+
+
+
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index d0d1da40a8f..039ebcc91f9 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -176,7 +176,7 @@ char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
case SPACE_TEXT:
ts= &btheme->text;
break;
- case SPACE_OOPS:
+ case SPACE_OUTLINER:
ts= &btheme->toops;
break;
case SPACE_SOUND:
@@ -363,14 +363,14 @@ void ui_theme_init_userdef(void)
UI_SetTheme(NULL); // make sure the global used in this file is set
- /* UI buttons (todo) */
- SETCOL(btheme->tui.outline, 0xA0,0xA0,0xA0, 255);
- SETCOL(btheme->tui.neutral, 180, 180, 180, 255);
- SETCOL(btheme->tui.action, 180, 180, 180, 255);
- SETCOL(btheme->tui.setting, 180, 180, 180, 255);
- SETCOL(btheme->tui.setting1, 180, 180, 180, 255);
- SETCOL(btheme->tui.setting2, 180, 180, 180, 255);
- SETCOL(btheme->tui.num, 143, 143, 143, 255);
+ /* UI buttons */
+ SETCOL(btheme->tui.outline, 130, 130, 130, 255);
+ SETCOL(btheme->tui.neutral, 165, 165, 165, 255);
+ SETCOL(btheme->tui.action, 165, 165, 165, 255);
+ SETCOL(btheme->tui.setting, 165, 165, 165, 255);
+ SETCOL(btheme->tui.setting1, 165, 165, 165, 255);
+ SETCOL(btheme->tui.setting2, 165, 165, 165, 255);
+ SETCOL(btheme->tui.num, 165, 165, 165, 255);
SETCOL(btheme->tui.textfield, 143, 142, 143, 255);
SETCOL(btheme->tui.textfield_hi,255, 151, 26, 255);
SETCOL(btheme->tui.popup, 174, 174, 174, 255);
@@ -378,9 +378,9 @@ void ui_theme_init_userdef(void)
SETCOL(btheme->tui.text, 0,0,0, 255);
SETCOL(btheme->tui.text_hi, 255, 255, 255, 255);
- SETCOL(btheme->tui.menu_back, 255, 255, 255, 235);
+ SETCOL(btheme->tui.menu_back, 220, 220, 220, 235);
SETCOL(btheme->tui.menu_item, 255, 255, 255, 20);
- SETCOL(btheme->tui.menu_hilite, 0x7F,0x7F,0x7F, 255);
+ SETCOL(btheme->tui.menu_hilite, 110, 110, 110, 255);
SETCOL(btheme->tui.menu_text, 0, 0, 0, 255);
SETCOL(btheme->tui.menu_text_hi, 255, 255, 255, 255);
@@ -391,7 +391,7 @@ void ui_theme_init_userdef(void)
SETCOL(btheme->tv3d.back, 90, 90, 90, 255);
SETCOL(btheme->tv3d.text, 0, 0, 0, 255);
SETCOL(btheme->tv3d.text_hi, 255, 255, 255, 255);
- SETCOL(btheme->tv3d.header, 195, 195, 195, 255);
+ SETCOL(btheme->tv3d.header, 185, 185, 185, 255);
SETCOL(btheme->tv3d.panel, 165, 165, 165, 127);
SETCOL(btheme->tv3d.shade1, 160, 160, 160, 100);
@@ -427,9 +427,9 @@ void ui_theme_init_userdef(void)
/* to have something initialized */
btheme->tbuts= btheme->tv3d;
- SETCOL(btheme->tbuts.back, 180, 180, 180, 255);
- SETCOL(btheme->tbuts.header, 195, 195, 195, 255);
- SETCOL(btheme->tbuts.panel, 255, 255, 255, 40);
+ SETCOL(btheme->tbuts.back, 0x82, 0x82, 0x82, 255);
+ SETCOL(btheme->tbuts.header, 185, 185, 185, 255);
+ SETCOL(btheme->tbuts.panel, 0x82, 0x82, 0x82, 255);
/* space ipo */
/* to have something initialized */
@@ -437,7 +437,7 @@ void ui_theme_init_userdef(void)
SETCOL(btheme->tipo.grid, 94, 94, 94, 255);
SETCOL(btheme->tipo.back, 120, 120, 120, 255);
- SETCOL(btheme->tipo.header, 195, 195, 195, 255);
+ SETCOL(btheme->tipo.header, 185, 185, 185, 255);
SETCOL(btheme->tipo.panel, 255, 255, 255, 150);
SETCOL(btheme->tipo.shade1, 172, 172, 172, 100);
SETCOL(btheme->tipo.shade2, 0x70, 0x70, 0x70, 100);
@@ -458,11 +458,18 @@ void ui_theme_init_userdef(void)
/* space file */
/* to have something initialized */
btheme->tfile= btheme->tv3d;
- SETCOL(btheme->tfile.back, 128, 128, 128, 255);
- SETCOL(btheme->tfile.text, 0, 0, 0, 255);
- SETCOL(btheme->tfile.text_hi, 255, 255, 255, 255);
- SETCOL(btheme->tfile.header, 182, 182, 182, 255);
- SETCOL(btheme->tfile.hilite, 0xA0, 0xA0, 0xD0, 255); // selected files
+ SETCOL(btheme->tfile.back, 90, 90, 90, 255);
+ SETCOL(btheme->tfile.text, 250, 250, 250, 255);
+ SETCOL(btheme->tfile.text_hi, 15, 15, 15, 255);
+ SETCOL(btheme->tfile.header, 185, 185, 185, 255);
+ SETCOL(btheme->tfile.panel, 180, 180, 180, 255); // bookmark/ui regions
+ SETCOL(btheme->tfile.active, 130, 130, 130, 255); // selected files
+ SETCOL(btheme->tfile.hilite, 255, 140, 25, 255); // selected files
+
+ SETCOL(btheme->tfile.grid, 250, 250, 250, 255);
+ SETCOL(btheme->tfile.image, 250, 250, 250, 255);
+ SETCOL(btheme->tfile.movie, 250, 250, 250, 255);
+ SETCOL(btheme->tfile.scene, 250, 250, 250, 255);
/* space action */
@@ -470,7 +477,7 @@ void ui_theme_init_userdef(void)
SETCOL(btheme->tact.back, 116, 116, 116, 255);
SETCOL(btheme->tact.text, 0, 0, 0, 255);
SETCOL(btheme->tact.text_hi, 255, 255, 255, 255);
- SETCOL(btheme->tact.header, 182, 182, 182, 255);
+ SETCOL(btheme->tact.header, 185, 185, 185, 255);
SETCOL(btheme->tact.grid, 94, 94, 94, 255);
SETCOL(btheme->tact.face, 166, 166, 166, 255); // RVK
SETCOL(btheme->tact.shade1, 172, 172, 172, 255); // sliders
@@ -489,7 +496,7 @@ void ui_theme_init_userdef(void)
SETCOL(btheme->tnla.back, 116, 116, 116, 255);
SETCOL(btheme->tnla.text, 0, 0, 0, 255);
SETCOL(btheme->tnla.text_hi, 255, 255, 255, 255);
- SETCOL(btheme->tnla.header, 182, 182, 182, 255);
+ SETCOL(btheme->tnla.header, 185, 185, 185, 255);
SETCOL(btheme->tnla.grid, 94, 94, 94, 255);
SETCOL(btheme->tnla.shade1, 172, 172, 172, 255); // sliders
SETCOL(btheme->tnla.shade2, 84, 44, 31, 100); // bar
@@ -526,7 +533,7 @@ void ui_theme_init_userdef(void)
SETCOL(btheme->timasel.active, 195, 195, 195, 255); /* active tile */
SETCOL(btheme->timasel.grid, 94, 94, 94, 255); /* active file text */
SETCOL(btheme->timasel.back, 110, 110, 110, 255);
- SETCOL(btheme->timasel.header, 195, 195, 195, 255);
+ SETCOL(btheme->timasel.header, 185, 185, 185, 255);
SETCOL(btheme->timasel.shade1, 94, 94, 94, 255); /* bar */
SETCOL(btheme->timasel.shade2, 172, 172, 172, 255); /* sliders */
SETCOL(btheme->timasel.hilite, 17, 27, 60, 100); /* selected tile */
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 693f540128f..d81d9eb79ca 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -249,9 +249,30 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
v2d->tot.ymin= -336.0f*((float)winy)/(float)winx;
v2d->cur= v2d->tot;
+ }
+ break;
+
+ /* panels view, with free/horizontal/vertical align */
+ case V2D_COMMONVIEW_PANELS_UI:
+ {
+ /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
+ v2d->keepzoom= (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPASPECT|V2D_KEEPZOOM);
+ v2d->minzoom= 0.5f;
+ v2d->maxzoom= 2.0f;
+
+ v2d->align= (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
+ v2d->keeptot= V2D_KEEPTOT_BOUNDS;
+ v2d->tot.xmin= 0.0f;
+ v2d->tot.xmax= winx;
+
+ v2d->tot.ymax= 0.0f;
+ v2d->tot.ymin= -winy;
+
+ v2d->cur= v2d->tot;
}
break;
+
/* other view types are completely defined using their own settings already */
default:
/* we don't do anything here, as settings should be fine, but just make sure that rect */
@@ -1468,10 +1489,14 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
/* draw numbers in the appropriate range */
if (dfac > 0.0f) {
for (; fac < hor.xmax; fac+=dfac, val+=grid->dx) {
- switch (vs->xunits) {
+ switch (vs->xunits) {
case V2D_UNIT_FRAMES: /* frames (as whole numbers)*/
scroll_printstr(vs, scene, fac, 3.0f+(float)(hor.ymin), val, grid->powerx, V2D_UNIT_FRAMES, 'h');
break;
+
+ case V2D_UNIT_FRAMESCALE: /* frames (not always as whole numbers) */
+ scroll_printstr(vs, scene, fac, 3.0f+(float)(hor.ymin), val, grid->powerx, V2D_UNIT_FRAMESCALE, 'h');
+ break;
case V2D_UNIT_SECONDS: /* seconds */
fac2= val/(float)FPS;
@@ -1490,7 +1515,7 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v
}
break;
- case V2D_UNIT_DEGREES: /* IPO-Editor for rotation IPO-Drivers */
+ case V2D_UNIT_DEGREES: /* Graph Editor for rotation Drivers */
/* HACK: although we're drawing horizontal, we make this draw as 'vertical', just to get degree signs */
scroll_printstr(vs, scene, fac, 3.0f+(float)(hor.ymin), val, grid->powerx, V2D_UNIT_DEGREES, 'v');
break;
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 95df3ef9c53..6da9512f9e0 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -239,11 +239,11 @@ static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-void View2D_OT_view_pan(wmOperatorType *ot)
+void VIEW2D_OT_pan(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Pan View";
- ot->idname= "View2D_OT_view_pan";
+ ot->idname= "VIEW2D_OT_pan";
/* api callbacks */
ot->exec= view_pan_exec;
@@ -287,11 +287,11 @@ static int view_scrollright_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void View2D_OT_view_scrollright(wmOperatorType *ot)
+void VIEW2D_OT_scroll_right(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Scroll Right";
- ot->idname= "View2D_OT_view_rightscroll";
+ ot->idname= "VIEW2D_OT_scroll_right";
/* api callbacks */
ot->exec= view_scrollright_exec;
@@ -333,11 +333,11 @@ static int view_scrollleft_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void View2D_OT_view_scrollleft(wmOperatorType *ot)
+void VIEW2D_OT_scroll_left(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Scroll Left";
- ot->idname= "View2D_OT_view_leftscroll";
+ ot->idname= "VIEW2D_OT_scroll_left";
/* api callbacks */
ot->exec= view_scrollleft_exec;
@@ -378,11 +378,11 @@ static int view_scrolldown_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void View2D_OT_view_scrolldown(wmOperatorType *ot)
+void VIEW2D_OT_scroll_down(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Scroll Down";
- ot->idname= "View2D_OT_view_downscroll";
+ ot->idname= "VIEW2D_OT_scroll_down";
/* api callbacks */
ot->exec= view_scrolldown_exec;
@@ -424,11 +424,11 @@ static int view_scrollup_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void View2D_OT_view_scrollup(wmOperatorType *ot)
+void VIEW2D_OT_scroll_up(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Scroll Up";
- ot->idname= "View2D_OT_view_upscroll";
+ ot->idname= "VIEW2D_OT_scroll_up";
/* api callbacks */
ot->exec= view_scrollup_exec;
@@ -524,11 +524,11 @@ static int view_zoomin_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void View2D_OT_view_zoomin(wmOperatorType *ot)
+void VIEW2D_OT_zoom_in(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Zoom In";
- ot->idname= "View2D_OT_view_zoomin";
+ ot->idname= "VIEW2D_OT_zoom_in";
/* api callbacks */
ot->exec= view_zoomin_exec;
@@ -560,11 +560,11 @@ static int view_zoomout_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void View2D_OT_view_zoomout(wmOperatorType *ot)
+void VIEW2D_OT_zoom_out(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Zoom Out";
- ot->idname= "View2D_OT_view_zoomout";
+ ot->idname= "VIEW2D_OT_zoom_out";
/* api callbacks */
ot->exec= view_zoomout_exec;
@@ -794,11 +794,11 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-void View2D_OT_view_zoom(wmOperatorType *ot)
+void VIEW2D_OT_zoom(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Zoom View";
- ot->idname= "View2D_OT_view_zoom";
+ ot->idname= "VIEW2D_OT_zoom";
/* api callbacks */
ot->exec= view_zoomdrag_exec;
@@ -892,11 +892,11 @@ static int view_borderzoom_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void View2D_OT_view_borderzoom(wmOperatorType *ot)
+void VIEW2D_OT_zoom_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Zoom to Border";
- ot->idname= "View2D_OT_view_borderzoom";
+ ot->idname= "VIEW2D_OT_zoom_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
@@ -1232,11 +1232,11 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* LMB-Drag in Scrollers - not repeatable operator! */
-void View2D_OT_scroller_activate(wmOperatorType *ot)
+void VIEW2D_OT_scroller_activate(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Scroller Activate";
- ot->idname= "View2D_OT_scroller_activate";
+ ot->idname= "VIEW2D_OT_scroller_activate";
/* api callbacks */
ot->invoke= scroller_activate_invoke;
@@ -1248,20 +1248,20 @@ void View2D_OT_scroller_activate(wmOperatorType *ot)
void ui_view2d_operatortypes(void)
{
- WM_operatortype_append(View2D_OT_view_pan);
+ WM_operatortype_append(VIEW2D_OT_pan);
- WM_operatortype_append(View2D_OT_view_scrollleft);
- WM_operatortype_append(View2D_OT_view_scrollright);
- WM_operatortype_append(View2D_OT_view_scrollup);
- WM_operatortype_append(View2D_OT_view_scrolldown);
+ WM_operatortype_append(VIEW2D_OT_scroll_left);
+ WM_operatortype_append(VIEW2D_OT_scroll_right);
+ WM_operatortype_append(VIEW2D_OT_scroll_up);
+ WM_operatortype_append(VIEW2D_OT_scroll_down);
- WM_operatortype_append(View2D_OT_view_zoomin);
- WM_operatortype_append(View2D_OT_view_zoomout);
+ WM_operatortype_append(VIEW2D_OT_zoom_in);
+ WM_operatortype_append(VIEW2D_OT_zoom_out);
- WM_operatortype_append(View2D_OT_view_zoom);
- WM_operatortype_append(View2D_OT_view_borderzoom);
+ WM_operatortype_append(VIEW2D_OT_zoom);
+ WM_operatortype_append(VIEW2D_OT_zoom_border);
- WM_operatortype_append(View2D_OT_scroller_activate);
+ WM_operatortype_append(VIEW2D_OT_scroller_activate);
}
void UI_view2d_keymap(wmWindowManager *wm)
@@ -1269,43 +1269,43 @@ void UI_view2d_keymap(wmWindowManager *wm)
ListBase *keymap= WM_keymap_listbase(wm, "View2D", 0, 0);
/* pan/scroll */
- WM_keymap_add_item(keymap, "View2D_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_rightscroll", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_leftscroll", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_right", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_left", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_downscroll", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_upscroll", WHEELUPMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, KM_SHIFT, 0);
/* zoom - single step */
- WM_keymap_add_item(keymap, "View2D_OT_view_zoomout", WHEELOUTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_zoomin", WHEELINMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_zoomout", PADMINUS, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_zoomin", PADPLUSKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_out", PADMINUS, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
/* scroll up/down - no modifiers, only when zoom fails */
/* these may fail if zoom is disallowed, in which case they should pass on event */
- WM_keymap_add_item(keymap, "View2D_OT_view_downscroll", WHEELDOWNMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_upscroll", WHEELUPMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, 0, 0);
/* these may be necessary if vertical scroll is disallowed */
- WM_keymap_add_item(keymap, "View2D_OT_view_rightscroll", WHEELDOWNMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_leftscroll", WHEELUPMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_right", WHEELDOWNMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_left", WHEELUPMOUSE, KM_PRESS, 0, 0);
/* zoom - drag */
- WM_keymap_add_item(keymap, "View2D_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
/* borderzoom - drag */
- WM_keymap_add_item(keymap, "View2D_OT_view_borderzoom", BKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0);
/* scrollers */
- WM_keymap_add_item(keymap, "View2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroller_activate", LEFTMOUSE, KM_PRESS, 0, 0);
/* Alternative keymap for buttons listview */
keymap= WM_keymap_listbase(wm, "View2D Buttons List", 0, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_downscroll", WHEELDOWNMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_upscroll", WHEELUPMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "View2D_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_down", WHEELDOWNMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_scroll_up", WHEELUPMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW2D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
}
diff --git a/source/blender/editors/mesh/editdeform.c b/source/blender/editors/mesh/editdeform.c
index 83668400708..1bf81f125fb 100644
--- a/source/blender/editors/mesh/editdeform.c
+++ b/source/blender/editors/mesh/editdeform.c
@@ -94,9 +94,10 @@ void sel_verts_defgroup (Object *obedit, int select)
case OB_MESH:
{
Mesh *me= ob->data;
-
- for (eve=me->edit_mesh->verts.first; eve; eve=eve->next){
- dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT);
+ EditMesh *em = EM_GetEditMesh(me);
+
+ for (eve=em->verts.first; eve; eve=eve->next){
+ dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
if (dvert && dvert->totweight){
for (i=0; i<dvert->totweight; i++){
@@ -110,8 +111,10 @@ void sel_verts_defgroup (Object *obedit, int select)
}
}
/* this has to be called, because this function operates on vertices only */
- if(select) EM_select_flush(me->edit_mesh); // vertices to edges/faces
- else EM_deselect_flush(me->edit_mesh);
+ if(select) EM_select_flush(em); // vertices to edges/faces
+ else EM_deselect_flush(em);
+
+ EM_EndEditMesh(em, me);
}
break;
case OB_LATTICE:
@@ -395,18 +398,19 @@ void del_defgroup (Object *ob)
/* Make sure that any verts with higher indices are adjusted accordingly */
if(ob->type==OB_MESH) {
Mesh *me= ob->data;
- EditMesh *em = me->edit_mesh;
+ EditMesh *em = EM_GetEditMesh(me);
EditVert *eve;
MDeformVert *dvert;
for (eve=em->verts.first; eve; eve=eve->next){
- dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT);
+ dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
if (dvert)
for (i=0; i<dvert->totweight; i++)
if (dvert->dw[i].def_nr > (ob->actdef-1))
dvert->dw[i].def_nr--;
}
+ EM_EndEditMesh(me, em);
}
else if(ob->type==OB_LATTICE) {
Lattice *lt= def_get_lattice(ob);
@@ -720,13 +724,14 @@ void assign_verts_defgroup (Object *obedit, float weight)
case OB_MESH:
{
Mesh *me= ob->data;
-
- if (!CustomData_has_layer(&me->edit_mesh->vdata, CD_MDEFORMVERT))
- EM_add_data_layer(me->edit_mesh, &me->edit_mesh->vdata, CD_MDEFORMVERT);
+ EditMesh *em = EM_GetEditMesh(me);
+
+ if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
+ EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT);
/* Go through the list of editverts and assign them */
- for (eve=me->edit_mesh->verts.first; eve; eve=eve->next){
- dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT);
+ for (eve=em->verts.first; eve; eve=eve->next){
+ dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
if (dvert && (eve->f & 1)){
done=0;
@@ -759,6 +764,7 @@ void assign_verts_defgroup (Object *obedit, float weight)
}
}
}
+ EM_EndEditMesh(me, em);
}
break;
case OB_LATTICE:
@@ -882,9 +888,10 @@ void remove_verts_defgroup (Object *obedit, int allverts)
case OB_MESH:
{
Mesh *me= ob->data;
-
- for (eve=me->edit_mesh->verts.first; eve; eve=eve->next){
- dvert= CustomData_em_get(&me->edit_mesh->vdata, eve->data, CD_MDEFORMVERT);
+ EditMesh *em = EM_GetEditMesh(me);
+
+ for (eve=em->verts.first; eve; eve=eve->next){
+ dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
if (dvert && dvert->dw && ((eve->f & 1) || allverts)){
for (i=0; i<dvert->totweight; i++){
@@ -911,6 +918,7 @@ void remove_verts_defgroup (Object *obedit, int allverts)
}
}
}
+ EM_EndEditMesh(me, em);
}
break;
case OB_LATTICE:
@@ -1007,11 +1015,11 @@ void vgroup_assign_with_menu(Scene *scene, Object *ob)
switch (mode) {
case 1: /* add to new group */
add_defgroup(ob);
- assign_verts_defgroup(ob, wp->weight);
+ assign_verts_defgroup(ob, wp->brush->alpha);
BIF_undo_push("Assign to vertex group");
break;
case 2: /* add to current group */
- assign_verts_defgroup(ob, wp->weight);
+ assign_verts_defgroup(ob, wp->brush->alpha);
BIF_undo_push("Assign to vertex group");
break;
case 3: /* remove from current group */
diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c
index 16f2ce7f6b7..e262f28a28e 100644
--- a/source/blender/editors/mesh/editmesh.c
+++ b/source/blender/editors/mesh/editmesh.c
@@ -1410,9 +1410,10 @@ static int mesh_separate_selected(Scene *scene, Base *editbase)
obedit= editbase->object;
me= obedit->data;
- em= me->edit_mesh;
+ em= EM_GetEditMesh(me);
if(me->key) {
error("Can't separate with vertex keys");
+ EM_EndEditMesh(me, em);
return 0;
}
@@ -1423,7 +1424,10 @@ static int mesh_separate_selected(Scene *scene, Base *editbase)
EM_stats_update(em);
- if(em->totvertsel==0) return 0;
+ if(em->totvertsel==0) {
+ EM_EndEditMesh(me, em);
+ return 0;
+ }
/* we are going to work as follows:
* 1. add a linked duplicate object: this will be the new one, we remember old pointer
@@ -1491,6 +1495,8 @@ static int mesh_separate_selected(Scene *scene, Base *editbase)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
DAG_object_flush_update(scene, basenew->object, OB_RECALC_DATA);
+ EM_EndEditMesh(me, em);
+
return 1;
}
@@ -1498,7 +1504,7 @@ static int mesh_separate_selected(Scene *scene, Base *editbase)
static int mesh_separate_material(Scene *scene, Base *editbase)
{
Mesh *me= editbase->object->data;
- EditMesh *em= me->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(me);
unsigned char curr_mat;
for (curr_mat = 1; curr_mat < editbase->object->totcol; ++curr_mat) {
@@ -1507,9 +1513,13 @@ static int mesh_separate_material(Scene *scene, Base *editbase)
/* select the material */
editmesh_select_by_material(em, curr_mat);
/* and now separate */
- if(0==mesh_separate_selected(scene, editbase))
+ if(0==mesh_separate_selected(scene, editbase)) {
+ EM_EndEditMesh(me, em);
return 0;
+ }
}
+
+ EM_EndEditMesh(me, em);
return 1;
}
@@ -1521,10 +1531,11 @@ static int mesh_separate_loose(Scene *scene, Base *editbase)
int doit= 1;
me= editbase->object->data;
- em= me->edit_mesh;
+ em= EM_GetEditMesh(me);
if(me->key) {
error("Can't separate with vertex keys");
+ EM_EndEditMesh(me, em);
return 0;
}
@@ -1540,6 +1551,8 @@ static int mesh_separate_loose(Scene *scene, Base *editbase)
/* and now separate */
doit= mesh_separate_selected(scene, editbase);
}
+
+ EM_EndEditMesh(me, em);
return 1;
}
@@ -1976,11 +1989,11 @@ void em_setup_viewcontext(bContext *C, ViewContext *vc)
}
}
-void EM_beginEditMesh(Object *ob)
+EditMesh *EM_GetEditMesh(Mesh *me)
{
- return ((Mesh *)ob->data)->edit_mesh;
+ return me->edit_mesh;
}
-void EM_endEditMesh(Object *ob, EditMesh *em)
+void EM_EndEditMesh(Mesh *me, EditMesh *em)
{
}
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 5b2f4d40e0a..b3ee7d6b2f1 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -82,18 +82,18 @@
/* XXX */
static float icovert[12][3] = {
- {0,0,-200},
- {144.72, -105.144,-89.443},
- {-55.277, -170.128,-89.443},
- {-178.885,0,-89.443},
- {-55.277,170.128,-89.443},
- {144.72,105.144,-89.443},
- {55.277,-170.128,89.443},
- {-144.72,-105.144,89.443},
- {-144.72,105.144,89.443},
- {55.277,170.128,89.443},
- {178.885,0,89.443},
- {0,0,200}
+ {0.0f,0.0f,-200.0f},
+ {144.72f, -105.144f,-89.443f},
+ {-55.277f, -170.128,-89.443f},
+ {-178.885f,0.0f,-89.443f},
+ {-55.277f,170.128f,-89.443f},
+ {144.72f,105.144f,-89.443f},
+ {55.277f,-170.128f,89.443f},
+ {-144.72f,-105.144f,89.443f},
+ {-144.72f,105.144f,89.443f},
+ {55.277f,170.128f,89.443f},
+ {178.885f,0.0f,89.443f},
+ {0.0f,0.0f,200.0f}
};
static short icoface[20][3] = {
{1,0,2},
@@ -341,23 +341,26 @@ int make_fgon(EditMesh *em, wmOperator *op, int make)
static int make_fgon_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
if( make_fgon(em, op, 1) ) {
DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
-void MESH_OT_make_fgon(struct wmOperatorType *ot)
+void MESH_OT_fgon_make(struct wmOperatorType *ot)
{
/* identifiers */
ot->name= "Make F-gon";
- ot->idname= "MESH_OT_make_fgon";
+ ot->idname= "MESH_OT_fgon_make";
/* api callbacks */
ot->exec= make_fgon_exec;
@@ -370,23 +373,26 @@ void MESH_OT_make_fgon(struct wmOperatorType *ot)
static int clear_fgon_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
if( make_fgon(em, op, 0) ) {
DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
-void MESH_OT_clear_fgon(struct wmOperatorType *ot)
+void MESH_OT_fgon_clear(struct wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear F-gon";
- ot->idname= "MESH_OT_clear_fgon";
+ ot->idname= "MESH_OT_fgon_clear";
/* api callbacks */
ot->exec= clear_fgon_exec;
@@ -819,7 +825,7 @@ static void addedgeface_mesh(EditMesh *em, wmOperator *op)
static int addedgeface_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
addedgeface_mesh(em, op);
@@ -827,6 +833,7 @@ static int addedgeface_mesh_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -1016,7 +1023,7 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se
* fill - end capping, and option to fill in circle
* cent[3] - center of the data.
* */
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
EditVert *eve, *v1=NULL, *v2, *v3, *v4=NULL, *vtop, *vdown;
float phi, phid, vec[3];
float q[4], cmat[3][3], nor[3]= {0.0, 0.0, 0.0};
@@ -1024,8 +1031,8 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se
EM_clear_flag_all(em, SELECT);
- phid= 2*M_PI/tot;
- phi= .25*M_PI;
+ phid= 2.0f*(float)M_PI/tot;
+ phi= .25f*(float)M_PI;
switch(type) {
case PRIM_GRID: /* grid */
@@ -1297,6 +1304,8 @@ static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int se
if(type!=0 && type!=13)
righthandfaces(em, 1); /* otherwise monkey has eyes in wrong direction */
+
+ EM_EndEditMesh(obedit->data, em);
}
diff --git a/source/blender/editors/mesh/editmesh_loop.c b/source/blender/editors/mesh/editmesh_loop.c
index 7afa5e1bceb..dcec73eebc2 100644
--- a/source/blender/editors/mesh/editmesh_loop.c
+++ b/source/blender/editors/mesh/editmesh_loop.c
@@ -782,8 +782,8 @@ static float bm_seg_intersect(BMEdge *e, CutCurve *c, int len, char mode,
static int knife_cut_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh, *em2;
BMesh *bm;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data)), *em2;
ARegion *ar= CTX_wm_region(C);
BMVert *bv;
BMIter iter;
@@ -798,6 +798,7 @@ static int knife_cut_exec(bContext *C, wmOperator *op)
if (EM_nvertices_selected(em) < 2) {
error("No edges are selected to operate on");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;;
}
@@ -810,8 +811,11 @@ static int knife_cut_exec(bContext *C, wmOperator *op)
}
RNA_END;
- if(len<2) return OPERATOR_CANCELLED;
-
+ if(len<2) {
+ EM_EndEditMesh(obedit->data, em);
+ return OPERATOR_CANCELLED;
+ }
+
bm = editmesh_to_bmesh(em);
/*the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer*/
@@ -872,7 +876,8 @@ static int knife_cut_exec(bContext *C, wmOperator *op)
MEM_freeN(em2);
BM_Free_Mesh(bm);
-
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c
index a77f6cbc538..dc081fe5a76 100644
--- a/source/blender/editors/mesh/editmesh_mods.c
+++ b/source/blender/editors/mesh/editmesh_mods.c
@@ -802,7 +802,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Mesh *me= obedit->data;
- EditMesh *em= me->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(me);
int selcount = similar_face_select__internal(scene, em, RNA_int_get(op->ptr, "type"));
@@ -810,17 +810,19 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
/* here was an edge-mode only select flush case, has to be generalized */
EM_selectmode_flush(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(me, em);
return OPERATOR_FINISHED;
}
+ EM_EndEditMesh(me, em);
return OPERATOR_CANCELLED;
}
-void MESH_OT_similar_face_select(wmOperatorType *ot)
+void MESH_OT_select_face_similar(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Similar Face Select";
- ot->idname= "MESH_OT_similar_face_select";
+ ot->idname= "MESH_OT_select_face_similar";
/* api callbacks */
ot->invoke= WM_menu_invoke;
@@ -1061,7 +1063,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Mesh *me= obedit->data;
- EditMesh *em= me->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(me);
int selcount = similar_edge_select__internal(scene, em, RNA_int_get(op->ptr, "type"));
@@ -1069,17 +1071,19 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
/* here was an edge-mode only select flush case, has to be generalized */
EM_selectmode_flush(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(me, em);
return OPERATOR_FINISHED;
}
+ EM_EndEditMesh(me, em);
return OPERATOR_CANCELLED;
}
-void MESH_OT_similar_edge_select(wmOperatorType *ot)
+void MESH_OT_select_edge_similar(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Similar Edge Select";
- ot->idname= "MESH_OT_similar_edge_select";
+ ot->idname= "MESH_OT_select_edge_similar";
/* api callbacks */
ot->invoke= WM_menu_invoke;
@@ -1114,7 +1118,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Mesh *me= obedit->data;
- EditMesh *em= me->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(me);
EditVert *eve, *base_eve=NULL;
unsigned int selcount=0; /* count how many new edges we select*/
@@ -1140,8 +1144,10 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
}
- if (!ok || !deselcount) /* no data selected OR no more data to select*/
+ if (!ok || !deselcount) { /* no data selected OR no more data to select*/
+ EM_EndEditMesh(me, em);
return 0;
+ }
if(RNA_enum_is_equal(op->ptr, "type", "FACE")) {
/* store face users */
@@ -1169,8 +1175,10 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
eve->f |= SELECT;
selcount++;
deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
+ if (!deselcount) {/*have we selected all posible faces?, if so return*/
+ EM_EndEditMesh(me, em);
return selcount;
+ }
}
}
}
@@ -1185,8 +1193,10 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
eve->f |= SELECT;
selcount++;
deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
+ if (!deselcount) {/*have we selected all posible faces?, if so return*/
+ EM_EndEditMesh(me, em);
return selcount;
+ }
}
}
}
@@ -1197,8 +1207,10 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
base_dvert= CustomData_em_get(&em->vdata, base_eve->data,
CD_MDEFORMVERT);
- if (!base_dvert || base_dvert->totweight == 0)
+ if (!base_dvert || base_dvert->totweight == 0) {
+ EM_EndEditMesh(me, em);
return selcount;
+ }
for(eve= em->verts.first; eve; eve= eve->next) {
dvert= CustomData_em_get(&em->vdata, eve->data,
@@ -1213,8 +1225,10 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
eve->f |= SELECT;
selcount++;
deselcount--;
- if (!deselcount) /*have we selected all posible faces?, if so return*/
+ if (!deselcount) { /*have we selected all posible faces?, if so return*/
+ EM_EndEditMesh(me, em);
return selcount;
+ }
break;
}
}
@@ -1227,16 +1241,19 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
if(selcount) {
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(me, em);
return OPERATOR_FINISHED;
}
+
+ EM_EndEditMesh(me, em);
return OPERATOR_CANCELLED;
}
-void MESH_OT_similar_vertex_select(wmOperatorType *ot)
+void MESH_OT_select_vertex_similar(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Similar Vertex Select";
- ot->idname= "MESH_OT_similar_vertex_select";
+ ot->idname= "MESH_OT_select_vertex_similar";
/* api callbacks */
ot->invoke= WM_menu_invoke;
@@ -1944,7 +1961,7 @@ static void edgering_select(EditMesh *em, EditEdge *startedge, int select)
static int loop_multiselect(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
EditEdge *eed;
EditEdge **edarray;
int edindex, edfirstcount;
@@ -1982,14 +1999,16 @@ static int loop_multiselect(bContext *C, wmOperator *op)
// if (EM_texFaceCheck())
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
-void MESH_OT_select_multi_loop(wmOperatorType *ot)
+void MESH_OT_select_loop_multi(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Multi Select Loops";
- ot->idname= "MESH_OT_select_multi_loop";
+ ot->idname= "MESH_OT_select_loop_multi";
/* api callbacks */
ot->exec= loop_multiselect;
@@ -2051,7 +2070,7 @@ static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring
}
}
-static int mesh_loop_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int mesh_select_loop_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
view3d_operator_needs_opengl(C);
@@ -2063,14 +2082,14 @@ static int mesh_loop_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
}
-void MESH_OT_loop_select(wmOperatorType *ot)
+void MESH_OT_select_loop(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Loop Select";
- ot->idname= "MESH_OT_loop_select";
+ ot->idname= "MESH_OT_select_loop";
/* api callbacks */
- ot->invoke= mesh_loop_select_invoke;
+ ot->invoke= mesh_select_loop_invoke;
ot->poll= ED_operator_editmesh;
/* flags */
@@ -2162,11 +2181,11 @@ static int mesh_shortest_path_select_invoke(bContext *C, wmOperator *op, wmEvent
return OPERATOR_FINISHED;
}
-void MESH_OT_shortest_path_select(wmOperatorType *ot)
+void MESH_OT_select_path_shortest(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Shortest Path Select";
- ot->idname= "MESH_OT_shortest_path_select";
+ ot->idname= "MESH_OT_select_path_shortest";
/* api callbacks */
ot->invoke= mesh_shortest_path_select_invoke;
@@ -2519,7 +2538,7 @@ void selectconnected_mesh_all(EditMesh *em)
static int select_linked_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(obedit->data);
if( RNA_boolean_get(op->ptr, "limit") ) {
ViewContext vc;
@@ -2530,6 +2549,8 @@ static int select_linked_exec(bContext *C, wmOperator *op)
selectconnected_mesh_all(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -2658,11 +2679,13 @@ void EM_hide_mesh(EditMesh *em, int swap)
static int hide_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
EM_hide_mesh(em, RNA_boolean_get(op->ptr, "unselected"));
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -2722,11 +2745,13 @@ void EM_reveal_mesh(EditMesh *em)
static int reveal_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
EM_reveal_mesh(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -2780,7 +2805,7 @@ static int select_sharp_edges_exec(bContext *C, wmOperator *op)
* small enough, select the edge
*/
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
EditEdge *eed;
EditFace *efa;
EditFace **efa1;
@@ -2792,6 +2817,7 @@ static int select_sharp_edges_exec(bContext *C, wmOperator *op)
if(em->selectmode==SCE_SELECT_FACE) {
BKE_report(op->reports, RPT_ERROR, "Doesn't work in face selection mode");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -2870,6 +2896,8 @@ static int select_sharp_edges_exec(bContext *C, wmOperator *op)
// if (EM_texFaceCheck())
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); //TODO is this needed ?
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -3030,11 +3058,13 @@ static void select_linked_flat_faces(EditMesh *em, wmOperator *op, float sharpne
static int select_linked_flat_faces_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
select_linked_flat_faces(em, op, RNA_float_get(op->ptr, "sharpness"));
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -3128,11 +3158,13 @@ void select_non_manifold(EditMesh *em, wmOperator *op )
static int select_non_manifold_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
select_non_manifold(em, op);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -3189,11 +3221,13 @@ void EM_select_swap(EditMesh *em) /* exported for UV */
static int select_invert_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
EM_select_swap(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -3224,20 +3258,21 @@ void EM_toggle_select_all(EditMesh *em) /* exported for UV */
static int toggle_select_all_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
EM_toggle_select_all(em);
- WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
-void MESH_OT_de_select_all(wmOperatorType *ot)
+void MESH_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select or Deselect All";
- ot->idname= "MESH_OT_de_select_all";
+ ot->idname= "MESH_OT_select_all_toggle";
/* api callbacks */
ot->exec= toggle_select_all_exec;
@@ -3377,13 +3412,15 @@ void EM_select_more(EditMesh *em)
static int select_more(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data)) ;
EM_select_more(em);
// if (EM_texFaceCheck(em))
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -3465,12 +3502,14 @@ void EM_select_less(EditMesh *em)
static int select_less(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
EM_select_less(em);
// if (EM_texFaceCheck(em))
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -3533,12 +3572,13 @@ static void selectrandom_mesh(EditMesh *em, float perc) /* randomly selects a us
static int mesh_select_random_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
selectrandom_mesh(em, RNA_float_get(op->ptr,"percent"));
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -3622,12 +3662,13 @@ static int mesh_selection_type_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
mesh_selection_type(CTX_data_scene(C), em, RNA_enum_get(op->ptr,"type"));
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -3647,7 +3688,7 @@ void MESH_OT_selection_type(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* props */
- RNA_def_enum(ot->srna, "type", prop_mesh_edit_types, 0, "Type", "Select the mesh selection type");
+ RNA_def_enum(ot->srna, "type", prop_mesh_edit_types, 0, "Type", "Set the mesh selection type");
}
/* ************************* SEAMS AND EDGES **************** */
@@ -3655,7 +3696,7 @@ void MESH_OT_selection_type(wmOperatorType *ot)
static int editmesh_mark_seam(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
Mesh *me= ((Mesh *)obedit->data);
EditEdge *eed;
int clear = RNA_boolean_get(op->ptr, "clear");
@@ -3686,6 +3727,7 @@ static int editmesh_mark_seam(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -3708,7 +3750,7 @@ void MESH_OT_mark_seam(wmOperatorType *ot)
static int editmesh_mark_sharp(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
Mesh *me= ((Mesh *)obedit->data);
int set = RNA_boolean_get(op->ptr, "set");
EditEdge *eed;
@@ -3734,6 +3776,7 @@ static int editmesh_mark_sharp(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -4128,7 +4171,7 @@ void righthandfaces(EditMesh *em, int select) /* makes faces righthand turning *
static int righthandfaces_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
/* 'standard' behaviour - check if selected, then apply relevant selection */
@@ -4136,6 +4179,8 @@ static int righthandfaces_exec(bContext *C, wmOperator *op)
righthandfaces(em, RNA_boolean_get(op->ptr, "inside"));
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); //TODO is this needed ?
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -4336,7 +4381,7 @@ static int smooth_vertex(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Mesh *me= obedit->data;
- EditMesh *em= me->edit_mesh;
+ EditMesh *em= me;
EditVert *eve, *eve_mir = NULL;
EditEdge *eed;
@@ -4345,7 +4390,10 @@ static int smooth_vertex(bContext *C, wmOperator *op)
int teller=0;
ModifierData *md= obedit->modifiers.first;
- if(em==NULL) return OPERATOR_CANCELLED;
+ if(em==NULL) {
+ EM_EndEditMesh(obedit->data, em);
+ return OPERATOR_CANCELLED;
+ }
/* count */
eve= em->verts.first;
@@ -4353,7 +4401,10 @@ static int smooth_vertex(bContext *C, wmOperator *op)
if(eve->f & SELECT) teller++;
eve= eve->next;
}
- if(teller==0) return OPERATOR_CANCELLED;
+ if(teller==0) {
+ EM_EndEditMesh(obedit->data, em);
+ return OPERATOR_CANCELLED;
+ }
adr=adror= (float *)MEM_callocN(3*sizeof(float *)*teller, "vertsmooth");
eve= em->verts.first;
@@ -4466,6 +4517,7 @@ static int smooth_vertex(bContext *C, wmOperator *op)
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -4590,12 +4642,13 @@ static int vertices_to_sphere_exec(bContext *C, wmOperator *op)
Object *obedit= CTX_data_edit_object(C);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
vertices_to_sphere(scene, v3d, obedit, em, RNA_float_get(op->ptr,"percent"));
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -4639,7 +4692,7 @@ void flipface(EditMesh *em, EditFace *efa)
static int flip_editnormals(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
EditFace *efa;
efa= em->faces.first;
@@ -4653,6 +4706,7 @@ static int flip_editnormals(bContext *C, wmOperator *op)
/* update vertex normals too */
recalc_editnormals(em);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 68a6a48a098..bfcbc01b8ed 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -488,7 +488,7 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(((Mesh *)obedit->data));
char msg[100];
int cnt = removedoublesflag(em,1,0,scene->toolsettings->doublimit);
@@ -501,14 +501,15 @@ static int removedoublesflag_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
-void MESH_OT_removedoublesflag(wmOperatorType *ot)
+void MESH_OT_remove_doubles(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Remove Doubles";
- ot->idname= "MESH_OT_removedoublesflag";
+ ot->idname= "MESH_OT_remove_doubles";
/* api callbacks */
ot->exec= removedoublesflag_exec;
@@ -704,7 +705,7 @@ void extrude_mesh(Object *obedit, EditMesh *em, wmOperator *op)
static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
extrude_mesh(obedit,em, op);
@@ -713,6 +714,7 @@ static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -720,12 +722,13 @@ static int mesh_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
static int mesh_extrude_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(obedit->data);
extrude_mesh(obedit,em, op);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -751,7 +754,7 @@ void MESH_OT_extrude(wmOperatorType *ot)
static int split_mesh(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
WM_cursor_wait(1);
@@ -766,14 +769,15 @@ static int split_mesh(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
-void MESH_OT_split_mesh(wmOperatorType *ot)
+void MESH_OT_split(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Split Mesh";
- ot->idname= "MESH_OT_split_mesh";
+ ot->idname= "MESH_OT_split";
/* api callbacks */
ot->exec= split_mesh;
@@ -787,8 +791,8 @@ void MESH_OT_split_mesh(wmOperatorType *ot)
static int extrude_repeat_mesh(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
-
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
+
RegionView3D *rv3d = CTX_wm_region_view3d(C);
int steps = RNA_int_get(op->ptr,"steps");
@@ -824,6 +828,7 @@ static int extrude_repeat_mesh(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -852,7 +857,7 @@ static int spin_mesh(bContext *C, float *dvec, int steps, float degr, int dupli
Object *obedit= CTX_data_edit_object(C);
View3D *v3d = CTX_wm_view3d(C);
Scene *scene = CTX_data_scene(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
RegionView3D *rv3d= CTX_wm_region_view3d(C);
EditVert *eve,*nextve;
float nor[3]= {0.0f, 0.0f, 0.0f};
@@ -935,6 +940,7 @@ static int spin_mesh(bContext *C, float *dvec, int steps, float degr, int dupli
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
}
+ EM_EndEditMesh(obedit->data, em);
return ok;
}
@@ -975,7 +981,7 @@ void MESH_OT_spin(wmOperatorType *ot)
static int screw_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
EditVert *eve,*v1=0,*v2=0;
EditEdge *eed;
float dvec[3], nor[3];
@@ -1011,6 +1017,7 @@ static int screw_mesh_exec(bContext *C, wmOperator *op)
}
if(v1==NULL || v2==NULL) {
BKE_report(op->reports, RPT_ERROR, "You have to select a string of connected vertices too");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -1029,13 +1036,16 @@ static int screw_mesh_exec(bContext *C, wmOperator *op)
if(spin_mesh(C, dvec, turns*steps, 360.0f*turns, 0)) {
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
else {
BKE_report(op->reports, RPT_ERROR, "No valid vertices are selected");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
+
+ EM_EndEditMesh(obedit->data, em);
}
void MESH_OT_screw(wmOperatorType *ot)
@@ -1102,29 +1112,13 @@ static void erase_vertices(EditMesh *em, ListBase *l)
}
}
-/* Note, these values must match delete_mesh() event values */
-static EnumPropertyItem prop_mesh_delete_types[] = {
- {10,"VERT", "Vertices", ""},
- {1, "EDGE", "Edges", ""},
- {2, "FACE", "Faces", ""},
- {3, "ALL", "All", ""},
- {4, "EDGE_FACE","Edges & Faces", ""},
- {5, "ONLY_FACE","Only Faces", ""},
- {6, "EDGE_LOOP","Edge Loop", ""},
- {7, "DISSOLVE","Dissolve Verts", ""},
- {0, NULL, NULL, NULL}
-};
-
-static int delete_mesh_exec(bContext *C, wmOperator *op)
+static int delete_mesh(Object *obedit, EditMesh *em, wmOperator *op, int event)
{
- Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
EditFace *efa, *nextvl;
EditVert *eve,*nextve;
EditEdge *eed,*nexted;
int count;
char *str="Erase";
- int event = RNA_enum_get(op->ptr, "type");
if(event<1) return;
@@ -1251,8 +1245,32 @@ static int delete_mesh_exec(bContext *C, wmOperator *op)
EM_fgon_flags(em); // redo flags and indices for fgons
+// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+}
+
+/* Note, these values must match delete_mesh() event values */
+static EnumPropertyItem prop_mesh_delete_types[] = {
+ {10,"VERT", "Vertices", ""},
+ {1, "EDGE", "Edges", ""},
+ {2, "FACE", "Faces", ""},
+ {3, "ALL", "All", ""},
+ {4, "EDGE_FACE","Edges & Faces", ""},
+ {5, "ONLY_FACE","Only Faces", ""},
+ {6, "EDGE_LOOP","Edge Loop", ""},
+ {7, "DISSOLVE","Dissolve Verts", ""},
+ {0, NULL, NULL, NULL}
+};
+
+static int delete_mesh_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit= CTX_data_edit_object(C);
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
+
+ delete_mesh(obedit, em, op, RNA_enum_get(op->ptr, "type"));
+
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -3621,7 +3639,7 @@ static void edge_rotate(EditMesh *em, wmOperator *op, EditEdge *eed,int dir)
static int edge_rotate_selected(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
int dir = RNA_int_get(op->ptr,"dir"); // dir == 2 when clockwise and ==1 for counter CW.
EditEdge *eed;
@@ -3660,6 +3678,7 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
else
{
BKE_report(op->reports, RPT_ERROR, "Select one edge or two adjacent faces");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
}
@@ -3675,6 +3694,7 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
else
{
BKE_report(op->reports, RPT_ERROR, "Select one edge or two adjacent faces");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -3686,16 +3706,16 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
-
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
-void MESH_OT_edge_rotate_selected(wmOperatorType *ot)
+void MESH_OT_edge_rotate(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Rotate Selected Edge";
- ot->idname= "MESH_OT_edge_rotate_selected";
+ ot->idname= "MESH_OT_edge_rotate";
/* api callbacks */
ot->exec= edge_rotate_selected;
@@ -4741,7 +4761,7 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
ARegion *ar= CTX_wm_region(C);
RegionView3D *rv3d= ar->regiondata;
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
EditVert *eve, *nextve;
EditEdge *eed, *seed= NULL;
EditFace *efa, *sefa= NULL;
@@ -4785,10 +4805,12 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
if(efa) {
BKE_report(op->reports, RPT_ERROR, "Can't perform ripping with faces selected this way");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
if(sefa==NULL) {
BKE_report(op->reports, RPT_ERROR, "No proper selection or faces included");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -4853,6 +4875,7 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
if(seed==NULL) { // never happens?
BKE_report(op->reports, RPT_ERROR, "No proper edge found to start");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -4942,6 +4965,7 @@ static int mesh_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
// scene->prop_mode = propmode;
// XXX scene->proportional = prop;
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -5880,7 +5904,7 @@ void pathselect(EditMesh *em, wmOperator *op)
static int region_to_loop(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
EditEdge *eed;
EditFace *efa;
@@ -5913,6 +5937,7 @@ static int region_to_loop(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6057,7 +6082,7 @@ static int loop_bisect(EditMesh *em, Collection *edgecollection){
static int loop_to_region(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
EditFace *efa;
@@ -6089,7 +6114,7 @@ static int loop_to_region(bContext *C, wmOperator *op)
// if (EM_texFaceCheck())
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6114,7 +6139,7 @@ void MESH_OT_loop_to_region(wmOperatorType *ot)
static int mesh_rotate_uvs(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
EditFace *efa;
short change = 0, ccw;
@@ -6124,6 +6149,7 @@ static int mesh_rotate_uvs(bContext *C, wmOperator *op)
if (!EM_texFaceCheck(em)) {
BKE_report(op->reports, RPT_ERROR, "mesh has no uv/image layers");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -6180,13 +6206,14 @@ static int mesh_rotate_uvs(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
}
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
static int mesh_mirror_uvs(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
EditFace *efa;
short change = 0, altaxis;
@@ -6196,6 +6223,7 @@ static int mesh_mirror_uvs(bContext *C, wmOperator *op)
if (!EM_texFaceCheck(em)) {
BKE_report(op->reports, RPT_ERROR, "mesh has no uv/image layers");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -6266,13 +6294,15 @@ static int mesh_mirror_uvs(bContext *C, wmOperator *op)
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
}
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
static int mesh_rotate_colors(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
EditFace *efa;
short change = 0, ccw;
@@ -6281,6 +6311,7 @@ static int mesh_rotate_colors(bContext *C, wmOperator *op)
if (!EM_vertColorCheck(em)) {
BKE_report(op->reports, RPT_ERROR, "mesh has no color layers");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -6320,6 +6351,7 @@ static int mesh_rotate_colors(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
}
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6327,7 +6359,7 @@ static int mesh_rotate_colors(bContext *C, wmOperator *op)
static int mesh_mirror_colors(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
EditFace *efa;
short change = 0, altaxis;
@@ -6336,6 +6368,7 @@ static int mesh_mirror_colors(bContext *C, wmOperator *op)
if (!EM_vertColorCheck(em)) {
BKE_report(op->reports, RPT_ERROR, "Mesh has no color layers");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -6374,6 +6407,7 @@ static int mesh_mirror_colors(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
}
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6437,12 +6471,13 @@ static int subdivide_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
BM_esubdivideflag_conv(obedit, em, 1, 0.0, scene->toolsettings->editbutflag, 1, 0);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6464,12 +6499,13 @@ static int subdivide_multi_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
BM_esubdivideflag_conv(obedit, em, 1, 0.0, scene->toolsettings->editbutflag, RNA_int_get(op->ptr,"number_cuts"), 0);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6494,12 +6530,13 @@ static int subdivide_multi_fractal_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
BM_esubdivideflag_conv(obedit, em, 1, -(RNA_float_get(op->ptr, "random_factor")/100), scene->toolsettings->editbutflag, RNA_int_get(op->ptr, "number_cuts"), 0);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6525,12 +6562,13 @@ static int subdivide_smooth_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
BM_esubdivideflag_conv(obedit, em, 1, 0.292f*RNA_float_get(op->ptr, "smoothness"), scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6865,13 +6903,14 @@ static void fill_mesh(EditMesh *em)
static int fill_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
fill_mesh(em);
DAG_object_flush_update(CTX_data_scene(C), obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6893,12 +6932,13 @@ void MESH_OT_fill(wmOperatorType *ot)
static int beauty_fill_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
beauty_fill(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6919,7 +6959,7 @@ void MESH_OT_beauty_fill(wmOperatorType *ot)
static int convert_quads_to_tris_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
//convert_to_triface(em,0);
if (!EDBM_CallOpf(em, op, "triangulate faces=%hf", BM_SELECT))
@@ -6927,6 +6967,7 @@ static int convert_quads_to_tris_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6947,12 +6988,13 @@ void MESH_OT_convert_quads_to_tris(wmOperatorType *ot)
static int convert_tris_to_quads_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
join_triangles(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6973,12 +7015,13 @@ void MESH_OT_convert_tris_to_quads(wmOperatorType *ot)
static int edge_flip_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
edge_flip(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -6999,19 +7042,20 @@ void MESH_OT_edge_flip(wmOperatorType *ot)
static int mesh_faces_shade_smooth_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
mesh_set_smooth_faces(em,1);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
void MESH_OT_faces_shade_smooth(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Flat Face Shading";
+ ot->name= "Smooth Face Shading";
ot->idname= "MESH_OT_faces_shade_smooth";
/* api callbacks */
@@ -7025,19 +7069,20 @@ void MESH_OT_faces_shade_smooth(wmOperatorType *ot)
static int mesh_faces_shade_solid_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
mesh_set_smooth_faces(em,0);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
void MESH_OT_faces_shade_solid(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Smooth Face Shading";
+ ot->name= "Flat Face Shading";
ot->idname= "MESH_OT_faces_shade_solid";
/* api callbacks */
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 1e07f5dff87..d618b524010 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -114,8 +114,8 @@ void MESH_OT_add_primitive_ico_sphere(struct wmOperatorType *ot);
void MESH_OT_dupli_extrude_cursor(struct wmOperatorType *ot);
void MESH_OT_add_edge_face(struct wmOperatorType *ot);
-void MESH_OT_make_fgon(struct wmOperatorType *ot);
-void MESH_OT_clear_fgon(struct wmOperatorType *ot);
+void MESH_OT_fgon_make(struct wmOperatorType *ot);
+void MESH_OT_fgon_clear(struct wmOperatorType *ot);
/* ******************* editmesh_lib.c */
void EM_stats_update(EditMesh *em);
@@ -173,8 +173,8 @@ extern struct EditFace *EM_face_from_faces(EditMesh *em, struct EditFace *efa1,
void MESH_OT_knife_cut(struct wmOperatorType *ot);
/* ******************* editmesh_mods.c */
-void MESH_OT_loop_select(struct wmOperatorType *ot);
-void MESH_OT_de_select_all(struct wmOperatorType *ot);
+void MESH_OT_select_loop(struct wmOperatorType *ot);
+void MESH_OT_select_all_toggle(struct wmOperatorType *ot);
void MESH_OT_bmesh_test(struct wmOperatorType *ot);
void MESH_OT_select_more(struct wmOperatorType *ot);
void MESH_OT_select_less(struct wmOperatorType *ot);
@@ -187,14 +187,14 @@ void MESH_OT_reveal(struct wmOperatorType *ot);
void MESH_OT_consistant_normals(struct wmOperatorType *ot);
void MESH_OT_select_linked_flat_faces(struct wmOperatorType *ot);
void MESH_OT_select_sharp_edges(struct wmOperatorType *ot);
-void MESH_OT_shortest_path_select(struct wmOperatorType *ot);
-void MESH_OT_similar_vertex_select(struct wmOperatorType *ot);
-void MESH_OT_similar_edge_select(struct wmOperatorType *ot);
-void MESH_OT_similar_face_select(struct wmOperatorType *ot);
+void MESH_OT_select_path_shortest(struct wmOperatorType *ot);
+void MESH_OT_select_vertex_similar(struct wmOperatorType *ot);
+void MESH_OT_select_edge_similar(struct wmOperatorType *ot);
+void MESH_OT_select_face_similar(struct wmOperatorType *ot);
void MESH_OT_select_random(struct wmOperatorType *ot);
void MESH_OT_vertices_to_sphere(struct wmOperatorType *ot);
void MESH_OT_selection_type(struct wmOperatorType *ot);
-void MESH_OT_select_multi_loop(struct wmOperatorType *ot);
+void MESH_OT_select_loop_multi(struct wmOperatorType *ot);
void MESH_OT_mark_seam(struct wmOperatorType *ot);
void MESH_OT_mark_sharp(struct wmOperatorType *ot);
void MESH_OT_smooth_vertex(struct wmOperatorType *ot);
@@ -232,12 +232,12 @@ int removedoublesflag(EditMesh *em, short flag, short automerge, float limit);
void esubdivideflag(Object *obedit, EditMesh *em, int flag, float rad, int beauty, int numcuts, int seltype);
int EdgeSlide(EditMesh *em, struct wmOperator *op, short immediate, float imperc);
-void MESH_OT_subdivs(struct wmOperatorType *ot);
void MESH_OT_subdivide(struct wmOperatorType *ot);
+void MESH_OT_subdivs(struct wmOperatorType *ot);
void MESH_OT_subdivide_multi(struct wmOperatorType *ot);
void MESH_OT_subdivide_multi_fractal(struct wmOperatorType *ot);
void MESH_OT_subdivide_smooth(struct wmOperatorType *ot);
-void MESH_OT_removedoublesflag(struct wmOperatorType *ot);
+void MESH_OT_remove_doubles(struct wmOperatorType *ot);
void MESH_OT_extrude(struct wmOperatorType *ot);
void MESH_OT_spin(struct wmOperatorType *ot);
void MESH_OT_screw(struct wmOperatorType *ot);
@@ -249,9 +249,9 @@ void MESH_OT_convert_tris_to_quads(struct wmOperatorType *ot);
void MESH_OT_edge_flip(struct wmOperatorType *ot);
void MESH_OT_faces_shade_smooth(struct wmOperatorType *ot);
void MESH_OT_faces_shade_solid(struct wmOperatorType *ot);
-void MESH_OT_split_mesh(struct wmOperatorType *ot);
+void MESH_OT_split(struct wmOperatorType *ot);
void MESH_OT_extrude_repeat(struct wmOperatorType *ot);
-void MESH_OT_edge_rotate_selected(struct wmOperatorType *ot);
+void MESH_OT_edge_rotate(struct wmOperatorType *ot);
void MESH_OT_loop_to_region(struct wmOperatorType *ot);
void MESH_OT_region_to_loop(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 05cc377c6f3..ebcd82c6a70 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -65,10 +65,11 @@
static int mesh_add_duplicate_exec(bContext *C, wmOperator *op)
{
Object *ob= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh *)ob->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(ob->data);
adduplicateflag(em, SELECT);
+ EM_EndEditMesh(ob->data, em);
return OPERATOR_FINISHED;
}
@@ -84,12 +85,12 @@ static int mesh_add_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event
return OPERATOR_FINISHED;
}
-static void MESH_OT_add_duplicate(wmOperatorType *ot)
+static void MESH_OT_duplicate_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Duplicate";
- ot->idname= "MESH_OT_add_duplicate";
+ ot->idname= "MESH_OT_duplicate_add";
/* api callbacks */
ot->invoke= mesh_add_duplicate_invoke;
@@ -106,7 +107,7 @@ static void MESH_OT_add_duplicate(wmOperatorType *ot)
void ED_operatortypes_mesh(void)
{
- WM_operatortype_append(MESH_OT_de_select_all);
+ WM_operatortype_append(MESH_OT_select_all_toggle);
WM_operatortype_append(MESH_OT_select_more);
WM_operatortype_append(MESH_OT_select_less);
WM_operatortype_append(MESH_OT_select_invert);
@@ -135,18 +136,18 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_add_primitive_monkey);
WM_operatortype_append(MESH_OT_add_primitive_uv_sphere);
WM_operatortype_append(MESH_OT_add_primitive_ico_sphere);
- WM_operatortype_append(MESH_OT_clear_fgon);
- WM_operatortype_append(MESH_OT_make_fgon);
- WM_operatortype_append(MESH_OT_add_duplicate);
- WM_operatortype_append(MESH_OT_removedoublesflag);
+ WM_operatortype_append(MESH_OT_fgon_clear);
+ WM_operatortype_append(MESH_OT_fgon_make);
+ WM_operatortype_append(MESH_OT_duplicate_add);
+ WM_operatortype_append(MESH_OT_remove_doubles);
WM_operatortype_append(MESH_OT_extrude);
WM_operatortype_append(MESH_OT_spin);
WM_operatortype_append(MESH_OT_screw);
WM_operatortype_append(MESH_OT_vertices_to_sphere);
- WM_operatortype_append(MESH_OT_split_mesh);
+ WM_operatortype_append(MESH_OT_split);
WM_operatortype_append(MESH_OT_extrude_repeat);
- WM_operatortype_append(MESH_OT_edge_rotate_selected);
+ WM_operatortype_append(MESH_OT_edge_rotate);
WM_operatortype_append(MESH_OT_loop_to_region);
WM_operatortype_append(MESH_OT_region_to_loop);
@@ -167,13 +168,13 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_separate);
WM_operatortype_append(MESH_OT_dupli_extrude_cursor);
- WM_operatortype_append(MESH_OT_loop_select);
+ WM_operatortype_append(MESH_OT_select_loop);
WM_operatortype_append(MESH_OT_add_edge_face);
- WM_operatortype_append(MESH_OT_shortest_path_select);
- WM_operatortype_append(MESH_OT_similar_vertex_select);
- WM_operatortype_append(MESH_OT_similar_edge_select);
- WM_operatortype_append(MESH_OT_similar_face_select);
- WM_operatortype_append(MESH_OT_select_multi_loop);
+ WM_operatortype_append(MESH_OT_select_path_shortest);
+ WM_operatortype_append(MESH_OT_select_vertex_similar);
+ WM_operatortype_append(MESH_OT_select_edge_similar);
+ WM_operatortype_append(MESH_OT_select_face_similar);
+ WM_operatortype_append(MESH_OT_select_loop_multi);
WM_operatortype_append(MESH_OT_mark_seam);
WM_operatortype_append(MESH_OT_mark_sharp);
WM_operatortype_append(MESH_OT_smooth_vertex);
@@ -193,18 +194,18 @@ void ED_keymap_mesh(wmWindowManager *wm)
/* selecting */
/* standard mouse selection goes via space_view3d */
- WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
- kmi= WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
+ kmi= WM_keymap_add_item(keymap, "MESH_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "extend", 1);
- kmi= WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0);
+ kmi= WM_keymap_add_item(keymap, "MESH_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "ring", 1);
- kmi= WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT|KM_CTRL, 0);
+ kmi= WM_keymap_add_item(keymap, "MESH_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT|KM_CTRL, 0);
RNA_boolean_set(kmi->ptr, "extend", 1);
RNA_boolean_set(kmi->ptr, "ring", 1);
- WM_keymap_add_item(keymap, "MESH_OT_shortest_path_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_select_path_shortest", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "MESH_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
@@ -227,9 +228,9 @@ void ED_keymap_mesh(wmWindowManager *wm)
RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_mark_sharp", TWOKEY, KM_PRESS, KM_ALT , 0)->ptr,"set",1);
/* temp hotkeys! */
- WM_keymap_add_item(keymap, "MESH_OT_similar_vertex_select", GKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "MESH_OT_similar_edge_select", GKEY, KM_PRESS, KM_SHIFT2|KM_CTRL, 0);
- WM_keymap_add_item(keymap, "MESH_OT_similar_face_select", GKEY, KM_PRESS, KM_SHIFT|KM_CTRL2, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_select_vertex_similar", GKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_select_edge_similar", GKEY, KM_PRESS, KM_SHIFT2|KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_select_face_similar", GKEY, KM_PRESS, KM_SHIFT|KM_CTRL2, 0);
/* selection mode */
WM_keymap_add_item(keymap, "MESH_OT_selection_type", TABKEY, KM_PRESS, KM_CTRL, 0);
@@ -249,7 +250,7 @@ void ED_keymap_mesh(wmWindowManager *wm)
/*WM_keymap_add_item(keymap, "MESH_OT_subdivide_multi", WKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
WM_keymap_add_item(keymap, "MESH_OT_subdivide_multi_fractal", WKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "MESH_OT_subdivide_smooth", WKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);*/
- WM_keymap_add_item(keymap, "MESH_OT_removedoublesflag", VKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_remove_doubles", VKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_extrude", EKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "MESH_OT_spin", RKEY, KM_PRESS, KM_ALT, 0);
@@ -261,9 +262,9 @@ void ED_keymap_mesh(wmWindowManager *wm)
WM_keymap_add_item(keymap, "MESH_OT_convert_quads_to_tris", TKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_convert_tris_to_quads", JKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "MESH_OT_split_mesh", FOURKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_split", FOURKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_extrude_repeat", FOURKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "MESH_OT_edge_rotate_selected", FIVEKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_edge_rotate", FIVEKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_loop_to_region",SIXKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "MESH_OT_region_to_loop",SIXKEY, KM_PRESS, KM_ALT, 0);
@@ -277,7 +278,7 @@ void ED_keymap_mesh(wmWindowManager *wm)
/* add/remove */
WM_keymap_add_item(keymap, "MESH_OT_add_edge_face", FKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "MESH_OT_add_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_duplicate_add", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_mesh_add", AKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, KM_SHIFT, 0);
/* use KM_RELEASE because same key is used for tweaks */
@@ -285,8 +286,8 @@ void ED_keymap_mesh(wmWindowManager *wm)
WM_keymap_add_item(keymap, "MESH_OT_delete", XKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "MESH_OT_make_fgon", FKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "MESH_OT_clear_fgon", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_fgon_make", FKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "MESH_OT_fgon_clear", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
WM_keymap_add_item(keymap, "MESH_OT_knife_cut", LEFTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0);
diff --git a/source/blender/editors/object/editgroup.c b/source/blender/editors/object/editgroup.c
index 5a47c6c4430..b49e2040b03 100644
--- a/source/blender/editors/object/editgroup.c
+++ b/source/blender/editors/object/editgroup.c
@@ -107,6 +107,7 @@ void GROUP_OT_objects_add_active(wmOperatorType *ot)
/* identifiers */
ot->name= "Add Selected To Active Group";
+ ot->description = "Add the object to an object group that contains the active object.";
ot->idname= "GROUP_OT_objects_add_active";
/* api callbacks */
@@ -161,6 +162,7 @@ void GROUP_OT_objects_remove_active(wmOperatorType *ot)
/* identifiers */
ot->name= "Remove Selected From active group";
+ ot->description = "Remove the object from an object group that contains the active object.";
ot->idname= "GROUP_OT_objects_remove_active";
/* api callbacks */
@@ -194,12 +196,13 @@ static int group_remove_exec(bContext *C, wmOperator *op)
}
-void GROUP_OT_group_remove(wmOperatorType *ot)
+void GROUP_OT_objects_remove(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "remove Selected from group";
- ot->idname= "GROUP_OT_group_remove";
+ ot->name= "Remove from group";
+ ot->description = "Remove selected objects from all groups.";
+ ot->idname= "GROUP_OT_objects_remove";
/* api callbacks */
ot->exec= group_remove_exec;
@@ -239,6 +242,7 @@ void GROUP_OT_group_create(wmOperatorType *ot)
/* identifiers */
ot->name= "Create New Group";
+ ot->description = "Create an object group.";
ot->idname= "GROUP_OT_group_create";
/* api callbacks */
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index cc07c334aec..59d7ad7ad26 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -319,6 +319,7 @@ void OBJECT_OT_object_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Object";
+ ot->description = "Add an object to the scene.";
ot->idname= "OBJECT_OT_object_add";
/* api callbacks */
@@ -405,6 +406,7 @@ void OBJECT_OT_mesh_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Mesh";
+ ot->description = "Add a mesh object to the scene.";
ot->idname= "OBJECT_OT_mesh_add";
/* api callbacks */
@@ -476,6 +478,7 @@ void OBJECT_OT_curve_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Curve";
+ ot->description = "Add a curve object to the scene.";
ot->idname= "OBJECT_OT_curve_add";
/* api callbacks */
@@ -533,6 +536,7 @@ void OBJECT_OT_surface_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Surface";
+ ot->description = "Add a surface object to the scene.";
ot->idname= "OBJECT_OT_surface_add";
/* api callbacks */
@@ -569,6 +573,7 @@ void OBJECT_OT_text_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Text";
+ ot->description = "Add a text object to the scene";
ot->idname= "OBJECT_OT_text_add";
/* api callbacks */
@@ -579,7 +584,7 @@ void OBJECT_OT_text_add(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static int object_add_armature_exec(bContext *C, wmOperator *op)
+static int object_armature_add_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
View3D *v3d= CTX_wm_view3d(C);
@@ -613,10 +618,11 @@ void OBJECT_OT_armature_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Armature";
+ ot->description = "Add an armature object to the scene.";
ot->idname= "OBJECT_OT_armature_add";
/* api callbacks */
- ot->exec= object_add_armature_exec;
+ ot->exec= object_armature_add_exec;
ot->poll= ED_operator_scene_editable;
/* flags */
@@ -624,7 +630,7 @@ void OBJECT_OT_armature_add(wmOperatorType *ot)
}
-static int object_add_primitive_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int object_primitive_add_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
uiMenuItem *head= uiPupMenuBegin("Add Object", 0);
@@ -650,10 +656,11 @@ void OBJECT_OT_primitive_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Primitive";
+ ot->description = "Add a primitive object.";
ot->idname= "OBJECT_OT_primitive_add";
/* api callbacks */
- ot->invoke= object_add_primitive_invoke;
+ ot->invoke= object_primitive_add_invoke;
ot->poll= ED_operator_scene_editable;
@@ -708,6 +715,7 @@ void OBJECT_OT_delete(wmOperatorType *ot)
/* identifiers */
ot->name= "Delete Objects";
+ ot->description = "Delete the object.";
ot->idname= "OBJECT_OT_delete";
/* api callbacks */
@@ -912,7 +920,7 @@ static int return_editmesh_vgroup(Object *obedit, EditMesh *em, char *name, floa
static void select_editmesh_hook(Object *ob, HookModifierData *hmd)
{
Mesh *me= ob->data;
- EditMesh *em= me->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(me);
EditVert *eve;
int index=0, nr=0;
@@ -923,6 +931,8 @@ static void select_editmesh_hook(Object *ob, HookModifierData *hmd)
}
}
EM_select_flush(em);
+
+ EM_EndEditMesh(me, em);
}
static int return_editlattice_indexar(Lattice *editlatt, int *tot, int **indexar, float *cent)
@@ -1095,9 +1105,16 @@ int hook_getIndexArray(Object *obedit, int *tot, int **indexar, char *name, floa
case OB_MESH:
{
Mesh *me= obedit->data;
+ EditMesh *em = EM_GetEditMesh(me);
+
/* check selected vertices first */
- if( return_editmesh_indexar(me->edit_mesh, tot, indexar, cent_r)) return 1;
- else return return_editmesh_vgroup(obedit, me->edit_mesh, name, cent_r);
+ if( return_editmesh_indexar(em, tot, indexar, cent_r)) {
+ EM_EndEditMesh(me, em);
+ return 1;
+ } else {
+ int ret = return_editmesh_vgroup(obedit, em, name, cent_r);
+ EM_EndEditMesh(me, em);
+ }
}
case OB_CURVE:
case OB_SURF:
@@ -1369,7 +1386,7 @@ static EnumPropertyItem prop_clear_parent_types[] = {
};
/* note, poll should check for editable scene */
-static int clear_parent_exec(bContext *C, wmOperator *op)
+static int parent_clear_exec(bContext *C, wmOperator *op)
{
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) {
@@ -1395,15 +1412,16 @@ static int clear_parent_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_clear_parent(wmOperatorType *ot)
+void OBJECT_OT_parent_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear parent";
- ot->idname= "OBJECT_OT_clear_parent";
+ ot->description = "Clear the object's parenting.";
+ ot->idname= "OBJECT_OT_parent_clear";
/* api callbacks */
ot->invoke= WM_menu_invoke;
- ot->exec= clear_parent_exec;
+ ot->exec= parent_clear_exec;
ot->poll= ED_operator_object_active;
@@ -1423,7 +1441,7 @@ static EnumPropertyItem prop_clear_track_types[] = {
};
/* note, poll should check for editable scene */
-static int object_clear_track_exec(bContext *C, wmOperator *op)
+static int object_track_clear_exec(bContext *C, wmOperator *op)
{
if(CTX_data_edit_object(C)) {
BKE_report(op->reports, RPT_ERROR, "Operation cannot be performed in EditMode");
@@ -1445,15 +1463,16 @@ static int object_clear_track_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_clear_track(wmOperatorType *ot)
+void OBJECT_OT_track_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear track";
- ot->idname= "OBJECT_OT_clear_track";
+ ot->description = "Clear tracking constraint or flag from object.";
+ ot->idname= "OBJECT_OT_track_clear";
/* api callbacks */
ot->invoke= WM_menu_invoke;
- ot->exec= object_clear_track_exec;
+ ot->exec= object_track_clear_exec;
ot->poll= ED_operator_scene_editable;
@@ -1489,6 +1508,7 @@ void OBJECT_OT_select_by_type(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select By Type";
+ ot->description = "Select all visible objects that are of a type.";
ot->idname= "OBJECT_OT_select_by_type";
/* api callbacks */
@@ -1641,6 +1661,7 @@ void OBJECT_OT_select_linked(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select Linked";
+ ot->description = "Select all visible objects that are linked.";
ot->idname= "OBJECT_OT_select_linked";
/* api callbacks */
@@ -1677,7 +1698,8 @@ static int object_select_by_layer_exec(bContext *C, wmOperator *op)
void OBJECT_OT_select_by_layer(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Selection by layer";
+ ot->name= "select by layer";
+ ot->description = "Select all visible objects on a layer.";
ot->idname= "OBJECT_OT_select_by_layer";
/* api callbacks */
@@ -1713,6 +1735,7 @@ void OBJECT_OT_select_invert(wmOperatorType *ot)
/* identifiers */
ot->name= "Invert selection";
+ ot->description = "Invert th select of all visible objects.";
ot->idname= "OBJECT_OT_select_invert";
/* api callbacks */
@@ -1725,7 +1748,7 @@ void OBJECT_OT_select_invert(wmOperatorType *ot)
}
/* ****** (de)select All *******/
-static int object_de_select_all_exec(bContext *C, wmOperator *op)
+static int object_select_de_select_all_exec(bContext *C, wmOperator *op)
{
int a=0, ok=0;
@@ -1753,15 +1776,16 @@ static int object_de_select_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_de_select_all(wmOperatorType *ot)
+void OBJECT_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "deselect all";
- ot->idname= "OBJECT_OT_de_select_all";
+ ot->description = "(de)select all visible objects in scene.";
+ ot->idname= "OBJECT_OT_select_all_toggle";
/* api callbacks */
- ot->exec= object_de_select_all_exec;
+ ot->exec= object_select_de_select_all_exec;
ot->poll= ED_operator_scene_editable;
/* flags */
@@ -1791,7 +1815,8 @@ static int object_select_random_exec(bContext *C, wmOperator *op)
void OBJECT_OT_select_random(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Random selection";
+ ot->name= "Random select";
+ ot->description = "Set select on random visible objects.";
ot->idname= "OBJECT_OT_select_random";
/* api callbacks */
@@ -1807,7 +1832,7 @@ void OBJECT_OT_select_random(wmOperatorType *ot)
/* ******** Clear object Translation *********** */
-static int object_clear_location_exec(bContext *C, wmOperator *op)
+static int object_location_clear_exec(bContext *C, wmOperator *op)
{
int armature_clear= 0;
@@ -1833,23 +1858,24 @@ static int object_clear_location_exec(bContext *C, wmOperator *op)
}
-void OBJECT_OT_clear_location(wmOperatorType *ot)
+void OBJECT_OT_location_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear Object Location";
- ot->idname= "OBJECT_OT_clear_location";
+ ot->description = "Clear the object's location.";
+ ot->idname= "OBJECT_OT_location_clear";
/* api callbacks */
ot->invoke= WM_operator_confirm;
- ot->exec= object_clear_location_exec;
+ ot->exec= object_location_clear_exec;
ot->poll= ED_operator_object_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static int object_clear_rotation_exec(bContext *C, wmOperator *op)
+static int object_rotation_clear_exec(bContext *C, wmOperator *op)
{
int armature_clear= 0;
@@ -1876,23 +1902,24 @@ static int object_clear_rotation_exec(bContext *C, wmOperator *op)
}
-void OBJECT_OT_clear_rotation(wmOperatorType *ot)
+void OBJECT_OT_rotation_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear Object Rotation";
- ot->idname= "OBJECT_OT_clear_rotation";
+ ot->description = "Clear the object's rotation.";
+ ot->idname= "OBJECT_OT_rotation_clear";
/* api callbacks */
ot->invoke= WM_operator_confirm;
- ot->exec= object_clear_rotation_exec;
+ ot->exec= object_rotation_clear_exec;
ot->poll= ED_operator_object_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static int object_clear_scale_exec(bContext *C, wmOperator *op)
+static int object_scale_clear_exec(bContext *C, wmOperator *op)
{
int armature_clear= 0;
@@ -1923,23 +1950,24 @@ static int object_clear_scale_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_clear_scale(wmOperatorType *ot)
+void OBJECT_OT_scale_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear Object Scale";
- ot->idname= "OBJECT_OT_clear_scale";
+ ot->description = "Clear the object's scale.";
+ ot->idname= "OBJECT_OT_scale_clear";
/* api callbacks */
ot->invoke= WM_operator_confirm;
- ot->exec= object_clear_scale_exec;
+ ot->exec= object_scale_clear_exec;
ot->poll= ED_operator_object_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static int object_clear_origin_exec(bContext *C, wmOperator *op)
+static int object_origin_clear_exec(bContext *C, wmOperator *op)
{
float *v1, *v3, mat[3][3];
int armature_clear= 0;
@@ -1968,16 +1996,17 @@ static int object_clear_origin_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_clear_origin(wmOperatorType *ot)
+void OBJECT_OT_origin_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear Object Origin";
- ot->idname= "OBJECT_OT_clear_origin";
+ ot->description = "Clear the object's origin.";
+ ot->idname= "OBJECT_OT_origin_clear";
/* api callbacks */
ot->invoke= WM_operator_confirm;
- ot->exec= object_clear_origin_exec;
+ ot->exec= object_origin_clear_exec;
ot->poll= ED_operator_object_active;
/* flags */
@@ -1985,7 +2014,7 @@ void OBJECT_OT_clear_origin(wmOperatorType *ot)
}
/* ********* clear/set restrict view *********/
-static int object_clear_restrictview_exec(bContext *C, wmOperator *op)
+static int object_restrictview_clear_exec(bContext *C, wmOperator *op)
{
ScrArea *sa= CTX_wm_area(C);
View3D *v3d= sa->spacedata.first;
@@ -2010,16 +2039,17 @@ static int object_clear_restrictview_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_clear_restrictview(wmOperatorType *ot)
+void OBJECT_OT_restrictview_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear restrict view";
- ot->idname= "OBJECT_OT_clear_restrictview";
+ ot->description = "Reveal the object by setting the restrictview flag.";
+ ot->idname= "OBJECT_OT_restrictview_clear";
/* api callbacks */
ot->invoke= WM_operator_confirm;
- ot->exec= object_clear_restrictview_exec;
+ ot->exec= object_restrictview_clear_exec;
ot->poll= ED_operator_view3d_active;
/* flags */
@@ -2032,7 +2062,7 @@ static EnumPropertyItem prop_set_restrictview_types[] = {
{0, NULL, NULL, NULL}
};
-static int object_set_restrictview_exec(bContext *C, wmOperator *op)
+static int object_restrictview_set_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
short changed = 0;
@@ -2068,15 +2098,16 @@ static int object_set_restrictview_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_set_restrictview(wmOperatorType *ot)
+void OBJECT_OT_restrictview_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set restrict view";
- ot->idname= "OBJECT_OT_set_restrictview";
+ ot->description = "Hide the object by setting the restrictview flag.";
+ ot->idname= "OBJECT_OT_restrictview_set";
/* api callbacks */
ot->invoke= WM_menu_invoke;
- ot->exec= object_set_restrictview_exec;
+ ot->exec= object_restrictview_set_exec;
ot->poll= ED_operator_view3d_active;
/* flags */
@@ -2086,7 +2117,7 @@ void OBJECT_OT_set_restrictview(wmOperatorType *ot)
}
/* ************* Slow Parent ******************* */
-static int object_set_slowparent_exec(bContext *C, wmOperator *op)
+static int object_slowparent_set_exec(bContext *C, wmOperator *op)
{
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
@@ -2104,23 +2135,24 @@ static int object_set_slowparent_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_set_slowparent(wmOperatorType *ot)
+void OBJECT_OT_slowparent_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Slow Parent";
- ot->idname= "OBJECT_OT_set_slow_parent";
+ ot->description = "Set the object's slow parent.";
+ ot->idname= "OBJECT_OT_slow_parent_set";
/* api callbacks */
ot->invoke= WM_operator_confirm;
- ot->exec= object_set_slowparent_exec;
+ ot->exec= object_slowparent_set_exec;
ot->poll= ED_operator_view3d_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static int object_clear_slowparent_exec(bContext *C, wmOperator *op)
+static int object_slowparent_clear_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
@@ -2144,16 +2176,17 @@ static int object_clear_slowparent_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_clear_slowparent(wmOperatorType *ot)
+void OBJECT_OT_slowparent_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear Slow Parent";
- ot->idname= "OBJECT_OT_clear_slow_parent";
+ ot->description = "Clear the object's slow parent.";
+ ot->idname= "OBJECT_OT_slow_parent_clear";
/* api callbacks */
ot->invoke= WM_operator_confirm;
- ot->exec= object_clear_slowparent_exec;
+ ot->exec= object_slowparent_clear_exec;
ot->poll= ED_operator_view3d_active;
/* flags */
@@ -2178,8 +2211,9 @@ void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d)
if(obedit->type==OB_MESH) {
Mesh *me= obedit->data;
-
- eve= me->edit_mesh->verts.first;
+ EditMesh *em = EM_GetEditMesh(me);
+
+ eve= em->verts.first;
while(eve) {
if(eve->f & 1) {
if(v1==0) v1= nr;
@@ -2191,6 +2225,8 @@ void make_vertex_parent(Scene *scene, Object *obedit, View3D *v3d)
nr++;
eve= eve->next;
}
+
+ EM_EndEditMesh(me, em);
}
else if(ELEM(obedit->type, OB_SURF, OB_CURVE)) {
ListBase *editnurb= curve_get_editcurve(obedit);
@@ -2421,7 +2457,7 @@ static int test_parent_loop(Object *par, Object *ob)
}
-static int make_parent_exec(bContext *C, wmOperator *op)
+static int parent_set_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *par= CTX_data_active_object(C);
@@ -2541,26 +2577,26 @@ static int make_parent_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int make_parent_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int parent_set_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Object *ob= CTX_data_active_object(C);
- uiMenuItem *head= uiPupMenuBegin("Make Parent To", 0);
+ uiMenuItem *head= uiPupMenuBegin("Set Parent To", 0);
uiMenuContext(head, WM_OP_EXEC_DEFAULT);
- uiMenuItemEnumO(head, "", 0, "OBJECT_OT_make_parent", "type", PAR_OBJECT);
+ uiMenuItemEnumO(head, "", 0, "OBJECT_OT_parent_set", "type", PAR_OBJECT);
/* ob becomes parent, make the associated menus */
if(ob->type==OB_ARMATURE) {
- uiMenuItemEnumO(head, "", 0, "OBJECT_OT_make_parent", "type", PAR_ARMATURE);
- uiMenuItemEnumO(head, "", 0, "OBJECT_OT_make_parent", "type", PAR_BONE);
+ uiMenuItemEnumO(head, "", 0, "OBJECT_OT_parent_set", "type", PAR_ARMATURE);
+ uiMenuItemEnumO(head, "", 0, "OBJECT_OT_parent_set", "type", PAR_BONE);
}
else if(ob->type==OB_CURVE) {
- uiMenuItemEnumO(head, "", 0, "OBJECT_OT_make_parent", "type", PAR_CURVE);
- uiMenuItemEnumO(head, "", 0, "OBJECT_OT_make_parent", "type", PAR_FOLLOW);
- uiMenuItemEnumO(head, "", 0, "OBJECT_OT_make_parent", "type", PAR_PATH_CONST);
+ uiMenuItemEnumO(head, "", 0, "OBJECT_OT_parent_set", "type", PAR_CURVE);
+ uiMenuItemEnumO(head, "", 0, "OBJECT_OT_parent_set", "type", PAR_FOLLOW);
+ uiMenuItemEnumO(head, "", 0, "OBJECT_OT_parent_set", "type", PAR_PATH_CONST);
}
else if(ob->type == OB_LATTICE) {
- uiMenuItemEnumO(head, "", 0, "OBJECT_OT_make_parent", "type", PAR_LATTICE);
+ uiMenuItemEnumO(head, "", 0, "OBJECT_OT_parent_set", "type", PAR_LATTICE);
}
uiPupMenuEnd(C, head);
@@ -2569,15 +2605,16 @@ static int make_parent_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
-void OBJECT_OT_make_parent(wmOperatorType *ot)
+void OBJECT_OT_parent_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Make parent";
- ot->idname= "OBJECT_OT_make_parent";
+ ot->description = "Set the object's parenting.";
+ ot->idname= "OBJECT_OT_parent_set";
/* api callbacks */
- ot->invoke= make_parent_invoke;
- ot->exec= make_parent_exec;
+ ot->invoke= parent_set_invoke;
+ ot->exec= parent_set_exec;
ot->poll= ED_operator_object_active;
@@ -2595,7 +2632,7 @@ static EnumPropertyItem prop_make_track_types[] = {
{0, NULL, NULL, NULL}
};
-static int make_track_exec(bContext *C, wmOperator *op)
+static int track_set_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
@@ -2662,15 +2699,16 @@ static int make_track_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_make_track(wmOperatorType *ot)
+void OBJECT_OT_track_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Make Track";
- ot->idname= "OBJECT_OT_make_track";
+ ot->description = "Make the object track another object, either by constraint or old way or locked track.";
+ ot->idname= "OBJECT_OT_track_set";
/* api callbacks */
ot->invoke= WM_menu_invoke;
- ot->exec= make_track_exec;
+ ot->exec= track_set_exec;
ot->poll= ED_operator_scene_editable;
@@ -2724,7 +2762,7 @@ static void make_object_duplilist_real(Scene *scene, View3D *v3d, Base *base)
}
-static int object_make_dupli_real_exec(bContext *C, wmOperator *op)
+static int object_dupli_set_real_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
ScrArea *sa= CTX_wm_area(C);
@@ -2744,16 +2782,17 @@ static int object_make_dupli_real_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_make_dupli_real(wmOperatorType *ot)
+void OBJECT_OT_dupli_set_real(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Make Dupli Real";
- ot->idname= "OBJECT_OT_make_dupli_real";
+ ot->description = "Make dupli objects attached to this object real.";
+ ot->idname= "OBJECT_OT_dupli_set_real";
/* api callbacks */
ot->invoke= WM_operator_confirm;
- ot->exec= object_make_dupli_real_exec;
+ ot->exec= object_dupli_set_real_exec;
ot->poll= ED_operator_scene_editable;
@@ -2770,7 +2809,7 @@ static EnumPropertyItem prop_set_center_types[] = {
};
/* 0 == do center, 1 == center new, 2 == center cursor */
-static int object_set_center_exec(bContext *C, wmOperator *op)
+static int object_center_set_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
ScrArea *sa= CTX_wm_area(C);
@@ -2807,8 +2846,9 @@ static int object_set_center_exec(bContext *C, wmOperator *op)
if(obedit->type==OB_MESH) {
Mesh *me= obedit->data;
-
- for(eve= me->edit_mesh->verts.first; eve; eve= eve->next) {
+ EditMesh *em = EM_GetEditMesh(me);
+
+ for(eve= em->verts.first; eve; eve= eve->next) {
if(v3d->around==V3D_CENTROID) {
total++;
VECADD(cent, cent, eve->co);
@@ -2827,13 +2867,14 @@ static int object_set_center_exec(bContext *C, wmOperator *op)
cent[2]= (min[2]+max[2])/2.0f;
}
- for(eve= me->edit_mesh->verts.first; eve; eve= eve->next) {
+ for(eve= em->verts.first; eve; eve= eve->next) {
VecSubf(eve->co, eve->co, cent);
}
- recalc_editnormals(me->edit_mesh);
+ recalc_editnormals(em);
tot_change++;
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+ EM_EndEditMesh(me, em);
}
}
@@ -3093,15 +3134,16 @@ static int object_set_center_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_set_center(wmOperatorType *ot)
+void OBJECT_OT_center_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Center";
- ot->idname= "OBJECT_OT_set_center";
+ ot->description = "Set the object's center, by either moving the data, or set to center of data, or use 3d cursor";
+ ot->idname= "OBJECT_OT_center_set";
/* api callbacks */
ot->invoke= WM_menu_invoke;
- ot->exec= object_set_center_exec;
+ ot->exec= object_center_set_exec;
ot->poll= ED_operator_view3d_active;
@@ -3284,7 +3326,7 @@ void ED_object_enter_editmode(bContext *C, int flag)
if(flag & EM_WAITCURSOR) waitcursor(0);
}
-static int toggle_editmode_exec(bContext *C, wmOperator *op)
+static int editmode_toggle_exec(bContext *C, wmOperator *op)
{
if(!CTX_data_edit_object(C))
@@ -3300,10 +3342,11 @@ void OBJECT_OT_editmode_toggle(wmOperatorType *ot)
/* identifiers */
ot->name= "Toggle Editmode";
+ ot->description = "Toggle object's editmode.";
ot->idname= "OBJECT_OT_editmode_toggle";
/* api callbacks */
- ot->exec= toggle_editmode_exec;
+ ot->exec= editmode_toggle_exec;
ot->poll= ED_operator_object_active;
@@ -6018,7 +6061,7 @@ Base *ED_object_add_duplicate(Scene *scene, Base *base, int usedupflag)
}
/* contextual operator dupli */
-static int add_duplicate_exec(bContext *C, wmOperator *op)
+static int duplicate_add_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
View3D *v3d= CTX_wm_view3d(C);
@@ -6050,9 +6093,9 @@ static int add_duplicate_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int add_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int duplicate_add_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- add_duplicate_exec(C, op);
+ duplicate_add_exec(C, op);
RNA_int_set(op->ptr, "mode", TFM_TRANSLATION);
WM_operator_name_call(C, "TFM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
@@ -6060,16 +6103,17 @@ static int add_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
}
-void OBJECT_OT_add_duplicate(wmOperatorType *ot)
+void OBJECT_OT_duplicate_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Duplicate";
- ot->idname= "OBJECT_OT_add_duplicate";
+ ot->description = "Duplicate the object.";
+ ot->idname= "OBJECT_OT_duplicate_add";
/* api callbacks */
- ot->invoke= add_duplicate_invoke;
- ot->exec= add_duplicate_exec;
+ ot->invoke= duplicate_add_invoke;
+ ot->exec= duplicate_add_exec;
ot->poll= ED_operator_scene_editable;
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 138f278fe77..1c56b0c7115 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -36,35 +36,32 @@ struct Object;
struct Mesh;
/* internal exports only */
-#define CLEAR_OBJ_ROTATION 0
-#define CLEAR_OBJ_LOCATION 1
-#define CLEAR_OBJ_SCALE 2
-#define CLEAR_OBJ_ORIGIN 3
+
/* object_edit.c */
void OBJECT_OT_editmode_toggle(struct wmOperatorType *ot);
-void OBJECT_OT_make_parent(struct wmOperatorType *ot);
-void OBJECT_OT_clear_parent(struct wmOperatorType *ot);
-void OBJECT_OT_make_track(struct wmOperatorType *ot);
-void OBJECT_OT_clear_track(struct wmOperatorType *ot);
-void OBJECT_OT_de_select_all(struct wmOperatorType *ot);
+void OBJECT_OT_parent_set(struct wmOperatorType *ot);
+void OBJECT_OT_parent_clear(struct wmOperatorType *ot);
+void OBJECT_OT_track_set(struct wmOperatorType *ot);
+void OBJECT_OT_track_clear(struct wmOperatorType *ot);
+void OBJECT_OT_select_all_toggle(struct wmOperatorType *ot);
void OBJECT_OT_select_invert(struct wmOperatorType *ot);
void OBJECT_OT_select_random(struct wmOperatorType *ot);
void OBJECT_OT_select_by_type(struct wmOperatorType *ot);
void OBJECT_OT_select_by_layer(struct wmOperatorType *ot);
void OBJECT_OT_select_linked(struct wmOperatorType *ot);
-void OBJECT_OT_clear_location(struct wmOperatorType *ot);
-void OBJECT_OT_clear_rotation(struct wmOperatorType *ot);
-void OBJECT_OT_clear_scale(struct wmOperatorType *ot);
-void OBJECT_OT_clear_origin(struct wmOperatorType *ot);
-void OBJECT_OT_clear_restrictview(struct wmOperatorType *ot);
-void OBJECT_OT_set_restrictview(struct wmOperatorType *ot);
-void OBJECT_OT_set_slowparent(struct wmOperatorType *ot);
-void OBJECT_OT_clear_slowparent(struct wmOperatorType *ot);
-void OBJECT_OT_set_center(struct wmOperatorType *ot);
-void OBJECT_OT_make_dupli_real(struct wmOperatorType *ot);
+void OBJECT_OT_location_clear(struct wmOperatorType *ot);
+void OBJECT_OT_rotation_clear(struct wmOperatorType *ot);
+void OBJECT_OT_scale_clear(struct wmOperatorType *ot);
+void OBJECT_OT_origin_clear(struct wmOperatorType *ot);
+void OBJECT_OT_restrictview_set(struct wmOperatorType *ot);
+void OBJECT_OT_restrictview_clear(struct wmOperatorType *ot);
+void OBJECT_OT_slowparent_set(struct wmOperatorType *ot);
+void OBJECT_OT_slowparent_clear(struct wmOperatorType *ot);
+void OBJECT_OT_center_set(struct wmOperatorType *ot);
+void OBJECT_OT_dupli_set_real(struct wmOperatorType *ot);
void OBJECT_OT_object_add(struct wmOperatorType *ot);
-void OBJECT_OT_add_duplicate(struct wmOperatorType *ot);
+void OBJECT_OT_duplicate_add(struct wmOperatorType *ot);
void OBJECT_OT_delete(struct wmOperatorType *ot);
void OBJECT_OT_mesh_add(struct wmOperatorType *ot);
@@ -83,7 +80,7 @@ void remake_editLatt(Object *obedit);
/* editgroup.c */
void GROUP_OT_group_create(struct wmOperatorType *ot);
-void GROUP_OT_group_remove(struct wmOperatorType *ot);
+void GROUP_OT_objects_remove(struct wmOperatorType *ot);
void GROUP_OT_objects_add_active(struct wmOperatorType *ot);
void GROUP_OT_objects_remove_active(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 134c486bb66..8cbf9bf5287 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -64,29 +64,29 @@
void ED_operatortypes_object(void)
{
WM_operatortype_append(OBJECT_OT_editmode_toggle);
- WM_operatortype_append(OBJECT_OT_make_parent);
- WM_operatortype_append(OBJECT_OT_clear_parent);
- WM_operatortype_append(OBJECT_OT_make_track);
- WM_operatortype_append(OBJECT_OT_clear_track);
+ WM_operatortype_append(OBJECT_OT_parent_set);
+ WM_operatortype_append(OBJECT_OT_parent_clear);
+ WM_operatortype_append(OBJECT_OT_track_set);
+ WM_operatortype_append(OBJECT_OT_track_clear);
WM_operatortype_append(OBJECT_OT_select_invert);
WM_operatortype_append(OBJECT_OT_select_random);
- WM_operatortype_append(OBJECT_OT_de_select_all);
+ WM_operatortype_append(OBJECT_OT_select_all_toggle);
WM_operatortype_append(OBJECT_OT_select_by_type);
WM_operatortype_append(OBJECT_OT_select_by_layer);
WM_operatortype_append(OBJECT_OT_select_linked);
- WM_operatortype_append(OBJECT_OT_clear_location);
- WM_operatortype_append(OBJECT_OT_clear_rotation);
- WM_operatortype_append(OBJECT_OT_clear_scale);
- WM_operatortype_append(OBJECT_OT_clear_origin);
- WM_operatortype_append(OBJECT_OT_clear_restrictview);
- WM_operatortype_append(OBJECT_OT_set_restrictview);
- WM_operatortype_append(OBJECT_OT_set_slowparent);
- WM_operatortype_append(OBJECT_OT_clear_slowparent);
- WM_operatortype_append(OBJECT_OT_set_center);
- WM_operatortype_append(OBJECT_OT_make_dupli_real);
- WM_operatortype_append(OBJECT_OT_add_duplicate);
+ WM_operatortype_append(OBJECT_OT_location_clear);
+ WM_operatortype_append(OBJECT_OT_rotation_clear);
+ WM_operatortype_append(OBJECT_OT_scale_clear);
+ WM_operatortype_append(OBJECT_OT_origin_clear);
+ WM_operatortype_append(OBJECT_OT_restrictview_clear);
+ WM_operatortype_append(OBJECT_OT_restrictview_set);
+ WM_operatortype_append(OBJECT_OT_slowparent_set);
+ WM_operatortype_append(OBJECT_OT_slowparent_clear);
+ WM_operatortype_append(OBJECT_OT_center_set);
+ WM_operatortype_append(OBJECT_OT_dupli_set_real);
+ WM_operatortype_append(OBJECT_OT_duplicate_add);
WM_operatortype_append(GROUP_OT_group_create);
- WM_operatortype_append(GROUP_OT_group_remove);
+ WM_operatortype_append(GROUP_OT_objects_remove);
WM_operatortype_append(GROUP_OT_objects_add_active);
WM_operatortype_append(GROUP_OT_objects_remove_active);
@@ -106,41 +106,41 @@ void ED_keymap_object(wmWindowManager *wm)
/* Note: this keymap works disregarding mode */
WM_keymap_add_item(keymap, "OBJECT_OT_editmode_toggle", TABKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "OBJECT_OT_set_center", CKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "OBJECT_OT_center_set", CKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
/* Note: this keymap gets disabled in non-objectmode, */
keymap= WM_keymap_listbase(wm, "Object Mode", 0, 0);
- WM_keymap_add_item(keymap, "OBJECT_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "OBJECT_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_select_random", PADASTERKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_select_by_type", PADASTERKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_select_by_layer", PADASTERKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "OBJECT_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_make_parent", PKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_clear_parent", PKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_make_track", TKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_clear_track", TKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_track_set", TKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_track_set", TKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_clear_location", GKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_clear_rotation", RKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_clear_scale", SKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_clear_origin", OKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_location_clear", GKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_rotation_clear", RKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_scale_clear", SKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_origin_clear", OKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_clear_restrictview", HKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_set_restrictview", HKEY, KM_PRESS, 0, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_restrictview_clear", HKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_restrictview_set", HKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "OBJECT_OT_primitive_add", AKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_verify_item(keymap, "OBJECT_OT_add_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_verify_item(keymap, "OBJECT_OT_duplicate_add", DKEY, KM_PRESS, KM_SHIFT, 0);
// XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith
WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_old", IKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_delete_keyframe_old", IKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_verify_item(keymap, "GROUP_OT_group_create", GKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_verify_item(keymap, "GROUP_OT_group_remove", GKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove", GKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
WM_keymap_verify_item(keymap, "GROUP_OT_objects_add_active", GKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_active", GKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
diff --git a/source/blender/editors/physics/editparticle.c b/source/blender/editors/physics/editparticle.c
index b3c7be688f2..33d1bd66676 100644
--- a/source/blender/editors/physics/editparticle.c
+++ b/source/blender/editors/physics/editparticle.c
@@ -1209,11 +1209,11 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void PARTICLE_OT_de_select_all(wmOperatorType *ot)
+void PARTICLE_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select or Deselect All";
- ot->idname= "PARTICLE_OT_de_select_all";
+ ot->idname= "PARTICLE_OT_select_all_toggle";
/* api callbacks */
ot->exec= de_select_all_exec;
@@ -2312,7 +2312,6 @@ static int brush_radial_control_exec(bContext *C, wmOperator *op)
ParticleBrushData *brush;
int mode = RNA_enum_get(op->ptr, "mode");
float new_value = RNA_float_get(op->ptr, "new_value");
- char str[256];
if(pset->brushtype < 0)
return OPERATOR_CANCELLED;
@@ -2324,8 +2323,6 @@ static int brush_radial_control_exec(bContext *C, wmOperator *op)
else if(mode == WM_RADIALCONTROL_STRENGTH)
brush->strength= new_value;
- WM_radial_control_string(op, str, 256);
-
return OPERATOR_FINISHED;
}
@@ -2584,11 +2581,11 @@ static int set_brush_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void PARTICLE_OT_set_brush(wmOperatorType *ot)
+void PARTICLE_OT_brush_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Brush";
- ot->idname= "PARTICLE_OT_set_brush";
+ ot->idname= "PARTICLE_OT_brush_set";
/* api callbacks */
ot->exec= set_brush_exec;
@@ -3781,11 +3778,11 @@ static int set_editable_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void PARTICLE_OT_set_editable(wmOperatorType *ot)
+void PARTICLE_OT_editable_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Editable";
- ot->idname= "PARTICLE_OT_set_editable";
+ ot->idname= "PARTICLE_OT_editable_set";
/* api callbacks */
ot->exec= set_editable_exec;
@@ -3874,7 +3871,7 @@ void PARTICLE_OT_specials_menu(wmOperatorType *ot)
void ED_operatortypes_particle(void)
{
- WM_operatortype_append(PARTICLE_OT_de_select_all);
+ WM_operatortype_append(PARTICLE_OT_select_all_toggle);
WM_operatortype_append(PARTICLE_OT_select_first);
WM_operatortype_append(PARTICLE_OT_select_last);
WM_operatortype_append(PARTICLE_OT_select_linked);
@@ -3890,21 +3887,21 @@ void ED_operatortypes_particle(void)
WM_operatortype_append(PARTICLE_OT_delete);
WM_operatortype_append(PARTICLE_OT_mirror);
- WM_operatortype_append(PARTICLE_OT_set_brush);
+ WM_operatortype_append(PARTICLE_OT_brush_set);
WM_operatortype_append(PARTICLE_OT_brush_edit);
WM_operatortype_append(PARTICLE_OT_brush_radial_control);
WM_operatortype_append(PARTICLE_OT_specials_menu);
WM_operatortype_append(PARTICLE_OT_particle_edit_toggle);
- WM_operatortype_append(PARTICLE_OT_set_editable);
+ WM_operatortype_append(PARTICLE_OT_editable_set);
}
void ED_keymap_particle(wmWindowManager *wm)
{
ListBase *keymap= WM_keymap_listbase(wm, "Particle", 0, 0);
- WM_keymap_add_item(keymap, "PARTICLE_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "PARTICLE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PARTICLE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "PARTICLE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "PARTICLE_OT_select_linked", LKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index be9c76111db..5c481652db1 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -660,12 +660,15 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
sa1->spacetype= sa2->spacetype;
sa1->butspacetype= sa2->butspacetype;
- if(swap_space) {
+ if(swap_space == 1) {
SWAP(ListBase, sa1->spacedata, sa2->spacedata);
/* exception: ensure preview is reset */
// if(sa1->spacetype==SPACE_VIEW3D)
// XXX BIF_view3d_previewrender_free(sa1->spacedata.first);
}
+ else if (swap_space == 2) {
+ BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata);
+ }
else {
BKE_spacedata_freelist(&sa1->spacedata);
BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata);
@@ -674,10 +677,12 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
/* Note; SPACE_EMPTY is possible on new screens */
/* regions */
- st= BKE_spacetype_from_id(sa1->spacetype);
- for(ar= sa1->regionbase.first; ar; ar= ar->next)
- BKE_area_region_free(st, ar);
- BLI_freelistN(&sa1->regionbase);
+ if(swap_space<2) {
+ st= BKE_spacetype_from_id(sa1->spacetype);
+ for(ar= sa1->regionbase.first; ar; ar= ar->next)
+ BKE_area_region_free(st, ar);
+ BLI_freelistN(&sa1->regionbase);
+ }
st= BKE_spacetype_from_id(sa2->spacetype);
for(ar= sa2->regionbase.first; ar; ar= ar->next) {
@@ -695,6 +700,35 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
/* *********** Space switching code *********** */
+void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2)
+{
+ ScrArea *tmp= MEM_callocN(sizeof(ScrArea), "addscrarea");
+
+ ED_area_exit(C, sa1);
+ ED_area_exit(C, sa2);
+
+ tmp->spacetype= sa1->spacetype;
+ tmp->butspacetype= sa1->butspacetype;
+ BKE_spacedata_copyfirst(&tmp->spacedata, &sa1->spacedata);
+
+ area_copy_data(tmp, sa1, 2);
+ area_copy_data(sa1, sa2, 0);
+ area_copy_data(sa2, tmp, 0);
+ ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa1);
+ ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa2);
+
+ BKE_screen_area_free(tmp);
+ MEM_freeN(tmp);
+
+ /* tell WM to refresh, cursor types etc */
+ WM_event_add_mousemove(C);
+
+ ED_area_tag_redraw(sa1);
+ ED_area_tag_refresh(sa1);
+ ED_area_tag_redraw(sa2);
+ ED_area_tag_refresh(sa2);
+}
+
void ED_area_newspace(bContext *C, ScrArea *sa, int type)
{
if(sa->spacetype != type) {
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 573e89b8bb4..74e0bc3852e 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -462,10 +462,10 @@ void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *
glTexCoord2f((float) (subpart_w-1)/tex_w, 0);
glVertex2f(rast_x+subpart_w*xzoom, rast_y);
- glTexCoord2f((float) (subpart_w-1)/tex_w, (float) subpart_h/tex_h);
+ glTexCoord2f((float) (subpart_w-1)/tex_w, (float) (subpart_h-1)/tex_h);
glVertex2f(rast_x+subpart_w*xzoom, rast_y+subpart_h*yzoom);
- glTexCoord2f(0, (float) subpart_h/tex_h);
+ glTexCoord2f(0, (float) (subpart_h-1)/tex_h);
glVertex2f(rast_x, rast_y+subpart_h*yzoom);
glEnd();
glDisable(GL_TEXTURE_2D);
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 2406c1c5e32..11d1d019005 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -25,6 +25,7 @@
*/
#include <stdlib.h>
+#include <string.h>
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -33,44 +34,48 @@
#include "BKE_context.h"
#include "BKE_utildefines.h"
-int ed_screen_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
+#include "RNA_access.h"
+
+int ed_screen_context(const bContext *C, const char *member, bContextDataResult *result)
{
bScreen *sc= CTX_wm_screen(C);
Scene *scene= sc->scene;
Base *base;
- if(member == CTX_DATA_SCENE) {
- CTX_data_pointer_set(result, scene);
+ if(CTX_data_equals(member, "scene")) {
+ CTX_data_id_pointer_set(result, &scene->id);
return 1;
}
- else if(ELEM(member, CTX_DATA_SELECTED_OBJECTS, CTX_DATA_SELECTED_BASES)) {
+ else if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
+ int selected_objects= CTX_data_equals(member, "selected_objects");
+
for(base=scene->base.first; base; base=base->next) {
if((base->flag & SELECT) && (base->lay & scene->lay)) {
- if(member == CTX_DATA_SELECTED_OBJECTS)
- CTX_data_list_add(result, base->object);
+ if(selected_objects)
+ CTX_data_id_list_add(result, &base->object->id);
else
- CTX_data_list_add(result, base);
+ CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
}
}
return 1;
}
- else if(member == CTX_DATA_ACTIVE_BASE) {
+ else if(CTX_data_equals(member, "active_base")) {
if(scene->basact)
- CTX_data_pointer_set(result, scene->basact);
+ CTX_data_pointer_set(result, &scene->id, &RNA_UnknownType, &scene->basact);
return 1;
}
- else if(member == CTX_DATA_ACTIVE_OBJECT) {
+ else if(CTX_data_equals(member, "active_object")) {
if(scene->basact)
- CTX_data_pointer_set(result, scene->basact->object);
+ CTX_data_id_pointer_set(result, &scene->basact->object->id);
return 1;
}
- else if(member == CTX_DATA_EDIT_OBJECT) {
+ else if(CTX_data_equals(member, "edit_object")) {
/* convenience for now, 1 object per scene in editmode */
if(scene->obedit)
- CTX_data_pointer_set(result, scene->obedit);
+ CTX_data_id_pointer_set(result, &scene->obedit->id);
return 1;
}
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index f39ca7d4c3e..a0804f3e633 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -55,7 +55,7 @@ AZone *is_in_area_actionzone(ScrArea *sa, int x, int y);
void ed_screen_fullarea(bContext *C, ScrArea *sa);
/* screen_context.c */
-void ed_screen_context(const bContext *C, bContextDataMember member, bContextDataResult *result);
+void ed_screen_context(const bContext *C, const char *member, bContextDataResult *result);
/* screendump.c */
void SCREEN_OT_screenshot(struct wmOperatorType *ot);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 8bc6cb6e567..d06259d1487 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -57,6 +57,7 @@
#include "ED_util.h"
#include "ED_screen.h"
+#include "ED_mesh.h"
#include "ED_screen_types.h"
#include "RE_pipeline.h"
@@ -134,11 +135,7 @@ int ED_operator_timeline_active(bContext *C)
int ED_operator_outliner_active(bContext *C)
{
- if(ed_spacetype_test(C, SPACE_OOPS)) {
- SpaceOops *so= (SpaceOops *)CTX_wm_space_data(C);
- return (so->type == SO_OUTLINER);
- }
- return 0;
+ return ed_spacetype_test(C, SPACE_OUTLINER);
}
int ED_operator_file_active(bContext *C)
@@ -220,11 +217,14 @@ int ED_operator_uvedit(bContext *C)
EditMesh *em= NULL;
if(obedit && obedit->type==OB_MESH)
- em= ((Mesh *)obedit->data)->edit_mesh;
+ em= EM_GetEditMesh((Mesh *)obedit->data);
- if(em && (em->faces.first) && (CustomData_has_layer(&em->fdata, CD_MTFACE)))
+ if(em && (em->faces.first) && (CustomData_has_layer(&em->fdata, CD_MTFACE))) {
+ EM_EndEditMesh(obedit->data, em);
return 1;
+ }
+ EM_EndEditMesh(obedit->data, em);
return 0;
}
@@ -234,11 +234,14 @@ int ED_operator_uvmap(bContext *C)
EditMesh *em= NULL;
if(obedit && obedit->type==OB_MESH)
- em= ((Mesh *)obedit->data)->edit_mesh;
+ em= EM_GetEditMesh((Mesh *)obedit->data);
- if(em && (em->faces.first))
+ if(em && (em->faces.first)) {
+ EM_EndEditMesh(obedit->data, em);
return 1;
+ }
+ EM_EndEditMesh(obedit->data, em);
return 0;
}
@@ -438,14 +441,122 @@ void SCREEN_OT_actionzone(wmOperatorType *ot)
RNA_def_int(ot->srna, "modifier", 0, 0, 2, "modifier", "modifier state", 0, 2);
}
+/* ************** swap area operator *********************************** */
-/* *********** Duplicate area as new window operator ****************** */
+/* operator state vars used:
+ sa1 start area
+ sa2 area to swap with
+
+ functions:
+
+ init() set custom data for operator, based on actionzone event custom data
+
+ cancel() cancel the operator
+
+ exit() cleanup, send notifier
+
+ callbacks:
+
+ invoke() gets called on shift+lmb drag in actionzone
+ call init(), add handler
+
+ modal() accept modal events while doing it
+
+*/
+
+typedef struct sAreaSwapData {
+ ScrArea *sa1, *sa2;
+} sAreaSwapData;
+static int area_swap_init(bContext *C, wmOperator *op, wmEvent *event)
+{
+ sAreaSwapData *sd= NULL;
+ sActionzoneData *sad= event->customdata;
+
+ if(sad==NULL || sad->sa1==NULL)
+ return 0;
+
+ sd= MEM_callocN(sizeof(sAreaSwapData), "sAreaSwapData");
+ sd->sa1= sad->sa1;
+ sd->sa2= sad->sa2;
+ op->customdata= sd;
+
+ return 1;
+}
+
+
+static void area_swap_exit(bContext *C, wmOperator *op)
+{
+ if(op->customdata)
+ MEM_freeN(op->customdata);
+ op->customdata= NULL;
+}
+
+static int area_swap_cancel(bContext *C, wmOperator *op)
+{
+ area_swap_exit(C, op);
+ return OPERATOR_CANCELLED;
+}
+
+static int area_swap_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+
+ if(!area_swap_init(C, op, event))
+ return OPERATOR_PASS_THROUGH;
+
+ /* add modal handler */
+ WM_cursor_modal(CTX_wm_window(C), BC_SWAPAREA_CURSOR);
+ WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+
+ return OPERATOR_RUNNING_MODAL;
+
+}
+
+static int area_swap_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+ sActionzoneData *sad= op->customdata;
+
+ switch(event->type) {
+ case MOUSEMOVE:
+ /* second area, for join */
+ sad->sa2= screen_areahascursor(CTX_wm_screen(C), event->x, event->y);
+ break;
+ case LEFTMOUSE: /* release LMB */
+ if(event->val==0) {
+ if(sad->sa1 == sad->sa2) {
+
+ return area_swap_cancel(C, op);
+ }
+ ED_area_swapspace(C, sad->sa1, sad->sa2);
+
+ area_swap_exit(C, op);
+
+ WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
+ }
+ break;
+
+ case ESCKEY:
+ return area_swap_cancel(C, op);
+ }
+ return OPERATOR_RUNNING_MODAL;
+}
+
+void SCREEN_OT_area_swap(wmOperatorType *ot)
+{
+ ot->name= "Swap areas";
+ ot->idname= "SCREEN_OT_area_swap";
+
+ ot->invoke= area_swap_invoke;
+ ot->modal= area_swap_modal;
+ ot->poll= ED_operator_areaactive;
+}
+
+/* *********** Duplicate area as new window operator ****************** */
/* operator callback */
-/* (ton) removed attempt to merge ripped area with another, don't think this is desired functionality.
-conventions: 'atomic' and 'dont think for user' :) */
-static int screen_area_dupli_new_op(bContext *C, wmOperator *op, wmEvent *event)
+static int area_dupli_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
wmWindow *newwin, *win;
bScreen *newsc, *sc;
@@ -454,15 +565,17 @@ static int screen_area_dupli_new_op(bContext *C, wmOperator *op, wmEvent *event)
sActionzoneData *sad= event->customdata;
if(sad==NULL)
- return OPERATOR_CANCELLED;
+ return OPERATOR_PASS_THROUGH;
win= CTX_wm_window(C);
sc= CTX_wm_screen(C);
sa= sad->sa1;
/* poll() checks area context, but we don't accept full-area windows */
- if(sc->full != SCREENNORMAL)
+ if(sc->full != SCREENNORMAL) {
+ actionzone_exit(C, op);
return OPERATOR_CANCELLED;
+ }
/* adds window to WM */
rect= sa->totrct;
@@ -478,16 +591,18 @@ static int screen_area_dupli_new_op(bContext *C, wmOperator *op, wmEvent *event)
/* screen, areas init */
WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL);
+
+ actionzone_exit(C, op);
return OPERATOR_FINISHED;
}
-void SCREEN_OT_area_dupli_new(wmOperatorType *ot)
+void SCREEN_OT_area_dupli(wmOperatorType *ot)
{
ot->name= "Duplicate Area into New Window";
- ot->idname= "SCREEN_OT_area_dupli_new";
+ ot->idname= "SCREEN_OT_area_dupli";
- ot->invoke= screen_area_dupli_new_op;
+ ot->invoke= area_dupli_invoke;
ot->poll= ED_operator_areaactive;
}
@@ -1527,6 +1642,7 @@ static uiBlock *ui_block_create_redo_last(bContext *C, ARegion *ar, void *arg_op
int height;
block= uiBeginBlock(C, ar, "redo_last_popup", UI_EMBOSS, UI_HELV);
+ uiBlockClearFlag(block, UI_BLOCK_LOOP);
uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1);
uiBlockSetFunc(block, redo_last_cb, arg_op, NULL);
@@ -1536,7 +1652,7 @@ static uiBlock *ui_block_create_redo_last(bContext *C, ARegion *ar, void *arg_op
}
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
- height= uiDefAutoButsRNA(block, &ptr);
+ height= uiDefAutoButsRNA(C, block, &ptr);
uiPopupBoundsBlock(block, 4.0f, 0, 0);
uiEndBlock(C, block);
@@ -2308,7 +2424,8 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(SCREEN_OT_area_move);
WM_operatortype_append(SCREEN_OT_area_split);
WM_operatortype_append(SCREEN_OT_area_join);
- WM_operatortype_append(SCREEN_OT_area_dupli_new);
+ WM_operatortype_append(SCREEN_OT_area_dupli);
+ WM_operatortype_append(SCREEN_OT_area_swap);
WM_operatortype_append(SCREEN_OT_region_split);
WM_operatortype_append(SCREEN_OT_region_foursplit);
WM_operatortype_append(SCREEN_OT_region_flip);
@@ -2339,16 +2456,16 @@ void ED_keymap_screen(wmWindowManager *wm)
/* standard timers */
WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", TIMER0, KM_ANY, KM_ANY, 0);
- /*WM_keymap_verify_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0);*/
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "modifier", 0);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "modifier", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_actionzone", LEFTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "modifier", 2);
/* screen tools */
WM_keymap_verify_item(keymap, "SCREEN_OT_area_move", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_verify_item(keymap, "SCREEN_OT_area_split", EVT_ACTIONZONE, 0, KM_ANY, 0);
- WM_keymap_verify_item(keymap, "SCREEN_OT_area_join", EVT_ACTIONZONE, 0, KM_ANY, 0);
- WM_keymap_verify_item(keymap, "SCREEN_OT_area_dupli_new", EVT_ACTIONZONE, 0, KM_ANY, 0);
+ WM_keymap_verify_item(keymap, "SCREEN_OT_area_split", EVT_ACTIONZONE, 0, 0, 0);
+ WM_keymap_verify_item(keymap, "SCREEN_OT_area_join", EVT_ACTIONZONE, 0, 0, 0);
+ WM_keymap_verify_item(keymap, "SCREEN_OT_area_dupli", EVT_ACTIONZONE, 0, KM_SHIFT, 0);
+ WM_keymap_verify_item(keymap, "SCREEN_OT_area_swap", EVT_ACTIONZONE, 0, KM_ALT, 0);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", RIGHTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1);
RNA_int_set(WM_keymap_add_item(keymap, "SCREEN_OT_screen_set", LEFTARROWKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1);
WM_keymap_add_item(keymap, "SCREEN_OT_screen_full_area", UPARROWKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index fd6719d63bb..1ce5f3a348b 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -5048,11 +5048,11 @@ static int set_clone_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
return set_clone_cursor_exec(C, op);
}
-void PAINT_OT_set_clone_cursor(wmOperatorType *ot)
+void PAINT_OT_clone_cursor_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Clone Cursor";
- ot->idname= "PAINT_OT_set_clone_cursor";
+ ot->idname= "PAINT_OT_clone_cursor_set";
/* api callbacks */
ot->exec= set_clone_cursor_exec;
@@ -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/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 7e1ecd9629a..b630975c934 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -50,7 +50,7 @@ void PAINT_OT_image_paint(struct wmOperatorType *ot);
void PAINT_OT_image_paint_radial_control(struct wmOperatorType *ot);
void PAINT_OT_grab_clone(struct wmOperatorType *ot);
void PAINT_OT_sample_color(struct wmOperatorType *ot);
-void PAINT_OT_set_clone_cursor(struct wmOperatorType *ot);
+void PAINT_OT_clone_cursor_set(struct wmOperatorType *ot);
void PAINT_OT_texture_paint_toggle(struct wmOperatorType *ot);
void PAINT_OT_texture_paint_radial_control(struct wmOperatorType *ot);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 6b3a36de826..e9263ddabf0 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -17,7 +17,7 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_image_paint_radial_control);
WM_operatortype_append(PAINT_OT_sample_color);
WM_operatortype_append(PAINT_OT_grab_clone);
- WM_operatortype_append(PAINT_OT_set_clone_cursor);
+ WM_operatortype_append(PAINT_OT_clone_cursor_set);
/* weight */
WM_operatortype_append(PAINT_OT_weight_paint_toggle);
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index e0ac3c94109..85ea55331dc 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -11,6 +11,7 @@
#include "BLI_arithb.h"
+#include "BKE_brush.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_utildefines.h"
@@ -159,7 +160,7 @@ int imapaint_pick_face(ViewContext *vc, Mesh *me, int *mval, unsigned int *index
/* used for both 3d view and image window */
void paint_sample_color(Scene *scene, ARegion *ar, int x, int y) /* frontbuf */
{
- VPaint *vp= scene->toolsettings->vpaint;
+ Brush **br = current_brush_source(scene);
unsigned int col;
char *cp;
@@ -172,20 +173,10 @@ void paint_sample_color(Scene *scene, ARegion *ar, int x, int y) /* frontbuf */
cp = (char *)&col;
- if(G.f & (G_VERTEXPAINT|G_WEIGHTPAINT)) {
- vp->r= cp[0]/255.0f;
- vp->g= cp[1]/255.0f;
- vp->b= cp[2]/255.0f;
- }
- else {
- Brush *brush= scene->toolsettings->imapaint.brush;
-
- if(brush) {
- brush->rgb[0]= cp[0]/255.0f;
- brush->rgb[1]= cp[1]/255.0f;
- brush->rgb[2]= cp[2]/255.0f;
-
- }
+ if(br && *br) {
+ (*br)->rgb[0]= cp[0]/255.0f;
+ (*br)->rgb[1]= cp[1]/255.0f;
+ (*br)->rgb[2]= cp[2]/255.0f;
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index a9860402f74..0c20c0cc1cf 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -64,6 +64,7 @@
#include "RNA_access.h"
#include "BKE_armature.h"
+#include "BKE_brush.h"
#include "BKE_DerivedMesh.h"
#include "BKE_cloth.h"
#include "BKE_context.h"
@@ -74,7 +75,6 @@
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
-#include "BKE_multires.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
@@ -143,7 +143,7 @@ static void vp_drawcursor(bContext *C, int x, int y, void *customdata)
glColor4ub(255, 255, 255, 128);
glEnable( GL_LINE_SMOOTH );
glEnable(GL_BLEND);
- glutil_draw_lined_arc(0.0, M_PI*2.0, ts->vpaint->size, 40);
+ glutil_draw_lined_arc(0.0, M_PI*2.0, ts->vpaint->brush->size, 40);
glDisable(GL_BLEND);
glDisable( GL_LINE_SMOOTH );
@@ -159,7 +159,7 @@ static void wp_drawcursor(bContext *C, int x, int y, void *customdata)
glColor4ub(200, 200, 255, 128);
glEnable( GL_LINE_SMOOTH );
glEnable(GL_BLEND);
- glutil_draw_lined_arc(0.0, M_PI*2.0, ts->wpaint->size, 40);
+ glutil_draw_lined_arc(0.0, M_PI*2.0, ts->wpaint->brush->size, 40);
glDisable(GL_BLEND);
glDisable( GL_LINE_SMOOTH );
@@ -186,20 +186,13 @@ static VPaint *new_vpaint(int wpaint)
{
VPaint *vp= MEM_callocN(sizeof(VPaint), "VPaint");
- vp->r= 1.0f;
- vp->g= 1.0f;
- vp->b= 1.0f;
- vp->a= 0.2f;
- vp->size= 25.0f;
vp->gamma= vp->mul= 1.0f;
vp->flag= VP_AREA+VP_SOFT+VP_SPRAY;
- if(wpaint) {
- vp->weight= 1.0f;
- vp->a= 1.0f;
+ if(wpaint)
vp->flag= VP_AREA+VP_SOFT;
- }
+
return vp;
}
@@ -239,7 +232,7 @@ unsigned int rgba_to_mcol(float r, float g, float b, float a)
static unsigned int vpaint_get_current_col(VPaint *vp)
{
- return rgba_to_mcol(vp->r, vp->g, vp->b, 1.0f);
+ return rgba_to_mcol(vp->brush->rgb[0], vp->brush->rgb[1], vp->brush->rgb[2], 1.0f);
}
void do_shared_vertexcol(Mesh *me)
@@ -334,8 +327,6 @@ void make_vertexcol(Scene *scene, int shade) /* single ob */
else
memset(me->mcol, 255, 4*sizeof(MCol)*me->totface);
-// XXX if (me->mr) multires_load_cols(me);
-
DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
}
@@ -434,7 +425,7 @@ void clear_vpaint_selectedfaces(Scene *scene)
void clear_wpaint_selectedfaces(Scene *scene)
{
VPaint *wp= scene->toolsettings->wpaint;
- float paintweight= wp->weight;
+ float paintweight= wp->brush->alpha;
Mesh *me;
MFace *mface;
Object *ob;
@@ -742,7 +733,7 @@ static void vpaint_blend(VPaint *vp, unsigned int *col, unsigned int *colorig, u
unsigned int testcol=0, a;
char *cp, *ct, *co;
- alpha= (int)(255.0*vp->a);
+ alpha= (int)(255.0*vp->brush->alpha);
if(vp->mode==VP_MIX || vp->mode==VP_BLUR) testcol= mcol_blend( *colorig, paintcol, alpha);
else if(vp->mode==VP_ADD) testcol= mcol_add( *colorig, paintcol, alpha);
@@ -818,14 +809,14 @@ static int calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, float vpimat[][3], floa
dy= mval[1]-vertco[1];
fac= sqrt(dx*dx + dy*dy);
- if(fac > vp->size) return 0;
+ if(fac > vp->brush->size) return 0;
if(vp->flag & VP_HARD)
alpha= 255;
else
- alpha= 255.0*vp->a*(1.0-fac/vp->size);
+ alpha= 255.0*vp->brush->alpha*(1.0-fac/vp->brush->size);
}
else {
- alpha= 255.0*vp->a;
+ alpha= 255.0*vp->brush->alpha;
}
if(vp->flag & VP_NORMALS) {
@@ -872,7 +863,7 @@ static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float
if((wp->flag & VP_SPRAY)==0) {
float testw=0.0f;
- alpha= wp->a;
+ alpha= wp->brush->alpha;
if(wp->mode==VP_MIX || wp->mode==VP_BLUR)
testw = paintval*alpha + uw->weight*(1.0-alpha);
else if(wp->mode==VP_ADD)
@@ -1028,20 +1019,20 @@ void sample_wpaint(Scene *scene, ARegion *ar, View3D *v3d, int mode)
fac= MIN4(w1, w2, w3, w4);
if(w1==fac) {
dw= get_defweight(me->dvert+mface->v1, ob->actdef-1);
- if(dw) wp->weight= dw->weight; else wp->weight= 0.0f;
+ if(dw) wp->brush->alpha= dw->weight; else wp->brush->alpha= 0.0f;
}
else if(w2==fac) {
dw= get_defweight(me->dvert+mface->v2, ob->actdef-1);
- if(dw) wp->weight= dw->weight; else wp->weight= 0.0f;
+ if(dw) wp->brush->alpha= dw->weight; else wp->brush->alpha= 0.0f;
}
else if(w3==fac) {
dw= get_defweight(me->dvert+mface->v3, ob->actdef-1);
- if(dw) wp->weight= dw->weight; else wp->weight= 0.0f;
+ if(dw) wp->brush->alpha= dw->weight; else wp->brush->alpha= 0.0f;
}
else if(w4==fac) {
if(mface->v4) {
dw= get_defweight(me->dvert+mface->v4, ob->actdef-1);
- if(dw) wp->weight= dw->weight; else wp->weight= 0.0f;
+ if(dw) wp->brush->alpha= dw->weight; else wp->brush->alpha= 0.0f;
}
}
}
@@ -1120,6 +1111,8 @@ static int set_wpaint(bContext *C, wmOperator *op) /* toggle */
if(wp==NULL)
wp= scene->toolsettings->wpaint= new_vpaint(1);
+
+ brush_check_exists(&wp->brush);
toggle_paint_cursor(C, 1);
@@ -1178,36 +1171,10 @@ void PAINT_OT_weight_paint_toggle(wmOperatorType *ot)
/* ************ paint radial controls *************/
-void paint_radial_control_invoke(wmOperator *op, VPaint *vp)
-{
- int mode = RNA_int_get(op->ptr, "mode");
- float original_value;
-
- if(mode == WM_RADIALCONTROL_SIZE)
- original_value = vp->size;
- else if(mode == WM_RADIALCONTROL_STRENGTH)
- original_value = vp->a;
-
- RNA_float_set(op->ptr, "initial_value", original_value);
-}
-
-static int paint_radial_control_exec(wmOperator *op, VPaint *vp)
-{
- int mode = RNA_int_get(op->ptr, "mode");
- float new_value = RNA_float_get(op->ptr, "new_value");
-
- if(mode == WM_RADIALCONTROL_SIZE)
- vp->size = new_value;
- else if(mode == WM_RADIALCONTROL_STRENGTH)
- vp->a = new_value;
-
- return OPERATOR_FINISHED;
-}
-
static int vpaint_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
toggle_paint_cursor(C, 0);
- paint_radial_control_invoke(op, CTX_data_scene(C)->toolsettings->vpaint);
+ brush_radial_control_invoke(op, CTX_data_scene(C)->toolsettings->vpaint->brush, 1);
return WM_radial_control_invoke(C, op, event);
}
@@ -1221,16 +1188,13 @@ static int vpaint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve
static int vpaint_radial_control_exec(bContext *C, wmOperator *op)
{
- int ret = paint_radial_control_exec(op, CTX_data_scene(C)->toolsettings->vpaint);
- char str[256];
- WM_radial_control_string(op, str, 256);
- return ret;
+ return brush_radial_control_exec(op, CTX_data_scene(C)->toolsettings->vpaint->brush, 1);
}
static int wpaint_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
toggle_paint_cursor(C, 1);
- paint_radial_control_invoke(op, CTX_data_scene(C)->toolsettings->wpaint);
+ brush_radial_control_invoke(op, CTX_data_scene(C)->toolsettings->wpaint->brush, 1);
return WM_radial_control_invoke(C, op, event);
}
@@ -1244,10 +1208,7 @@ static int wpaint_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve
static int wpaint_radial_control_exec(bContext *C, wmOperator *op)
{
- int ret = paint_radial_control_exec(op, CTX_data_scene(C)->toolsettings->wpaint);
- char str[256];
- WM_radial_control_string(op, str, 256);
- return ret;
+ return brush_radial_control_exec(op, CTX_data_scene(C)->toolsettings->wpaint->brush, 1);
}
void PAINT_OT_weight_paint_radial_control(wmOperatorType *ot)
@@ -1347,7 +1308,7 @@ static int wpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
Object *ob= vc->obact;
Mesh *me= ob->data;
float mat[4][4];
- float paintweight= wp->weight;
+ float paintweight= wp->brush->alpha;
int *indexar= wpd->indexar;
int totindex, index, alpha, totw;
short mval[2];
@@ -1366,7 +1327,7 @@ static int wpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
/* which faces are involved */
if(wp->flag & VP_AREA) {
- totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], wp->size);
+ totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], wp->brush->size);
}
else {
indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]);
@@ -1404,7 +1365,7 @@ static int wpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
if(wp->mode==VP_BLUR)
paintweight= 0.0f;
else
- paintweight= wp->weight;
+ paintweight= wp->brush->alpha;
for(index=0; index<totindex; index++) {
if(indexar[index] && indexar[index]<=me->totface) {
@@ -1655,6 +1616,7 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */
vp= scene->toolsettings->vpaint= new_vpaint(0);
toggle_paint_cursor(C, 0);
+ brush_check_exists(&scene->toolsettings->vpaint->brush);
}
if (me)
@@ -1765,7 +1727,7 @@ static int vpaint_modal(bContext *C, wmOperator *op, wmEvent *event)
/* which faces are involved */
if(vp->flag & VP_AREA) {
- totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], vp->size);
+ totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], vp->brush->size);
}
else {
indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 40aaee758b9..8f1e3826314 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1275,11 +1275,7 @@ static int sculpt_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve
static int sculpt_radial_control_exec(bContext *C, wmOperator *op)
{
- int ret = brush_radial_control_exec(op, CTX_data_scene(C)->toolsettings->sculpt->brush, 1);
- char str[256];
- WM_radial_control_string(op, str, 256);
-
- return ret;
+ return brush_radial_control_exec(op, CTX_data_scene(C)->toolsettings->sculpt->brush, 1);
}
static void SCULPT_OT_radial_control(wmOperatorType *ot)
@@ -1662,12 +1658,10 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op)
toggle_paint_cursor(C);
+ /* If there's no brush, create one */
+ brush_check_exists(&ts->sculpt->brush);
-
- /* XXX: testing */
- /* Needed for testing, if there's no brush then create one */
- ts->sculpt->brush = add_brush("test brush");
- /* Also for testing, set the brush texture to the first available one */
+ /* XXX: testing: set the brush texture to the first available one */
if(G.main->tex.first) {
Tex *tex = G.main->tex.first;
if(tex->type) {
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 53403a4e699..adb5d749f71 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -172,11 +172,11 @@ static int actkeys_previewrange_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ACT_OT_set_previewrange (wmOperatorType *ot)
+void ACT_OT_previewrange_set (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Auto-Set Preview Range";
- ot->idname= "ACT_OT_set_previewrange";
+ ot->idname= "ACT_OT_previewrange_set";
/* api callbacks */
ot->exec= actkeys_previewrange_exec;
@@ -248,7 +248,7 @@ static short copy_action_keys (bAnimContext *ac)
free_anim_copybuf();
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* copy keyframes */
@@ -852,11 +852,11 @@ static int actkeys_expo_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ACT_OT_keyframes_extrapolation_type (wmOperatorType *ot)
+void ACT_OT_keyframes_extrapolation_type_set (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Keyframe Extrapolation";
- ot->idname= "ACT_OT_keyframes_extrapolation_type";
+ ot->idname= "ACT_OT_keyframes_extrapolation_type_set";
/* api callbacks */
ot->invoke= WM_menu_invoke;
@@ -1028,11 +1028,11 @@ static int actkeys_handletype_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ACT_OT_keyframes_handletype (wmOperatorType *ot)
+void ACT_OT_keyframes_handle_type_set (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Keyframe Handle Type";
- ot->idname= "ACT_OT_keyframes_handletype";
+ ot->idname= "ACT_OT_keyframes_handle_type_set";
/* api callbacks */
ot->invoke= WM_menu_invoke;
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index 7d21ac263c3..b4d2528b3b4 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -53,9 +53,9 @@ void action_header_buttons(const struct bContext *C, struct ARegion *ar);
/* ***************************************** */
/* action_select.c */
-void ACT_OT_keyframes_deselectall(struct wmOperatorType *ot);
-void ACT_OT_keyframes_borderselect(struct wmOperatorType *ot);
-void ACT_OT_keyframes_columnselect(struct wmOperatorType *ot);
+void ACT_OT_keyframes_select_all_toggle(struct wmOperatorType *ot);
+void ACT_OT_keyframes_select_border(struct wmOperatorType *ot);
+void ACT_OT_keyframes_select_column(struct wmOperatorType *ot);
void ACT_OT_keyframes_clickselect(struct wmOperatorType *ot);
/* defines for left-right select tool */
@@ -77,7 +77,7 @@ enum {
/* ***************************************** */
/* action_edit.c */
-void ACT_OT_set_previewrange(struct wmOperatorType *ot);
+void ACT_OT_previewrange_set(struct wmOperatorType *ot);
void ACT_OT_view_all(struct wmOperatorType *ot);
void ACT_OT_keyframes_copy(struct wmOperatorType *ot);
@@ -89,9 +89,9 @@ void ACT_OT_keyframes_delete(struct wmOperatorType *ot);
void ACT_OT_keyframes_clean(struct wmOperatorType *ot);
void ACT_OT_keyframes_sample(struct wmOperatorType *ot);
-void ACT_OT_keyframes_handletype(struct wmOperatorType *ot);
+void ACT_OT_keyframes_handle_type_set(struct wmOperatorType *ot);
void ACT_OT_keyframes_interpolation_type(struct wmOperatorType *ot);
-void ACT_OT_keyframes_extrapolation_type(struct wmOperatorType *ot);
+void ACT_OT_keyframes_extrapolation_type_set(struct wmOperatorType *ot);
void ACT_OT_keyframes_cfrasnap(struct wmOperatorType *ot);
void ACT_OT_keyframes_snap(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 081b5539524..eedf4868391 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -64,17 +64,17 @@ void action_operatortypes(void)
/* keyframes */
/* selection */
WM_operatortype_append(ACT_OT_keyframes_clickselect);
- WM_operatortype_append(ACT_OT_keyframes_deselectall);
- WM_operatortype_append(ACT_OT_keyframes_borderselect);
- WM_operatortype_append(ACT_OT_keyframes_columnselect);
+ WM_operatortype_append(ACT_OT_keyframes_select_all_toggle);
+ WM_operatortype_append(ACT_OT_keyframes_select_border);
+ WM_operatortype_append(ACT_OT_keyframes_select_column);
/* editing */
WM_operatortype_append(ACT_OT_keyframes_snap);
WM_operatortype_append(ACT_OT_keyframes_mirror);
WM_operatortype_append(ACT_OT_keyframes_cfrasnap);
- WM_operatortype_append(ACT_OT_keyframes_handletype);
+ WM_operatortype_append(ACT_OT_keyframes_handle_type_set);
WM_operatortype_append(ACT_OT_keyframes_interpolation_type);
- WM_operatortype_append(ACT_OT_keyframes_extrapolation_type);
+ WM_operatortype_append(ACT_OT_keyframes_extrapolation_type_set);
WM_operatortype_append(ACT_OT_keyframes_sample);
WM_operatortype_append(ACT_OT_keyframes_clean);
WM_operatortype_append(ACT_OT_keyframes_delete);
@@ -83,7 +83,7 @@ void action_operatortypes(void)
WM_operatortype_append(ACT_OT_keyframes_copy);
WM_operatortype_append(ACT_OT_keyframes_paste);
- WM_operatortype_append(ACT_OT_set_previewrange);
+ WM_operatortype_append(ACT_OT_previewrange_set);
WM_operatortype_append(ACT_OT_view_all);
}
@@ -95,23 +95,23 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
/* click-select */
// TODO: column to alt, left-right to ctrl (for select-linked consistency)
WM_keymap_add_item(keymap, "ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "column_select", 1);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend_select", 1);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "column", 1);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "left_right", ACTKEYS_LRSEL_TEST);
/* deselect all */
- WM_keymap_add_item(keymap, "ACT_OT_keyframes_deselectall", AKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_deselectall", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
+ WM_keymap_add_item(keymap, "ACT_OT_keyframes_select_all_toggle", AKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
/* borderselect */
- WM_keymap_add_item(keymap, "ACT_OT_keyframes_borderselect", BKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_borderselect", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1);
+ WM_keymap_add_item(keymap, "ACT_OT_keyframes_select_border", BKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_select_border", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1);
/* column select */
- RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, 0, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_KEYS);
- RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_CFRA);
- RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_COLUMN);
- RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_BETWEEN);
+ RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_KEYS);
+ RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_select_column", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_CFRA);
+ RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_select_column", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_COLUMN);
+ RNA_enum_set(WM_keymap_add_item(keymap, "ACT_OT_keyframes_select_column", KKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", ACTKEYS_COLUMNSEL_MARKERS_BETWEEN);
/* action_edit.c */
/* snap - current frame to selected keys */
@@ -122,9 +122,9 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
WM_keymap_add_item(keymap, "ACT_OT_keyframes_mirror", MKEY, KM_PRESS, KM_SHIFT, 0);
/* menu + set setting */
- WM_keymap_add_item(keymap, "ACT_OT_keyframes_handletype", HKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ACT_OT_keyframes_handle_type_set", HKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ACT_OT_keyframes_interpolation_type", TKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "ACT_OT_keyframes_extrapolation_type", EKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "ACT_OT_keyframes_extrapolation_type_set", EKEY, KM_PRESS, KM_SHIFT, 0);
/* destructive */
WM_keymap_add_item(keymap, "ACT_OT_keyframes_clean", OKEY, KM_PRESS, 0, 0);
@@ -141,7 +141,7 @@ static void action_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
WM_keymap_add_item(keymap, "ACT_OT_keyframes_paste", VKEY, KM_PRESS, KM_CTRL, 0);
/* auto-set range */
- WM_keymap_add_item(keymap, "ACT_OT_set_previewrange", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ WM_keymap_add_item(keymap, "ACT_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
WM_keymap_add_item(keymap, "ACT_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
/* transform system */
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 5cf92abb664..5fb39376fd0 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -328,11 +328,11 @@ static int actkeys_deselectall_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ACT_OT_keyframes_deselectall (wmOperatorType *ot)
+void ACT_OT_keyframes_select_all_toggle (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select All";
- ot->idname= "ACT_OT_keyframes_deselectall";
+ ot->idname= "ACT_OT_keyframes_select_all_toggle";
/* api callbacks */
ot->exec= actkeys_deselectall_exec;
@@ -487,11 +487,11 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ACT_OT_keyframes_borderselect(wmOperatorType *ot)
+void ACT_OT_keyframes_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Border Select";
- ot->idname= "ACT_OT_keyframes_borderselect";
+ ot->idname= "ACT_OT_keyframes_select_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
@@ -723,11 +723,11 @@ static int actkeys_columnselect_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void ACT_OT_keyframes_columnselect (wmOperatorType *ot)
+void ACT_OT_keyframes_select_column (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select All";
- ot->idname= "ACT_OT_keyframes_columnselect";
+ ot->idname= "ACT_OT_keyframes_select_column";
/* api callbacks */
ot->exec= actkeys_columnselect_exec;
@@ -1067,7 +1067,7 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *even
/* select mode is either replace (deselect all, then add) or add/extend */
// XXX this is currently only available for normal select only
- if (RNA_boolean_get(op->ptr, "extend_select"))
+ if (RNA_boolean_get(op->ptr, "extend"))
selectmode= SELECT_INVERT;
else
selectmode= SELECT_REPLACE;
@@ -1085,7 +1085,7 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *even
selectkeys_leftright(&ac, RNA_enum_get(op->ptr, "left_right"), selectmode);
}
- else if (RNA_boolean_get(op->ptr, "column_select")) {
+ else if (RNA_boolean_get(op->ptr, "column")) {
/* select all the keyframes that occur on the same frame as where the mouse clicked */
float x;
@@ -1122,8 +1122,8 @@ void ACT_OT_keyframes_clickselect (wmOperatorType *ot)
/* id-props */
// XXX should we make this into separate operators?
RNA_def_enum(ot->srna, "left_right", NULL /* XXX prop_actkeys_clickselect_items */, 0, "Left Right", ""); // ALTKEY
- RNA_def_boolean(ot->srna, "extend_select", 0, "Extend Select", ""); // SHIFTKEY
- RNA_def_boolean(ot->srna, "column_select", 0, "Column Select", ""); // CTRLKEY
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
+ RNA_def_boolean(ot->srna, "column", 0, "Column Select", ""); // CTRLKEY
}
/* ************************************************************************** */
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_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
index 515083c9fec..40e3564e69b 100644
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ b/source/blender/editors/space_buttons/buttons_header.c
@@ -62,22 +62,44 @@
static void do_viewmenu(bContext *C, void *arg, int event)
{
-
+ SpaceButs *sbuts= (SpaceButs*)CTX_wm_space_data(C);
+ ScrArea *sa= CTX_wm_area(C);
+
+ switch(event) {
+ case 0: /* panel alignment */
+ case 1:
+ case 2:
+ sbuts->align= event;
+ if(event) {
+ sbuts->re_align= 1;
+ // uiAlignPanelStep(sa, 1.0);
+ }
+ break;
+ }
+
+ ED_area_tag_redraw(sa);
}
static uiBlock *dummy_viewmenu(bContext *C, ARegion *ar, void *arg_unused)
{
- ScrArea *curarea= CTX_wm_area(C);
+ SpaceButs *sbuts= (SpaceButs*)CTX_wm_space_data(C);
+ ScrArea *sa= CTX_wm_area(C);
uiBlock *block;
short yco= 0, menuwidth=120;
block= uiBeginBlock(C, ar, "dummy_viewmenu", UI_EMBOSSP, UI_HELV);
uiBlockSetButmFunc(block, do_viewmenu, NULL);
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Nothing yet", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-
- if(curarea->headertype==HEADERTOP) {
+ if (sbuts->align == 1) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Horizontal", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+ else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Horizontal", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+
+ if (sbuts->align == 2) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Vertical", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+ else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Vertical", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+
+ if (sbuts->align == 0) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Free", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+ else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Free", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+
+ if(sa->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
}
else {
diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h
index ffc325e59ab..e979e815e18 100644
--- a/source/blender/editors/space_buttons/buttons_intern.h
+++ b/source/blender/editors/space_buttons/buttons_intern.h
@@ -28,6 +28,10 @@
#ifndef ED_BUTTONS_INTERN_H
#define ED_BUTTONS_INTERN_H
+struct ARegion;
+struct ARegionType;
+struct bContext;
+
/* warning: the values of these defines are used in sbuts->tabs[7] */
/* buts->mainb new */
#define CONTEXT_SCENE 0
@@ -73,8 +77,9 @@
/* internal exports only */
/* image_header.c */
-void buttons_header_buttons(const bContext *C, ARegion *ar);
-void buttons_scene(const bContext *C, ARegion *ar);
+void buttons_header_buttons(const struct bContext *C, struct ARegion *ar);
+void buttons_scene(const struct bContext *C, struct ARegion *ar);
+void buttons_object_register(struct ARegionType *art);
#endif /* ED_BUTTONS_INTERN_H */
diff --git a/source/blender/editors/space_buttons/buttons_object.c b/source/blender/editors/space_buttons/buttons_object.c
new file mode 100644
index 00000000000..965376b731a
--- /dev/null
+++ b/source/blender/editors/space_buttons/buttons_object.c
@@ -0,0 +1,216 @@
+/**
+ * $Id$
+ *
+ * ***** 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 *****
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_group_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+
+#include "BLI_listbase.h"
+
+#include "BKE_context.h"
+#include "BKE_group.h"
+#include "BKE_main.h"
+#include "BKE_screen.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "RNA_access.h"
+
+#include "WM_types.h"
+
+static void object_panel_transform(const bContext *C, Panel *pnl)
+{
+ uiLayout *layout= pnl->layout;
+ Object *ob= CTX_data_active_object(C);
+ PointerRNA obptr;
+
+ RNA_id_pointer_create(&ob->id, &obptr);
+
+ uiTemplateColumn(layout);
+ uiItemR(layout, UI_TSLOT_COLUMN_1, NULL, 0, &obptr, "location");
+ uiItemR(layout, UI_TSLOT_COLUMN_2, NULL, 0, &obptr, "rotation");
+ uiItemR(layout, UI_TSLOT_COLUMN_3, NULL, 0, &obptr, "scale");
+}
+
+static void object_panel_groups(const bContext *C, Panel *pnl)
+{
+ uiLayout *layout= pnl->layout;
+ Main *bmain= CTX_data_main(C);
+ Object *ob= CTX_data_active_object(C);
+ Group *group;
+ PointerRNA obptr, groupptr;
+ uiLayout *sublayout;
+
+ RNA_id_pointer_create(&ob->id, &obptr);
+
+ uiTemplateColumn(layout);
+ uiItemR(layout, UI_TSLOT_COLUMN_1, NULL, 0, &obptr, "pass_index");
+ uiItemR(layout, UI_TSLOT_COLUMN_2, NULL, 0, &obptr, "parent");
+
+ /* uiTemplateLeftRight(layout);
+ uiItemO(layout, UI_TSLOT_LR_LEFT, NULL, 0, "OBJECT_OT_add_group"); */
+
+ for(group=bmain->group.first; group; group=group->id.next) {
+ if(object_in_group(ob, group)) {
+ RNA_id_pointer_create(&group->id, &groupptr);
+
+ sublayout= uiTemplateStack(layout);
+
+ uiTemplateLeftRight(sublayout);
+ uiItemR(sublayout, UI_TSLOT_LR_LEFT, NULL, 0, &groupptr, "name");
+ // uiItemO(sublayout, UI_TSLOT_LR_RIGHT, "", ICON_X, "OBJECT_OT_remove_group");
+
+ uiTemplateColumn(sublayout);
+ uiItemR(sublayout, UI_TSLOT_COLUMN_1, NULL, 0, &groupptr, "layer");
+ uiItemR(sublayout, UI_TSLOT_COLUMN_2, NULL, 0, &groupptr, "dupli_offset");
+ }
+ }
+}
+
+static void object_panel_display(const bContext *C, Panel *pnl)
+{
+ uiLayout *layout= pnl->layout;
+ Object *ob= CTX_data_active_object(C);
+ PointerRNA obptr;
+
+ RNA_id_pointer_create(&ob->id, &obptr);
+
+ uiTemplateColumn(layout);
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Type", 0, &obptr, "max_draw_type");
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "Bounds", 0, &obptr, "draw_bounds_type");
+
+ uiTemplateColumn(layout);
+ uiItemLabel(layout, UI_TSLOT_COLUMN_1, "Extra", 0);
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Name", 0, &obptr, "draw_name");
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Axis", 0, &obptr, "draw_axis");
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Wire", 0, &obptr, "draw_wire");
+ uiItemLabel(layout, UI_TSLOT_COLUMN_2, "", 0);
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "Texture Space", 0, &obptr, "draw_texture_space");
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "X-Ray", 0, &obptr, "x_ray");
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "Transparency", 0, &obptr, "draw_transparent");
+}
+
+static void object_panel_duplication(const bContext *C, Panel *pnl)
+{
+ uiLayout *layout= pnl->layout;
+ Object *ob= CTX_data_active_object(C);
+ PointerRNA obptr;
+
+ RNA_id_pointer_create(&ob->id, &obptr);
+
+ uiTemplateColumn(layout);
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Frames", 0, &obptr, "dupli_frames");
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "Verts", 0, &obptr, "dupli_verts");
+ uiItemR(layout, UI_TSLOT_COLUMN_3, "Faces", 0, &obptr, "dupli_faces");
+ uiItemR(layout, UI_TSLOT_COLUMN_4, "Group", 0, &obptr, "use_dupli_group");
+
+ if(RNA_boolean_get(&obptr, "dupli_frames")) {
+ uiTemplateColumn(layout);
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Start:", 0, &obptr, "dupli_frames_start");
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "End:", 0, &obptr, "dupli_frames_end");
+
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "On:", 0, &obptr, "dupli_frames_on");
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "Off:", 0, &obptr, "dupli_frames_off");
+ }
+}
+
+static void object_panel_animation(const bContext *C, Panel *pnl)
+{
+ uiLayout *layout= pnl->layout;
+ Object *ob= CTX_data_active_object(C);
+ PointerRNA obptr;
+
+ RNA_id_pointer_create(&ob->id, &obptr);
+
+ uiTemplateColumn(layout);
+ uiItemLabel(layout, UI_TSLOT_COLUMN_1, "Time Offset:", 0);
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Edit", 0, &obptr, "time_offset_edit");
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Particle", 0, &obptr, "time_offset_particle");
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Parent", 0, &obptr, "time_offset_parent");
+ uiItemR(layout, UI_TSLOT_COLUMN_1, NULL, 0, &obptr, "slow_parent");
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Offset: ", 0, &obptr, "time_offset");
+
+ uiItemLabel(layout, UI_TSLOT_COLUMN_2, "Tracking:", 0);
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "Axis: ", 0, &obptr, "track_axis");
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "Up Axis: ", 0, &obptr, "up_axis");
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "Rotation", 0, &obptr, "track_rotation");
+}
+
+void buttons_object_register(ARegionType *art)
+{
+ PanelType *pt;
+
+ /* panels: transform */
+ pt= MEM_callocN(sizeof(PanelType), "spacetype buttons panel");
+ pt->idname= "OBJECT_PT_transform";
+ pt->name= "Transform";
+ pt->context= "object";
+ pt->draw= object_panel_transform;
+ BLI_addtail(&art->paneltypes, pt);
+
+ /* panels: groups */
+ pt= MEM_callocN(sizeof(PanelType), "spacetype buttons panel");
+ pt->idname= "OBJECT_PT_groups";
+ pt->name= "Groups";
+ pt->context= "object";
+ pt->draw= object_panel_groups;
+ BLI_addtail(&art->paneltypes, pt);
+
+ /* panels: display */
+ pt= MEM_callocN(sizeof(PanelType), "spacetype buttons panel");
+ pt->idname= "OBJECT_PT_display";
+ pt->name= "Display";
+ pt->context= "object";
+ pt->draw= object_panel_display;
+ BLI_addtail(&art->paneltypes, pt);
+
+ /* panels: duplication */
+ pt= MEM_callocN(sizeof(PanelType), "spacetype buttons panel");
+ pt->idname= "OBJECT_PT_duplication";
+ pt->name= "Duplication";
+ pt->context= "object";
+ pt->draw= object_panel_duplication;
+ BLI_addtail(&art->paneltypes, pt);
+
+ /* panels: animation */
+ pt= MEM_callocN(sizeof(PanelType), "spacetype buttons panel");
+ pt->idname= "OBJECT_PT_animation";
+ pt->name= "Animation";
+ pt->context= "object";
+ pt->draw= object_panel_animation;
+ BLI_addtail(&art->paneltypes, pt);
+}
+
diff --git a/source/blender/editors/space_buttons/buttons_scene.c b/source/blender/editors/space_buttons/buttons_scene.c
index e4cff2f4f06..ca645ab1845 100644
--- a/source/blender/editors/space_buttons/buttons_scene.c
+++ b/source/blender/editors/space_buttons/buttons_scene.c
@@ -266,13 +266,11 @@ static void render_panel_render(const bContext *C, ARegion *ar)
uiDefButBitI(block, TOG, R_RADIO, 0,"Radio", 649,142,38,29, &scene->r.mode, 0, 0, 0, 0, "Enable radiosity rendering");
uiBlockEndAlign(block);
- uiBlockBeginAlign(block);
- uiDefButS(block, ROW,0,"100%", 565,109,122,20,&scene->r.size,1.0,100.0, 0, 0, "Set render size to defined size");
- uiDefButS(block, ROW,0,"75%", 565,88,40,20,&scene->r.size,1.0,75.0, 0, 0, "Set render size to 3/4 of defined size");
- uiDefButS(block, ROW,0,"50%", 606,88,40,20,&scene->r.size,1.0,50.0, 0, 0, "Set render size to 1/2 of defined size");
- uiDefButS(block, ROW,0,"25%", 647,88,40,20,&scene->r.size,1.0,25.0, 0, 0, "Set render size to 1/4 of defined size");
- uiBlockEndAlign(block);
-
+ uiDefButS(block, NUMSLI, 0, "Size %: ",
+ 565,109,122,20,
+ &(scene->r.size), 1.0, 100.0, 0, 0,
+ "Render at percentage of frame size");
+
uiBlockBeginAlign(block);
uiDefButBitI(block, TOG, R_FIELDS, 0,"Fields", 565,55,60,20,&scene->r.mode, 0, 0, 0, 0, "Enables field rendering");
uiDefButBitI(block, TOG, R_ODDFIELD, 0,"Odd", 627,55,39,20,&scene->r.mode, 0, 0, 0, 0, "Enables Odd field first rendering (Default: Even field)");
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index f2134af7424..bae318ff454 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -141,14 +141,13 @@ static SpaceLink *buttons_duplicate(SpaceLink *sl)
return (SpaceLink *)sbutsn;
}
-
-
/* add handlers, stuff you only do once or on area/region changes */
static void buttons_main_area_init(wmWindowManager *wm, ARegion *ar)
{
ListBase *keymap;
-
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
+
+// ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
/* own keymap */
keymap= WM_keymap_listbase(wm, "Buttons", SPACE_BUTS, 0); /* XXX weak? */
@@ -159,37 +158,51 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar)
{
/* draw entirely, view changes should be handled here */
SpaceButs *sbuts= (SpaceButs*)CTX_wm_space_data(C);
- View2D *v2d= &ar->v2d;
- float col[3], fac;
- int align= 0;
-
- /* clear and setup matrix */
- UI_GetThemeColor3fv(TH_BACK, col);
- glClearColor(col[0], col[1], col[2], 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- UI_view2d_view_ortho(C, v2d);
+
+ if(sbuts->mainb == CONTEXT_OBJECT) {
+ int tab= sbuts->tab[CONTEXT_OBJECT];
+ int vertical= (sbuts->align == 2);
+
+ if(tab == TAB_OBJECT_OBJECT)
+ uiRegionPanelLayout(C, ar, vertical, "object");
+ }
+ else {
+ View2D *v2d= &ar->v2d;
+ float col[3], fac;
+ //int align= 0;
+
+ /* clear and setup matrix */
+ UI_GetThemeColor3fv(TH_BACK, col);
+ glClearColor(col[0], col[1], col[2], 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
- /* swapbuffers indicator */
- fac= BLI_frand();
- glColor3f(fac, fac, fac);
- glRecti(20, 2, 30, 12);
-
- /* panels */
- if(sbuts->mainb == CONTEXT_SCENE)
- buttons_scene(C, ar);
-
- if(sbuts->align)
- if(sbuts->re_align || sbuts->mainbo!=sbuts->mainb || sbuts->tabo!=sbuts->tab[sbuts->mainb])
- align= 1;
+ UI_view2d_view_ortho(C, v2d);
- uiDrawPanels(C, align);
- uiMatchPanelsView2d(ar);
-
- /* reset view matrix */
- UI_view2d_view_restore(C);
-
- /* scrollers? */
+ /* swapbuffers indicator */
+ fac= BLI_frand();
+ glColor3f(fac, fac, fac);
+ glRecti(20, v2d->cur.ymin+2, 30, v2d->cur.ymin+12);
+
+ /* panels */
+ if(sbuts->mainb == CONTEXT_SCENE)
+ buttons_scene(C, ar);
+ else
+ drawnewstuff();
+
+#if 0
+ if(sbuts->align)
+ if(sbuts->re_align || sbuts->mainbo!=sbuts->mainb || sbuts->tabo!=sbuts->tab[sbuts->mainb])
+ align= 1;
+#endif
+
+ uiDrawPanels(C, 1); // XXX align);
+ uiMatchPanelsView2d(ar);
+
+ /* reset view matrix */
+ UI_view2d_view_restore(C);
+
+ /* scrollers? */
+ }
}
void buttons_operatortypes(void)
@@ -268,6 +281,8 @@ void ED_spacetype_buttons(void)
art->listener= buttons_area_listener;
art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES;
+ buttons_object_register(art);
+
BLI_addhead(&st->regiontypes, art);
/* regions: header */
@@ -292,7 +307,6 @@ void ED_spacetype_buttons(void)
BLI_addhead(&st->regiontypes, art);
-
BKE_spacetype_register(st);
}
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_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 72da15ccd9d..c65c486d4bb 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -29,6 +29,7 @@
#include <string.h>
#include "BLI_blenlib.h"
+#include "BLI_dynstr.h"
#include "BLI_storage_types.h"
#ifdef WIN32
#include "BLI_winstuff.h"
@@ -36,6 +37,7 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "BMF_Api.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
@@ -76,7 +78,7 @@
#include "file_intern.h" // own include
/* ui geometry */
-#define IMASEL_BUTTONS_HEIGHT 60
+#define IMASEL_BUTTONS_HEIGHT 40
#define TILE_BORDER_X 8
#define TILE_BORDER_Y 8
@@ -88,6 +90,9 @@ enum {
B_FS_PARENT,
} eFile_ButEvents;
+/* XXX very bad, need to check font code */
+static int gFontsize=12;
+
static void do_file_buttons(bContext *C, void *arg, int event)
{
switch(event) {
@@ -111,19 +116,14 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
uiBlock *block;
int loadbutton;
char name[20];
- char *menu;
float slen;
- float parentbut_width = 20;
- float bookmarkbut_width = 0.0f;
- float file_start_width = 0.0f;
-
int filebuty1, filebuty2;
- float xmin = 10;
+ float xmin = 8;
float xmax = ar->winx - 10;
- filebuty1= ar->winy - IMASEL_BUTTONS_HEIGHT;
- filebuty2= filebuty1+IMASEL_BUTTONS_HEIGHT/2 -6;
+ filebuty1= ar->winy - IMASEL_BUTTONS_HEIGHT - 12;
+ filebuty2= filebuty1 + IMASEL_BUTTONS_HEIGHT/2 + 4;
/* HEADER */
sprintf(name, "win %p", ar);
@@ -146,34 +146,28 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
loadbutton= 0;
}
- /* XXX to channel region */
- menu= fsmenu_build_menu();
-
- if (menu[0]&& (params->type != FILE_MAIN)) {
- bookmarkbut_width = parentbut_width;
- file_start_width = parentbut_width;
- }
-
- uiDefBut(block, TEX, 0 /* XXX B_FS_FILENAME */,"", xmin+file_start_width+bookmarkbut_width+2, filebuty1, xmax-xmin-loadbutton-file_start_width-bookmarkbut_width, 21, params->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
- uiDefBut(block, TEX, 0 /* XXX B_FS_DIRNAME */,"", xmin+parentbut_width, filebuty2, xmax-xmin-loadbutton-parentbut_width, 21, params->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
-
+ uiDefBut(block, TEX, 0 /* XXX B_FS_FILENAME */,"", xmin+2, filebuty1, xmax-xmin-loadbutton-4, 21, params->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
+ uiDefBut(block, TEX, 0 /* XXX B_FS_DIRNAME */,"", xmin+2, filebuty2, xmax-xmin-loadbutton-4, 21, params->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
+
if(loadbutton) {
uiSetCurFont(block, UI_HELV);
uiDefBut(block, BUT, B_FS_EXEC, params->title, xmax-loadbutton, filebuty2, loadbutton, 21, params->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
uiDefBut(block, BUT, B_FS_CANCEL, "Cancel", xmax-loadbutton, filebuty1, loadbutton, 21, params->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
}
+#if 0
/* menu[0] = NULL happens when no .Bfs is there, and first time browse
disallow external directory browsing for databrowse */
if(menu[0] && (params->type != FILE_MAIN)) {
- uiDefButS(block, MENU, 0 /* B_FS_DIR_MENU */, menu, xmin, filebuty1, parentbut_width, 21, &params->menu, 0, 0, 0, 0, "");
- uiDefBut(block, BUT, 0 /* B_FS_BOOKMARK */, "B", xmin+22, filebuty1, bookmarkbut_width, 21, 0, 0, 0, 0, 0, "Bookmark current directory");
+ uiDefButS(block, MENU, 0 /* B_FS_DIR_MENU */, menu, xmin, filebuty2, fsmenubut_width, 21, &params->menu, 0, 0, 0, 0, "");
+ uiDefBut(block, BUT, 0 /* B_FS_BOOKMARK */, "B", xmin, filebuty1, bookmarkbut_width, 21, 0, 0, 0, 0, 0, "Bookmark current directory");
}
MEM_freeN(menu);
+#endif
+
- uiDefBut(block, BUT, B_FS_PARENT, "P", xmin, filebuty2, parentbut_width, 21, 0, 0, 0, 0, 0, "Move to the parent directory (PKEY)");
uiEndBlock(C, block);
uiDrawBlock(C, block);
}
@@ -194,28 +188,89 @@ static void draw_tile(short sx, short sy, short width, short height, int colorid
uiRoundBox(sx, sy - height, sx + width, sy, 6);
}
-static float shorten_string(char* string, float w)
+#define FILE_SHORTEN_END 0
+#define FILE_SHORTEN_FRONT 1
+
+static float shorten_string(char* string, float w, int flag)
{
+ char temp[FILE_MAX];
short shortened = 0;
float sw = 0;
-
+ float pad = 0;
+
sw = UI_GetStringWidth(G.font, string,0);
- while (sw>w) {
- int slen = strlen(string);
- string[slen-1] = '\0';
- sw = UI_GetStringWidth(G.font, string,0);
- shortened = 1;
- }
- if (shortened) {
- int slen = strlen(string);
- if (slen > 3) {
- BLI_strncpy(string+slen-3, "...", 4);
+ if (flag == FILE_SHORTEN_FRONT) {
+ char *s = string;
+ BLI_strncpy(temp, "...", 4);
+ pad = UI_GetStringWidth(G.font, temp,0);
+ while (s && (sw+pad>w)) {
+ s++;
+ sw = UI_GetStringWidth(G.font, s,0);
+ shortened = 1;
+ }
+ if (shortened) {
+ int slen = strlen(s);
+ BLI_strncpy(temp+3, s, slen+1);
+ temp[slen+4] = '\0';
+ BLI_strncpy(string, temp, slen+4);
+ }
+ } else {
+ char *s = string;
+ while (sw>w) {
+ int slen = strlen(string);
+ string[slen-1] = '\0';
+ sw = UI_GetStringWidth(G.font, s,0);
+ shortened = 1;
+ }
+ if (shortened) {
+ int slen = strlen(string);
+ if (slen > 3) {
+ BLI_strncpy(string+slen-3, "...", 4);
+ }
}
}
+
return sw;
}
-static void file_draw_string(short sx, short sy, char* string, short width, short height)
+static int get_file_icon(struct direntry *file)
+{
+ if (file->type & S_IFDIR)
+ return ICON_FILE_FOLDER;
+ else if (file->flags & BLENDERFILE)
+ return ICON_FILE_BLEND;
+ else if (file->flags & IMAGEFILE)
+ return ICON_FILE_IMAGE;
+ else if (file->flags & MOVIEFILE)
+ return ICON_FILE_MOVIE;
+ else if (file->flags & PYSCRIPTFILE)
+ return ICON_FILE_SCRIPT;
+ else if (file->flags & PYSCRIPTFILE)
+ return ICON_FILE_SCRIPT;
+ else if (file->flags & SOUNDFILE)
+ return ICON_FILE_SOUND;
+ else if (file->flags & FTFONTFILE)
+ return ICON_FILE_FONT;
+ else
+ return ICON_FILE_BLANK;
+}
+
+static void file_draw_icon(short sx, short sy, int icon, short width, short height)
+{
+ float x,y;
+ int blend=0;
+
+ x = (float)(sx);
+ y = (float)(sy-height);
+
+ if (icon == ICON_FILE_BLANK) blend = -80;
+
+ glEnable(GL_BLEND);
+
+ UI_icon_draw_aspect_blended(x, y, icon, 1.f, blend);
+}
+
+static void file_draw_string(short sx, short sy, const char* string, short width, short height, int flag)
{
short soffs;
char fname[FILE_MAXFILE];
@@ -223,7 +278,8 @@ static void file_draw_string(short sx, short sy, char* string, short width, shor
float x,y;
BLI_strncpy(fname,string, FILE_MAXFILE);
- sw = shorten_string(fname, width );
+ sw = shorten_string(fname, width, flag );
+
soffs = (width - sw) / 2;
x = (float)(sx);
y = (float)(sy-height);
@@ -240,210 +296,131 @@ static void file_draw_string(short sx, short sy, char* string, short width, shor
}
-/* returns max number of rows in view */
-static int file_view_rows(SpaceFile* sfile, View2D *v2d)
-{
- int height= (v2d->cur.ymax - v2d->cur.ymin - 2*sfile->tile_border_y);
- return height / (sfile->tile_h + 2*sfile->tile_border_y);
-}
-
-/* returns max number of columns in view */
-static int file_view_columns(SpaceFile* sfile, View2D *v2d)
-{
- int width= (v2d->cur.xmax - v2d->cur.xmin - 2*sfile->tile_border_x);
- return width / (sfile->tile_w + 2*sfile->tile_border_x);
-}
-
void file_calc_previews(const bContext *C, ARegion *ar)
{
SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
- FileSelectParams* params = ED_fileselect_get_params(sfile);
View2D *v2d= &ar->v2d;
- int width=0, height=0;
- int rows, columns;
-
- if (params->display == FILE_IMGDISPLAY) {
- sfile->prv_w = 96;
- sfile->prv_h = 96;
- sfile->tile_border_x = 4;
- sfile->tile_border_y = 4;
- sfile->prv_border_x = 4;
- sfile->prv_border_y = 4;
- sfile->tile_w = sfile->prv_w + 2*sfile->prv_border_x;
- sfile->tile_h = sfile->prv_h + 4*sfile->prv_border_y + U.fontsize*3/2;
- width= (v2d->cur.xmax - v2d->cur.xmin - 2*sfile->tile_border_x);
- columns= file_view_columns(sfile, v2d);
- if(columns)
- rows= filelist_numfiles(sfile->files)/columns + 1; // XXX dirty, modulo is zero
- else
- rows= filelist_numfiles(sfile->files) + 1; // XXX dirty, modulo is zero
- height= rows*(sfile->tile_h+2*sfile->tile_border_y) + sfile->tile_border_y*2;
- } else {
- sfile->prv_w = 0;
- sfile->prv_h = 0;
- sfile->tile_border_x = 8;
- sfile->tile_border_y = 2;
- sfile->prv_border_x = 0;
- sfile->prv_border_y = 0;
- sfile->tile_w = 240;
- sfile->tile_h = U.fontsize*3/2;
- height= v2d->cur.ymax - v2d->cur.ymin;
- rows = file_view_rows(sfile, v2d);
- if(rows)
- columns = filelist_numfiles(sfile->files)/rows + 1; // XXX dirty, modulo is zero
- else
- columns = filelist_numfiles(sfile->files) + 1; // XXX dirty, modulo is zero
-
- width = columns * (sfile->tile_w + 2*sfile->tile_border_x) + sfile->tile_border_x*2;
- }
-
- UI_view2d_totRect_set(v2d, width, height);
+
+ ED_fileselect_init_layout(sfile, ar);
+ UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
}
void file_draw_previews(const bContext *C, ARegion *ar)
{
SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
FileSelectParams* params= ED_fileselect_get_params(sfile);
+ FileLayout* layout= ED_fileselect_get_layout(sfile, ar);
View2D *v2d= &ar->v2d;
- static double lasttime= 0;
struct FileList* files = sfile->files;
int numfiles;
struct direntry *file;
-
short sx, sy;
- int do_load = 1;
-
ImBuf* imb=0;
int i;
- short type;
int colorid = 0;
- int todo;
int offset;
- int columns;
- int rows;
+ int is_icon;
if (!files) return;
- type = filelist_gettype(files);
- filelist_imgsize(files,sfile->prv_w,sfile->prv_h);
+ filelist_imgsize(files,sfile->layout->prv_w,sfile->layout->prv_h);
numfiles = filelist_numfiles(files);
-
- todo = 0;
- if (lasttime < 0.001) lasttime = PIL_check_seconds_timer();
-
- sx = v2d->cur.xmin + sfile->tile_border_x;
- sy = v2d->cur.ymax - sfile->tile_border_y;
- columns = file_view_columns(sfile, v2d);
- rows = file_view_rows(sfile, v2d);
- offset = columns*(-v2d->cur.ymax-sfile->tile_border_y)/(sfile->tile_h+sfile->tile_border_y);
- offset = (offset/columns-1)*columns;
+ sx = v2d->cur.xmin + layout->tile_border_x;
+ sy = v2d->cur.ymax - layout->tile_border_y;
+
+ offset = ED_fileselect_layout_offset(layout, 0, 0);
if (offset<0) offset=0;
- for (i=offset; (i < numfiles) && (i < (offset+(rows+2)*columns)); ++i)
+ for (i=offset; (i < numfiles) && (i < (offset+(layout->rows+2)*layout->columns)); ++i)
{
- sx = v2d->tot.xmin + sfile->tile_border_x + ((i)%columns)*(sfile->tile_w+2*sfile->tile_border_x);
- sy = v2d->tot.ymax - sfile->tile_border_y - ((i)/columns)*(sfile->tile_h+2*sfile->tile_border_y);
+ ED_fileselect_layout_tilepos(layout, i, &sx, &sy);
+ sx += v2d->tot.xmin+2;
+ sy = v2d->tot.ymax - sy;
file = filelist_file(files, i);
- if (params->active_file == i) {
- colorid = TH_ACTIVE;
- draw_tile(sx - 1, sy, sfile->tile_w + 1, sfile->tile_h, colorid,0);
- } else if (file->flags & ACTIVE) {
+ if (file->flags & ACTIVE) {
colorid = TH_HILITE;
- draw_tile(sx - 1, sy, sfile->tile_w + 1, sfile->tile_h, colorid,0);
- } else {
- colorid = TH_BACK;
- draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid, -5);
+ draw_tile(sx - 1, sy, sfile->layout->tile_w + 1, sfile->layout->tile_h, colorid,0);
+ } else if (params->active_file == i) {
+ colorid = TH_ACTIVE;
+ draw_tile(sx - 1, sy, sfile->layout->tile_w + 1, sfile->layout->tile_h, colorid,0);
}
-
-#if 0
- if ( type == FILE_MAIN) {
- ID *id;
- int icon_id = 0;
- int idcode;
- idcode= groupname_to_code(sfile->dir);
- if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
- id = (ID *)file->poin;
- icon_id = BKE_icon_getid(id);
- }
- if (icon_id) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- if (do_load) {
- UI_icon_draw_preview(sx+2*TILE_BORDER_X, sy-simasel->prv_w-TILE_BORDER_X, icon_id, 0);
- } else {
- UI_icon_draw_preview(sx+2*TILE_BORDER_X, sy-simasel->prv_w-TILE_BORDER_X, icon_id, 1);
- todo++;
- }
-
- glDisable(GL_BLEND);
- }
+
+ if ( (file->flags & IMAGEFILE) /* || (file->flags & MOVIEFILE) */)
+ {
+ filelist_loadimage(files, i);
+ }
+ is_icon = 0;
+ imb = filelist_getimage(files, i);
+ if (!imb) {
+ imb = filelist_geticon(files,i);
+ is_icon = 1;
}
- else {
-#endif
- if ( (file->flags & IMAGEFILE) /* || (file->flags & MOVIEFILE) */)
- {
- if (do_load) {
- filelist_loadimage(files, i);
- } else {
- todo++;
- }
- imb = filelist_getimage(files, i);
- } else {
- imb = filelist_getimage(files, i);
- }
- if (imb) {
- float fx = ((float)sfile->prv_w - (float)imb->x)/2.0f;
- float fy = ((float)sfile->prv_h - (float)imb->y)/2.0f;
- short dx = (short)(fx + 0.5f + sfile->prv_border_x);
- short dy = (short)(fy + 0.5f - sfile->prv_border_y);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- // glaDrawPixelsSafe((float)sx+8 + dx, (float)sy - imgwidth + dy - 8, imb->x, imb->y, imb->x, GL_RGBA, GL_UNSIGNED_BYTE, imb->rect);
- glColor4f(1.0, 1.0, 1.0, 1.0);
- glaDrawPixelsTex((float)sx + dx, (float)sy - sfile->prv_h + dy, imb->x, imb->y,GL_UNSIGNED_BYTE, imb->rect);
- glDisable(GL_BLEND);
- imb = 0;
+ if (imb) {
+ float fx = ((float)layout->prv_w - (float)imb->x)/2.0f;
+ float fy = ((float)layout->prv_h - (float)imb->y)/2.0f;
+ float dx = (fx + 0.5f + sfile->layout->prv_border_x);
+ float dy = (fy + 0.5f - sfile->layout->prv_border_y);
+ short xco = (float)sx + dx;
+ short yco = (float)sy - sfile->layout->prv_h + dy;
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ /* shadow */
+ if (!is_icon && (file->flags & IMAGEFILE))
+ uiDrawBoxShadow(220, xco, yco, xco + imb->x, yco + imb->y);
+
+ glEnable(GL_BLEND);
+
+ /* the image */
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ glaDrawPixelsTex(xco, yco, imb->x, imb->y, GL_UNSIGNED_BYTE, imb->rect);
+
+ /* border */
+ if (!is_icon && (file->flags & IMAGEFILE)) {
+ glColor4f(0.0f, 0.0f, 0.0f, 0.4f);
+ fdrawbox(xco, yco, xco + imb->x, yco + imb->y);
}
-#if 0
- }
-#endif
- if (type == FILE_MAIN) {
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+ glDisable(GL_BLEND);
+ imb = 0;
+ }
+
+ /* shadow */
+ UI_ThemeColorShade(TH_BACK, -20);
+
+
+ if (S_ISDIR(file->type)) {
+ glColor4f(1.0f, 1.0f, 0.9f, 1.0f);
+ }
+ else if (file->flags & IMAGEFILE) {
+ UI_ThemeColor(TH_SEQ_IMAGE);
+ }
+ else if (file->flags & MOVIEFILE) {
+ UI_ThemeColor(TH_SEQ_MOVIE);
+ }
+ else if (file->flags & BLENDERFILE) {
+ UI_ThemeColor(TH_SEQ_SCENE);
}
else {
- if (S_ISDIR(file->type)) {
- glColor4f(1.0f, 1.0f, 0.9f, 1.0f);
- }
- else if (file->flags & IMAGEFILE) {
- UI_ThemeColor(TH_SEQ_IMAGE);
- }
- else if (file->flags & MOVIEFILE) {
- UI_ThemeColor(TH_SEQ_MOVIE);
- }
- else if (file->flags & BLENDERFILE) {
- UI_ThemeColor(TH_SEQ_SCENE);
- }
- else {
- if (params->active_file == i) {
- UI_ThemeColor(TH_GRID); /* grid used for active text */
- } else if (file->flags & ACTIVE) {
- UI_ThemeColor(TH_TEXT_HI);
- } else {
- UI_ThemeColor(TH_TEXT);
- }
+ if (params->active_file == i) {
+ UI_ThemeColor(TH_GRID); /* grid used for active text */
+ } else if (file->flags & ACTIVE) {
+ UI_ThemeColor(TH_TEXT_HI);
+ } else {
+ UI_ThemeColor(TH_TEXT);
}
}
-
- file_draw_string(sx + sfile->prv_border_x, sy+U.fontsize*3/2, file->relname, sfile->tile_w, sfile->tile_h);
+
+ file_draw_string(sx + layout->prv_border_x, sy+4, file->relname, layout->tile_w, layout->tile_h, FILE_SHORTEN_END);
if (!sfile->loadimage_timer)
sfile->loadimage_timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frames/sec. */
}
+ uiSetRoundBox(0);
}
@@ -451,6 +428,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
{
SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
FileSelectParams* params = ED_fileselect_get_params(sfile);
+ FileLayout* layout= ED_fileselect_get_layout(sfile, ar);
+ View2D *v2d= &ar->v2d;
struct FileList* files = sfile->files;
struct direntry *file;
int numfiles;
@@ -459,113 +438,181 @@ void file_draw_list(const bContext *C, ARegion *ar)
int offset;
short type;
int i;
- int rows;
- float sw;
+ float sw, spos;
numfiles = filelist_numfiles(files);
type = filelist_gettype(files);
- sx = ar->v2d.tot.xmin + sfile->tile_border_x/2;
- sy = ar->v2d.cur.ymax - sfile->tile_border_y;
+ sx = ar->v2d.tot.xmin + layout->tile_border_x/2;
+ sy = ar->v2d.cur.ymax - layout->tile_border_y;
- rows = (ar->v2d.cur.ymax - ar->v2d.cur.ymin - 2*sfile->tile_border_y) / (sfile->tile_h+sfile->tile_border_y);
- offset = rows*(sx - sfile->tile_border_x)/(sfile->tile_w+sfile->tile_border_x);
- offset = (offset/rows-1)*rows;
+ offset = ED_fileselect_layout_offset(layout, 0, 0);
+ if (offset<0) offset=0;
+ /* alternating flat shade background */
+ for (i=0; (i <= layout->rows); ++i)
+ {
+ sx = v2d->cur.xmin;
+ sy = v2d->cur.ymax - i*(layout->tile_h+2*layout->tile_border_y) - layout->tile_border_y;
+
+ if (i % 2) {
+ UI_ThemeColor(TH_BACK);
+ } else {
+ UI_ThemeColorShade(TH_BACK, -7);
+ }
+ glRectf(v2d->cur.xmin, sy, v2d->cur.xmax, sy+layout->tile_h+2*layout->tile_border_y);
+ }
+
+ /* vertical column dividers */
+ sx = v2d->tot.xmin;
while (sx < ar->v2d.cur.xmax) {
- sx += (sfile->tile_w+sfile->tile_border_x);
- glColor4ub(0xB0,0xB0,0xB0, 0xFF);
- sdrawline(sx+1, ar->v2d.cur.ymax - sfile->tile_border_y , sx+1, ar->v2d.cur.ymin + sfile->tile_border_y);
- glColor4ub(0x30,0x30,0x30, 0xFF);
- sdrawline(sx, ar->v2d.cur.ymax - sfile->tile_border_y , sx, ar->v2d.cur.ymin + sfile->tile_border_y);
+ sx += (sfile->layout->tile_w+2*sfile->layout->tile_border_x);
+
+ UI_ThemeColorShade(TH_BACK, 30);
+ sdrawline(sx+1, ar->v2d.cur.ymax - layout->tile_border_y , sx+1, ar->v2d.cur.ymin);
+ UI_ThemeColorShade(TH_BACK, -30);
+ sdrawline(sx, ar->v2d.cur.ymax - layout->tile_border_y , sx, ar->v2d.cur.ymin);
}
- sx = ar->v2d.cur.xmin + sfile->tile_border_x;
- sy = ar->v2d.cur.ymax - sfile->tile_border_y;
- if (offset<0) offset=0;
+ sx = ar->v2d.cur.xmin + layout->tile_border_x;
+ sy = ar->v2d.cur.ymax - layout->tile_border_y;
+
for (i=offset; (i < numfiles); ++i)
{
- sy = ar->v2d.tot.ymax-sfile->tile_border_y - (i%rows)*(sfile->tile_h+sfile->tile_border_y);
- sx = 2 + ar->v2d.tot.xmin +sfile->tile_border_x + (i/rows)*(sfile->tile_w+sfile->tile_border_x);
+ ED_fileselect_layout_tilepos(layout, i, &sx, &sy);
+ sx += v2d->tot.xmin+2;
+ sy = v2d->tot.ymax - sy;
file = filelist_file(files, i);
if (params->active_file == i) {
if (file->flags & ACTIVE) colorid= TH_HILITE;
else colorid = TH_BACK;
- draw_tile(sx-2, sy-3, sfile->tile_w+2, sfile->tile_h, colorid,20);
+ draw_tile(sx-2, sy-3, layout->tile_w+2, sfile->layout->tile_h+layout->tile_border_y, colorid,20);
} else if (file->flags & ACTIVE) {
colorid = TH_HILITE;
- draw_tile(sx-2, sy-3, sfile->tile_w+2, sfile->tile_h, colorid,0);
+ draw_tile(sx-2, sy-3, layout->tile_w+2, sfile->layout->tile_h+layout->tile_border_y, colorid,0);
+ }
+
+ spos = sx;
+ file_draw_icon(spos, sy-3, get_file_icon(file), ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH);
+ spos += ICON_DEFAULT_WIDTH + 4;
+
+ UI_ThemeColor4(TH_TEXT);
+
+
+ sw = UI_GetStringWidth(G.font, file->relname, 0);
+ file_draw_string(spos, sy, file->relname, sw, layout->tile_h, FILE_SHORTEN_END);
+ spos += filelist_column_len(sfile->files, COLUMN_NAME) + 10;
+ if (params->display == FILE_SHOWSHORT) {
+ if (!(file->type & S_IFDIR)) {
+ sw = UI_GetStringWidth(G.font, file->size, 0);
+ spos += filelist_column_len(sfile->files, COLUMN_SIZE) + 10 - sw;
+ file_draw_string(spos, sy, file->size, sw, layout->tile_h, FILE_SHORTEN_END);
+ }
} else {
- /*
- colorid = TH_PANEL;
- draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid);
- */
- }
- if (type == FILE_MAIN) {
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
- }
- else {
- if (S_ISDIR(file->type))
- UI_ThemeColor4(TH_TEXT_HI);
- else
- UI_ThemeColor4(TH_TEXT);
+#if 0 // XXX TODO: add this for non-windows systems
+ /* rwx rwx rwx */
+ spos += 20;
+ sw = UI_GetStringWidth(G.font, file->mode1, 0);
+ file_draw_string(spos, sy, file->mode1, sw, layout->tile_h);
+
+ spos += 30;
+ sw = UI_GetStringWidth(G.font, file->mode2, 0);
+ file_draw_string(spos, sy, file->mode2, sw, layout->tile_h);
+
+ spos += 30;
+ sw = UI_GetStringWidth(G.font, file->mode3, 0);
+ file_draw_string(spos, sy, file->mode3, sw, layout->tile_h);
+
+ spos += 30;
+ sw = UI_GetStringWidth(G.font, file->owner, 0);
+ file_draw_string(spos, sy, file->owner, sw, layout->tile_h);
+#endif
+
+
+ sw = UI_GetStringWidth(G.font, file->date, 0);
+ file_draw_string(spos, sy, file->date, sw, layout->tile_h, FILE_SHORTEN_END);
+ spos += filelist_column_len(sfile->files, COLUMN_DATE) + 10;
+
+ sw = UI_GetStringWidth(G.font, file->time, 0);
+ file_draw_string(spos, sy, file->time, sw, layout->tile_h, FILE_SHORTEN_END);
+ spos += filelist_column_len(sfile->files, COLUMN_TIME) + 10;
+
+ if (!(file->type & S_IFDIR)) {
+ sw = UI_GetStringWidth(G.font, file->size, 0);
+ spos += filelist_column_len(sfile->files, COLUMN_SIZE) + 10 - sw;
+ file_draw_string(spos, sy, file->size, sw, layout->tile_h, FILE_SHORTEN_END);
+ }
}
-
- sw = UI_GetStringWidth(G.font, file->size, 0);
- file_draw_string(sx, sy, file->relname, sfile->tile_w - sw - 5, sfile->tile_h);
- file_draw_string(sx + sfile->tile_w - sw, sy, file->size, sfile->tile_w - sw, sfile->tile_h);
}
}
-void file_draw_fsmenu(const bContext *C, ARegion *ar)
+static void file_draw_fsmenu_category(const bContext *C, ARegion *ar, FSMenuCategory category, const char* category_name, short *starty)
{
- SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
- FileSelectParams* params = ED_fileselect_get_params(sfile);
+ struct FSMenu* fsmenu = fsmenu_get();
char bookmark[FILE_MAX];
- int nentries = fsmenu_get_nentries();
- int linestep = U.fontsize*3/2;
+ int nentries = fsmenu_get_nentries(fsmenu, category);
+ int linestep = gFontsize*2.0f;
+ short sx, sy, xpos, ypos;
+ int bmwidth = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*TILE_BORDER_X - ICON_DEFAULT_WIDTH - 4;
+ int fontsize = gFontsize;
int i;
- short sx, sy;
- int bmwidth = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*TILE_BORDER_X;
- int fontsize = U.fontsize;
-
- if (params->flag & FILE_BOOKMARKS) {
- sx = ar->v2d.cur.xmin + TILE_BORDER_X;
- sy = ar->v2d.cur.ymax-2*TILE_BORDER_Y;
- for (i=0; i< nentries && (sy > ar->v2d.cur.ymin) ;++i) {
- char *fname = fsmenu_get_entry(i);
-
- if (fname) {
- int sl;
- BLI_strncpy(bookmark, fname, FILE_MAX);
-
- sl = strlen(bookmark)-1;
- while (bookmark[sl] == '\\' || bookmark[sl] == '/') {
- bookmark[sl] = '\0';
- sl--;
- }
- if (params->active_bookmark == i ) {
- glColor4ub(0, 0, 0, 100);
- UI_ThemeColor(TH_HILITE);
- uiSetRoundBox(15);
- uiRoundBox(sx, sy - linestep, sx + bmwidth, sy, 6);
- // glRecti(sx, sy - linestep, sx + bmwidth, sy);
- UI_ThemeColor(TH_TEXT_HI);
- } else {
- UI_ThemeColor(TH_TEXT);
- }
-
- file_draw_string(sx, sy, bookmark, bmwidth, fontsize);
- sy -= linestep;
+
+
+ sx = ar->v2d.cur.xmin + TILE_BORDER_X;
+ sy = *starty;
+
+ UI_ThemeColor(TH_TEXT_HI);
+ file_draw_string(sx, sy, category_name, bmwidth, fontsize, FILE_SHORTEN_END);
+
+ sy -= linestep;
+
+ for (i=0; i< nentries && (sy > ar->v2d.cur.ymin) ;++i) {
+ char *fname = fsmenu_get_entry(fsmenu, category, i);
+
+ if (fname) {
+ int sl;
+ BLI_strncpy(bookmark, fname, FILE_MAX);
+
+ sl = strlen(bookmark)-1;
+ while (bookmark[sl] == '\\' || bookmark[sl] == '/') {
+ bookmark[sl] = '\0';
+ sl--;
+ }
+ if (fsmenu_is_selected(fsmenu, category, i) ) {
+ UI_ThemeColor(TH_HILITE);
+ //uiSetRoundBox(15);
+ uiRoundBox(sx, sy - linestep, ar->v2d.cur.xmax - TILE_BORDER_X, sy, 4.0f);
+ // glRectf(ar->v2d.cur.xmin, sy-linestep, ar->v2d.cur.xmax + 2*TILE_BORDER_X, sy);
+ UI_ThemeColor(TH_TEXT);
} else {
- glColor4ub(0xB0,0xB0,0xB0, 0xFF);
- sdrawline(sx, sy-1-fontsize/2 , sx + bmwidth, sy-1-fontsize/2);
- glColor4ub(0x30,0x30,0x30, 0xFF);
- sdrawline(sx, sy-fontsize/2 , sx + bmwidth, sy - fontsize/2);
- sy -= linestep;
+ UI_ThemeColor(TH_TEXT_HI);
}
+
+ xpos = sx;
+ ypos = sy - (TILE_BORDER_Y * 0.5);
+
+ file_draw_icon(xpos, ypos, ICON_FILE_FOLDER, ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH);
+ xpos += ICON_DEFAULT_WIDTH + 4;
+ file_draw_string(xpos, ypos, bookmark, bmwidth, fontsize, FILE_SHORTEN_FRONT);
+ sy -= linestep;
+ fsmenu_set_pos(fsmenu, category, i, xpos, ypos);
}
}
+
+ *starty = sy;
+}
+
+void file_draw_fsmenu(const bContext *C, ARegion *ar)
+{
+ int linestep = gFontsize*2.0f;
+ short sy= ar->v2d.cur.ymax-2*TILE_BORDER_Y;
+
+ file_draw_fsmenu_category(C, ar, FS_CATEGORY_SYSTEM, "SYSTEM", &sy);
+ sy -= linestep;
+ file_draw_fsmenu_category(C, ar, FS_CATEGORY_BOOKMARKS, "BOOKMARKS", &sy);
+ sy -= linestep;
+ file_draw_fsmenu_category(C, ar, FS_CATEGORY_RECENT, "RECENT", &sy);
+
}
diff --git a/source/blender/editors/space_file/file_header.c b/source/blender/editors/space_file/file_header.c
index be734ec971d..54dd7ff15ba 100644
--- a/source/blender/editors/space_file/file_header.c
+++ b/source/blender/editors/space_file/file_header.c
@@ -63,41 +63,10 @@
#define B_SORTIMASELLIST 1
#define B_RELOADIMASELDIR 2
-
+#define B_FILTERIMASELDIR 3
/* ************************ header area region *********************** */
-static void do_viewmenu(bContext *C, void *arg, int event)
-{
-
-}
-
-static uiBlock *dummy_viewmenu(bContext *C, ARegion *ar, void *arg_unused)
-{
- ScrArea *curarea= CTX_wm_area(C);
- uiBlock *block;
- short yco= 0, menuwidth=120;
-
- block= uiBeginBlock(C, ar, "dummy_viewmenu", UI_EMBOSSP, UI_HELV);
- uiBlockSetButmFunc(block, do_viewmenu, NULL);
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Nothing yet", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-
- if(curarea->headertype==HEADERTOP) {
- uiBlockSetDirection(block, UI_DOWN);
- }
- else {
- uiBlockSetDirection(block, UI_TOP);
- uiBlockFlipOrder(block);
- }
-
- uiTextBoundsBlock(block, 50);
- uiEndBlock(C, block);
-
- return block;
-}
-
static void do_file_header_buttons(bContext *C, void *arg, int event)
{
SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
@@ -109,13 +78,23 @@ static void do_file_header_buttons(bContext *C, void *arg, int event)
case B_RELOADIMASELDIR:
WM_event_add_notifier(C, NC_WINDOW, NULL);
break;
+ case B_FILTERIMASELDIR:
+ if(sfile->params) {
+ if (sfile->params->flag & FILE_FILTER) {
+ filelist_setfilter(sfile->files,sfile->params->filter);
+ filelist_filter(sfile->files);
+ } else {
+ filelist_setfilter(sfile->files,0);
+ filelist_filter(sfile->files);
+ }
+ }
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
}
}
void file_header_buttons(const bContext *C, ARegion *ar)
{
- ScrArea *sa= CTX_wm_area(C);
SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
FileSelectParams* params = ED_fileselect_get_params(sfile);
@@ -128,10 +107,10 @@ void file_header_buttons(const bContext *C, ARegion *ar)
xco= ED_area_header_standardbuttons(C, block, yco);
+ /*
if((sa->flag & HEADER_NO_PULLDOWN)==0) {
int xmax;
- /* pull down menus */
uiBlockSetEmboss(block, UI_EMBOSSP);
xmax= GetButStringLength("View");
@@ -139,31 +118,65 @@ void file_header_buttons(const bContext *C, ARegion *ar)
"View", xco, yco-2, xmax-3, 24, "");
xco+=XIC+xmax;
}
+ */
/* SORT TYPE */
uiBlockSetEmboss(block, UI_EMBOSSX);
- xco+=XIC;
+
+ xco += 5;
+
uiBlockBeginAlign(block);
- uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTALPHA, xco+=XIC,0,XIC,YIC, &params->sort, 1.0, 0.0, 0, 0, "Sorts files alphabetically");
- uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTBYEXT, xco+=XIC,0,XIC,YIC, &params->sort, 1.0, 3.0, 0, 0, "Sorts files by extension");
- uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTTIME, xco+=XIC,0,XIC,YIC, &params->sort, 1.0, 1.0, 0, 0, "Sorts files by time");
- uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTSIZE, xco+=XIC,0,XIC,YIC, &params->sort, 1.0, 2.0, 0, 0, "Sorts files by size");
+ uiDefIconButO(block, BUT, "FILE_OT_parent", WM_OP_INVOKE_DEFAULT, ICON_FILE_PARENT, xco+=XIC, yco, 20, 20, "Navigate to Parent Folder");
+ uiDefIconButO(block, BUT, "FILE_OT_refresh", WM_OP_INVOKE_DEFAULT, ICON_FILE_REFRESH, xco+=XIC, yco, 20, 20, "Refresh List of Files");
uiBlockEndAlign(block);
- xco+=XIC+10;
+ xco += 5;
+
if (sfile->params->type != FILE_MAIN) {
- uiDefIconButBitS(block, TOG, FILE_BOOKMARKS, B_RELOADIMASELDIR, ICON_BOOKMARKS,xco+=XIC,0,XIC,YIC, &params->flag, 0, 0, 0, 0, "Toggles Bookmarks on/off");
- xco+=XIC+10;
- }
+ uiBlockBeginAlign(block);
+ uiDefIconButS(block, ROW, B_RELOADIMASELDIR, ICON_SHORTDISPLAY, xco+=XIC, yco, XIC,YIC, &params->display, 1.0, FILE_SHORTDISPLAY, 0, 0, "Displays short file description");
+ uiDefIconButS(block, ROW, B_RELOADIMASELDIR, ICON_LONGDISPLAY, xco+=XIC, yco, XIC,YIC, &params->display, 1.0, FILE_LONGDISPLAY, 0, 0, "Displays long file description");
+ uiDefIconButS(block, ROW, B_RELOADIMASELDIR, ICON_IMGDISPLAY, xco+=XIC, yco, XIC,YIC, &params->display, 1.0, FILE_IMGDISPLAY, 0, 0, "Displays files as thumbnails");
+ uiBlockEndAlign(block);
+
+ xco+=XIC;
+ }
+
+ uiBlockBeginAlign(block);
+ uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTALPHA, xco+=XIC, yco, XIC,YIC, &params->sort, 1.0, 0.0, 0, 0, "Sorts files alphabetically");
+ uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTBYEXT, xco+=XIC, yco, XIC,YIC, &params->sort, 1.0, 3.0, 0, 0, "Sorts files by extension");
+ uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTTIME, xco+=XIC, yco, XIC,YIC, &params->sort, 1.0, 1.0, 0, 0, "Sorts files by time");
+ uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTSIZE, xco+=XIC, yco, XIC,YIC, &params->sort, 1.0, 2.0, 0, 0, "Sorts files by size");
+ uiBlockEndAlign(block);
+
+ xco+=XIC;
+ /* replace with consistent sub-region collapsing
if (sfile->params->type != FILE_MAIN) {
uiBlockBeginAlign(block);
- uiDefIconButS(block, ROW, B_RELOADIMASELDIR, ICON_SHORTDISPLAY, xco+=XIC,0,XIC,YIC, &params->display, 1.0, 1.0, 0, 0, "Displays short file description");
- uiDefIconButS(block, ROW, B_RELOADIMASELDIR, ICON_LONGDISPLAY, xco+=XIC,0,XIC,YIC, &params->display, 1.0, 2.0, 0, 0, "Displays long file description");
- uiDefIconButS(block, ROW, B_RELOADIMASELDIR, ICON_IMAGE_COL /* ICON_IMGDISPLAY */, xco+=XIC,0,XIC,YIC, &params->display, 1.0, 3.0, 0, 0, "Displays files as thumbnails");
+ // uiDefIconButBitS(block, TOG, FILE_BOOKMARKS, B_RELOADIMASELDIR, ICON_BOOKMARKS,xco+=XIC,0,XIC,YIC, &params->flag, 0, 0, 0, 0, "Toggles Bookmarks on/off");
+ uiDefIconButO(block, TOG, "FILE_OT_bookmark_toggle", WM_OP_INVOKE_DEFAULT, ICON_BOOKMARKS, xco+XIC,yco,20,20, "Toggle Bookmarks");
uiBlockEndAlign(block);
- xco+=XIC+10;
- }
+ xco+=XIC;
+ }
+ */
+
+ uiDefIconButBitS(block, TOG, FILE_FILTER, B_FILTERIMASELDIR, ICON_FILTER,xco+=XIC,0,XIC,YIC, &params->flag, 0, 0, 0, 0, "Filter files");
+ if (params->flag & FILE_FILTER) {
+ xco+=4;
+ uiBlockBeginAlign(block);
+ uiDefIconButBitS(block, TOG, IMAGEFILE, B_FILTERIMASELDIR, ICON_FILE_IMAGE,xco+=XIC,0,XIC,YIC, &params->filter, 0, 0, 0, 0, "Show images");
+ uiDefIconButBitS(block, TOG, BLENDERFILE, B_FILTERIMASELDIR, ICON_FILE_BLEND,xco+=XIC,0,XIC,YIC, &params->filter, 0, 0, 0, 0, "Show .blend files");
+ uiDefIconButBitS(block, TOG, MOVIEFILE, B_FILTERIMASELDIR, ICON_FILE_MOVIE,xco+=XIC,0,XIC,YIC, &params->filter, 0, 0, 0, 0, "Show movies");
+ uiDefIconButBitS(block, TOG, PYSCRIPTFILE, B_FILTERIMASELDIR, ICON_FILE_SCRIPT,xco+=XIC,0,XIC,YIC, &params->filter, 0, 0, 0, 0, "Show python scripts");
+ uiDefIconButBitS(block, TOG, FTFONTFILE, B_FILTERIMASELDIR, ICON_FILE_FONT,xco+=XIC,0,XIC,YIC, &params->filter, 0, 0, 0, 0, "Show fonts");
+ uiDefIconButBitS(block, TOG, SOUNDFILE, B_FILTERIMASELDIR, ICON_FILE_SOUND,xco+=XIC,0,XIC,YIC, &params->filter, 0, 0, 0, 0, "Show sound files");
+ uiDefIconButBitS(block, TOG, TEXTFILE, B_FILTERIMASELDIR, ICON_FILE_BLANK,xco+=XIC,0,XIC,YIC, &params->filter, 0, 0, 0, 0, "Show text files");
+ uiDefIconButBitS(block, TOG, FOLDERFILE, B_FILTERIMASELDIR, ICON_FILE_FOLDER,xco+=XIC,0,XIC,YIC, &params->filter, 0, 0, 0, 0, "Show folders");
+ uiBlockEndAlign(block);
+ xco+=XIC;
+ }
+
xcotitle= xco;
xco+= UI_GetStringWidth(G.font, params->title, 0);
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index e47387a2d22..80b7eb21818 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -34,6 +34,8 @@
/* file_header.c */
void file_header_buttons(const bContext *C, ARegion *ar);
+/* file_ops.c */
+struct ARegion *file_buttons_region(struct ScrArea *sa);
/* file_draw.c */
#define TILE_BORDER_X 8
@@ -51,13 +53,15 @@ struct wmOperator;
struct wmEvent;
void FILE_OT_highlight(struct wmOperatorType *ot);
void FILE_OT_select(struct wmOperatorType *ot);
-void FILE_OT_select_all(struct wmOperatorType *ot);
-void FILE_OT_border_select(struct wmOperatorType *ot);
+void FILE_OT_select_all_toggle(struct wmOperatorType *ot);
+void FILE_OT_select_border(struct wmOperatorType *ot);
void FILE_OT_select_bookmark(struct wmOperatorType *ot);
void FILE_OT_loadimages(struct wmOperatorType *ot);
void FILE_OT_exec(struct wmOperatorType *ot);
void FILE_OT_cancel(struct wmOperatorType *ot);
void FILE_OT_parent(struct wmOperatorType *ot);
+void FILE_OT_refresh(struct wmOperatorType *ot);
+void FILE_OT_bookmark_toggle(struct wmOperatorType *ot);
int file_exec(bContext *C, struct wmOperator *unused);
int file_cancel_exec(bContext *C, struct wmOperator *unused);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index ae989194527..3d845ac4be6 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -69,19 +69,15 @@
static int find_file_mouse_hor(SpaceFile *sfile, struct ARegion* ar, short x, short y)
{
float fx,fy;
- int offsetx, offsety;
- int columns;
int active_file = -1;
int numfiles = filelist_numfiles(sfile->files);
View2D* v2d = &ar->v2d;
UI_view2d_region_to_view(v2d, x, y, &fx, &fy);
- offsetx = (fx - (v2d->cur.xmin+sfile->tile_border_x))/(sfile->tile_w + 2*sfile->tile_border_x);
- offsety = (v2d->tot.ymax - sfile->tile_border_y - fy)/(sfile->tile_h + 2*sfile->tile_border_y);
- columns = (v2d->cur.xmax - v2d->cur.xmin) / (sfile->tile_w+ 2*sfile->tile_border_x);
- active_file = offsetx + columns*offsety;
+ active_file = ED_fileselect_layout_offset(sfile->layout, v2d->tot.xmin + fx, v2d->tot.ymax - fy);
+ printf("FINDFILE %d\n", active_file);
if ( (active_file < 0) || (active_file >= numfiles) )
{
active_file = -1;
@@ -92,19 +88,15 @@ static int find_file_mouse_hor(SpaceFile *sfile, struct ARegion* ar, short x, sh
static int find_file_mouse_vert(SpaceFile *sfile, struct ARegion* ar, short x, short y)
{
- int offsetx, offsety;
float fx,fy;
int active_file = -1;
int numfiles = filelist_numfiles(sfile->files);
- int rows;
View2D* v2d = &ar->v2d;
UI_view2d_region_to_view(v2d, x, y, &fx, &fy);
- offsetx = (fx-sfile->tile_border_x)/(sfile->tile_w + sfile->tile_border_x);
- offsety = (v2d->cur.ymax-fy-sfile->tile_border_y)/(sfile->tile_h + sfile->tile_border_y);
- rows = (v2d->cur.ymax - v2d->cur.ymin - 2*sfile->tile_border_y) / (sfile->tile_h+sfile->tile_border_y);
- active_file = rows*offsetx + offsety;
+ active_file = ED_fileselect_layout_offset(sfile->layout, v2d->tot.xmin + fx, v2d->tot.ymax - fy);
+
if ( (active_file < 0) || (active_file >= numfiles) )
{
active_file = -1;
@@ -125,17 +117,19 @@ static void file_deselect_all(SpaceFile* sfile)
}
}
-static void file_select(SpaceFile* sfile, FileSelectParams* params, ARegion* ar, const rcti* rect, short val)
+static void file_select(SpaceFile* sfile, ARegion* ar, const rcti* rect, short val)
{
int first_file = -1;
int last_file = -1;
int act_file;
short selecting = (val == LEFTMOUSE);
+ FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileLayout *layout = ED_fileselect_get_layout(sfile, ar);
int numfiles = filelist_numfiles(sfile->files);
params->selstate = NOTACTIVE;
- if (params->display) {
+ if ( (layout->flag == FILE_LAYOUT_HOR) ) {
first_file = find_file_mouse_hor(sfile, ar, rect->xmin, rect->ymax);
last_file = find_file_mouse_hor(sfile, ar, rect->xmax, rect->ymin);
} else {
@@ -154,6 +148,8 @@ static void file_select(SpaceFile* sfile, FileSelectParams* params, ARegion* ar,
}
}
+ printf("Selecting %d %d\n", first_file, last_file);
+
/* make the last file active */
if (last_file >= 0 && last_file < numfiles) {
struct direntry* file = filelist_file(sfile->files, last_file);
@@ -215,16 +211,16 @@ static int file_border_select_exec(bContext *C, wmOperator *op)
rect.xmax= RNA_int_get(op->ptr, "xmax");
rect.ymax= RNA_int_get(op->ptr, "ymax");
- file_select(sfile, sfile->params, ar, &rect, val );
+ file_select(sfile, ar, &rect, val );
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
}
-void FILE_OT_border_select(wmOperatorType *ot)
+void FILE_OT_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Activate/Select File";
- ot->idname= "FILE_OT_border_select";
+ ot->idname= "FILE_OT_select_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
@@ -252,10 +248,13 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
rect.ymin = rect.ymax = event->y - ar->winrct.ymin;
val = event->val;
- /* single select, deselect all selected first */
- file_deselect_all(sfile);
- file_select(sfile, sfile->params, ar, &rect, val );
- WM_event_add_notifier(C, NC_WINDOW, NULL);
+ if (BLI_in_rcti(&ar->v2d.mask, rect.xmin, rect.ymin)) {
+
+ /* single select, deselect all selected first */
+ file_deselect_all(sfile);
+ file_select(sfile, ar, &rect, val );
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+ }
return OPERATOR_FINISHED;
}
@@ -303,11 +302,11 @@ static int file_select_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
}
-void FILE_OT_select_all(wmOperatorType *ot)
+void FILE_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select/Deselect all files";
- ot->idname= "FILE_OT_select_all";
+ ot->idname= "FILE_OT_select_all_toggle";
/* api callbacks */
ot->invoke= file_select_all_invoke;
@@ -321,34 +320,73 @@ void FILE_OT_select_all(wmOperatorType *ot)
static void set_active_bookmark(FileSelectParams* params, struct ARegion* ar, short x, short y)
{
- int nentries = fsmenu_get_nentries();
+ int nentries = fsmenu_get_nentries(fsmenu_get(), FS_CATEGORY_BOOKMARKS);
float fx, fy;
short posy;
UI_view2d_region_to_view(&ar->v2d, x, y, &fx, &fy);
posy = ar->v2d.cur.ymax - 2*TILE_BORDER_Y - fy;
- params->active_bookmark = ((float)posy / (U.fontsize*3.0f/2.0f));
+ posy -= U.fontsize*2.0f; /* header */
+
+ params->active_bookmark = ((float)posy / (U.fontsize*2.0f));
if (params->active_bookmark < 0 || params->active_bookmark > nentries) {
params->active_bookmark = -1;
}
}
+static int file_select_bookmark_category(SpaceFile* sfile, ARegion* ar, short x, short y, FSMenuCategory category)
+{
+ struct FSMenu* fsmenu = fsmenu_get();
+ int nentries = fsmenu_get_nentries(fsmenu, category);
+ int linestep = U.fontsize*2.0f;
+ short xs, ys;
+ int i;
+ int selected = -1;
+
+ for (i=0; i < nentries; ++i) {
+ fsmenu_get_pos(fsmenu, category, i, &xs, &ys);
+ if ( (y<=ys) && (y>ys-linestep) ) {
+ fsmenu_select_entry(fsmenu, category, i);
+ selected = i;
+ break;
+ }
+ }
+ return selected;
+}
+
static void file_select_bookmark(SpaceFile* sfile, ARegion* ar, short x, short y)
{
+ float fx, fy;
+ int selected;
+ FSMenuCategory category = FS_CATEGORY_SYSTEM;
+
if (BLI_in_rcti(&ar->v2d.mask, x, y)) {
- char *selected;
- set_active_bookmark(sfile->params, ar, x, y);
- selected= fsmenu_get_entry(sfile->params->active_bookmark);
- /* which string */
- if (selected) {
- FileSelectParams* params = sfile->params;
- BLI_strncpy(params->dir, selected, sizeof(params->dir));
- BLI_cleanup_dir(G.sce, params->dir);
- filelist_free(sfile->files);
- filelist_setdir(sfile->files, params->dir);
- params->file[0] = '\0';
- params->active_file = -1;
+ char *entry;
+
+ UI_view2d_region_to_view(&ar->v2d, x, y, &fx, &fy);
+ selected = file_select_bookmark_category(sfile, ar, fx, fy, FS_CATEGORY_SYSTEM);
+ if (selected<0) {
+ category = FS_CATEGORY_BOOKMARKS;
+ selected = file_select_bookmark_category(sfile, ar, fx, fy, category);
+ }
+ if (selected<0) {
+ category = FS_CATEGORY_RECENT;
+ selected = file_select_bookmark_category(sfile, ar, fx, fy, category);
+ }
+
+ if (selected>=0) {
+ entry= fsmenu_get_entry(fsmenu_get(), category, selected);
+ /* which string */
+ if (entry) {
+ FileSelectParams* params = sfile->params;
+ BLI_strncpy(params->dir, entry, sizeof(params->dir));
+ BLI_cleanup_dir(G.sce, params->dir);
+ filelist_free(sfile->files);
+ filelist_setdir(sfile->files, params->dir);
+ params->file[0] = '\0';
+ params->active_file = -1;
+ }
}
}
}
@@ -410,20 +448,22 @@ void FILE_OT_loadimages(wmOperatorType *ot)
int file_hilight_set(SpaceFile *sfile, ARegion *ar, int mx, int my)
{
FileSelectParams* params;
+ FileLayout* layout;
int numfiles, actfile;
if(sfile==NULL || sfile->files==NULL) return 0;
numfiles = filelist_numfiles(sfile->files);
params = ED_fileselect_get_params(sfile);
-
- if (params->display == FILE_IMGDISPLAY) {
+ layout = ED_fileselect_get_layout(sfile, ar);
+
+ if ( (layout->flag == FILE_LAYOUT_HOR)) {
actfile = find_file_mouse_hor(sfile, ar, mx , my);
} else {
actfile = find_file_mouse_vert(sfile, ar, mx, my);
}
- if (actfile >= 0 && actfile < numfiles ) {
+ if (params && (actfile >= 0) && (actfile < numfiles) ) {
params->active_file=actfile;
return 1;
}
@@ -488,6 +528,9 @@ int file_exec(bContext *C, wmOperator *unused)
strcat(name, sfile->params->file);
RNA_string_set(op->ptr, "filename", name);
+ fsmenu_insert_entry(fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir,0, 1);
+ BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs");
+ fsmenu_write_file(fsmenu_get(), name);
WM_event_fileselect_event(C, op, EVT_FILESELECT_EXEC);
}
@@ -522,6 +565,7 @@ int file_parent_exec(bContext *C, wmOperator *unused)
}
+
void FILE_OT_parent(struct wmOperatorType *ot)
{
/* identifiers */
@@ -534,4 +578,65 @@ void FILE_OT_parent(struct wmOperatorType *ot)
}
+int file_refresh_exec(bContext *C, wmOperator *unused)
+{
+ SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
+
+ if(sfile->params) {
+ filelist_setdir(sfile->files, sfile->params->dir);
+ filelist_free(sfile->files);
+ sfile->params->active_file = -1;
+ }
+ ED_area_tag_redraw(CTX_wm_area(C));
+
+ return OPERATOR_FINISHED;
+
+}
+
+
+void FILE_OT_refresh(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Refresh Filelist";
+ ot->idname= "FILE_OT_refresh";
+
+ /* api callbacks */
+ ot->exec= file_refresh_exec;
+ ot->poll= ED_operator_file_active; /* <- important, handler is on window level */
+}
+struct ARegion *file_buttons_region(struct ScrArea *sa)
+{
+ ARegion *ar;
+
+ for(ar= sa->regionbase.first; ar; ar= ar->next)
+ if(ar->regiontype==RGN_TYPE_CHANNELS)
+ return ar;
+ return NULL;
+}
+
+int file_bookmark_toggle_exec(bContext *C, wmOperator *unused)
+{
+ ScrArea *sa= CTX_wm_area(C);
+ ARegion *ar= file_buttons_region(sa);
+
+ if(ar) {
+ ar->flag ^= RGN_FLAG_HIDDEN;
+ ar->v2d.flag &= ~V2D_IS_INITIALISED; /* XXX should become hide/unhide api? */
+
+ ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
+ ED_area_tag_redraw(sa);
+ }
+ return OPERATOR_FINISHED;
+}
+
+void FILE_OT_bookmark_toggle(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Toggle Bookmarks";
+ ot->idname= "FILE_OT_bookmark_toggle";
+
+ /* api callbacks */
+ ot->exec= file_bookmark_toggle_exec;
+ ot->poll= ED_operator_file_active; /* <- important, handler is on window level */
+}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 384fb2141c3..1ba84566940 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -82,6 +82,7 @@
#include "PIL_time.h"
+#include "UI_text.h"
#include "filelist.h"
@@ -113,32 +114,17 @@ typedef struct FileList
int numfiltered;
char dir[FILE_MAX];
short type;
- short ipotype;
- struct BlendHandle *libfiledata;
int has_func;
short prv_w;
short prv_h;
short hide_dot;
unsigned int filter;
short changed;
+ int columns[MAX_FILE_COLUMN];
ListBase loadimages;
ListBase threads;
} FileList;
-int BIF_groupname_to_code(char *group)
-{
- char buf[32];
- char *lslash;
-
- BLI_strncpy(buf, group, 31);
- lslash= BLI_last_slash(buf);
- if (lslash)
- lslash[0]= '\0';
-
- return BLO_idcode_from_name(buf);
-}
-
-
#define SPECIAL_IMG_SIZE 48
#define SPECIAL_IMG_ROWS 4
#define SPECIAL_IMG_COLS 4
@@ -153,7 +139,8 @@ int BIF_groupname_to_code(char *group)
#define SPECIAL_IMG_TEXTFILE 7
#define SPECIAL_IMG_FONTFILE 8
#define SPECIAL_IMG_UNKNOWNFILE 9
-#define SPECIAL_IMG_MAX SPECIAL_IMG_UNKNOWNFILE + 1
+#define SPECIAL_IMG_LOADING 10
+#define SPECIAL_IMG_MAX SPECIAL_IMG_LOADING + 1
static ImBuf* gSpecialFileImages[SPECIAL_IMG_MAX];
@@ -183,6 +170,7 @@ static int compare_name(const void *a1, const void *a2)
if( strcmp(entry1->relname, ".")==0 ) return (-1);
if( strcmp(entry2->relname, ".")==0 ) return (1);
if( strcmp(entry1->relname, "..")==0 ) return (-1);
+ if( strcmp(entry2->relname, "..")==0 ) return (1);
return (BLI_strcasecmp(entry1->relname,entry2->relname));
}
@@ -210,6 +198,7 @@ static int compare_date(const void *a1, const void *a2)
if( strcmp(entry1->relname, ".")==0 ) return (-1);
if( strcmp(entry2->relname, ".")==0 ) return (1);
if( strcmp(entry1->relname, "..")==0 ) return (-1);
+ if( strcmp(entry2->relname, "..")==0 ) return (1);
if ( entry1->s.st_mtime < entry2->s.st_mtime) return 1;
if ( entry1->s.st_mtime > entry2->s.st_mtime) return -1;
@@ -240,6 +229,7 @@ static int compare_size(const void *a1, const void *a2)
if( strcmp(entry1->relname, ".")==0 ) return (-1);
if( strcmp(entry2->relname, ".")==0 ) return (1);
if( strcmp(entry1->relname, "..")==0 ) return (-1);
+ if( strcmp(entry2->relname, "..")==0 ) return (1);
if ( entry1->s.st_size < entry2->s.st_size) return 1;
if ( entry1->s.st_size > entry2->s.st_size) return -1;
@@ -277,25 +267,19 @@ static int compare_extension(const void *a1, const void *a2) {
if( strcmp(entry1->relname, ".")==0 ) return (-1);
if( strcmp(entry2->relname, ".")==0 ) return (1);
if( strcmp(entry1->relname, "..")==0 ) return (-1);
- if( strcmp(entry2->relname, "..")==0 ) return (-1);
+ if( strcmp(entry2->relname, "..")==0 ) return (1);
return (BLI_strcasecmp(sufix1, sufix2));
}
void filelist_filter(FileList* filelist)
{
- char dir[FILE_MAX], group[GROUP_MAX];
int num_filtered = 0;
int i, j;
if (!filelist->filelist)
return;
- if ( ( (filelist->type == FILE_LOADLIB) && filelist_islibrary(filelist, dir, group))
- || (filelist->type == FILE_MAIN) ) {
- filelist->filter = 0;
- }
-
if (!filelist->filter) {
if (filelist->fidx) {
MEM_freeN(filelist->fidx);
@@ -378,7 +362,6 @@ struct FileList* filelist_new()
p->filelist = 0;
p->numfiles = 0;
p->dir[0] = '\0';
- p->libfiledata = 0;
p->type = 0;
p->has_func = 0;
p->filter = 0;
@@ -392,8 +375,6 @@ struct FileList* filelist_copy(struct FileList* filelist)
p->filelist = NULL;
p->fidx = NULL;
p->type = filelist->type;
- p->ipotype = filelist->ipotype;
- p->has_func = filelist->has_func;
return p;
}
@@ -435,18 +416,6 @@ void filelist_free(struct FileList* filelist)
filelist->numfiltered =0;
}
-void filelist_freelib(struct FileList* filelist)
-{
- if(filelist->libfiledata)
- BLO_blendhandle_close(filelist->libfiledata);
- filelist->libfiledata= 0;
-}
-
-struct BlendHandle *filelist_lib(struct FileList* filelist)
-{
- return filelist->libfiledata;
-}
-
int filelist_numfiles(struct FileList* filelist)
{
return filelist->numfiltered;
@@ -597,34 +566,47 @@ struct ImBuf * filelist_getimage(struct FileList* filelist, int index)
fidx = filelist->fidx[index];
ibuf = filelist->filelist[fidx].image;
- if (ibuf == NULL) {
- struct direntry *file = &filelist->filelist[fidx];
- if (file->type & S_IFDIR) {
+ return ibuf;
+}
+
+struct ImBuf * filelist_geticon(struct FileList* filelist, int index)
+{
+ ImBuf* ibuf= NULL;
+ struct direntry *file= NULL;
+ int fidx = 0;
+ if ( (index < 0) || (index >= filelist->numfiltered) ) {
+ return NULL;
+ }
+ fidx = filelist->fidx[index];
+ file = &filelist->filelist[fidx];
+ if (file->type & S_IFDIR) {
if ( strcmp(filelist->filelist[fidx].relname, "..") == 0) {
ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT];
} else if ( strcmp(filelist->filelist[fidx].relname, ".") == 0) {
ibuf = gSpecialFileImages[SPECIAL_IMG_REFRESH];
} else {
- ibuf = gSpecialFileImages[SPECIAL_IMG_FOLDER];
+ ibuf = gSpecialFileImages[SPECIAL_IMG_FOLDER];
}
- } else {
- ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE];
- }
+ } else {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE];
+ }
- if (file->flags & BLENDERFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_BLENDFILE];
- } else if ( (file->flags & MOVIEFILE) || (file->flags & MOVIEFILE_ICON) ) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_MOVIEFILE];
- } else if (file->flags & SOUNDFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_SOUNDFILE];
- } else if (file->flags & PYSCRIPTFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_PYTHONFILE];
- } else if (file->flags & FTFONTFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_FONTFILE];
- } else if (file->flags & TEXTFILE) {
- ibuf = gSpecialFileImages[SPECIAL_IMG_TEXTFILE];
- }
+ if (file->flags & BLENDERFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_BLENDFILE];
+ } else if ( (file->flags & MOVIEFILE) || (file->flags & MOVIEFILE_ICON) ) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_MOVIEFILE];
+ } else if (file->flags & SOUNDFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_SOUNDFILE];
+ } else if (file->flags & PYSCRIPTFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_PYTHONFILE];
+ } else if (file->flags & FTFONTFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_FONTFILE];
+ } else if (file->flags & TEXTFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_TEXTFILE];
+ } else if (file->flags & IMAGEFILE) {
+ ibuf = gSpecialFileImages[SPECIAL_IMG_LOADING];
}
+
return ibuf;
}
@@ -676,39 +658,59 @@ void filelist_setfilter(struct FileList* filelist, unsigned int filter)
filelist->filter = filter;
}
+int filelist_column_len(struct FileList* filelist, FileListColumns column)
+{
+ return filelist->columns[column];
+}
+
void filelist_readdir(struct FileList* filelist)
{
char wdir[FILE_MAX];
- int finished = 0;
+ int i;
if (!filelist) return;
filelist->fidx = 0;
filelist->filelist = 0;
- if(filelist->type==FILE_MAIN) {
- filelist_from_main(filelist);
- finished = 1;
- } else if(filelist->type==FILE_LOADLIB) {
- BLI_cleanup_dir(G.sce, filelist->dir);
- filelist_from_library(filelist);
- if(filelist->libfiledata) {
- finished = 1;
- }
+ BLI_getwdN(wdir);
+
+ BLI_cleanup_dir(G.sce, filelist->dir);
+ BLI_hide_dot_files(filelist->hide_dot);
+ filelist->numfiles = BLI_getdir(filelist->dir, &(filelist->filelist));
+
+ chdir(wdir);
+ filelist_setfiletypes(filelist, G.have_quicktime);
+ filelist_filter(filelist);
+
+ if (!filelist->threads.first) {
+ BLI_init_threads(&filelist->threads, exec_loadimages, 2);
}
- if (!finished) {
- BLI_getwdN(wdir);
-
- BLI_cleanup_dir(G.sce, filelist->dir);
- BLI_hide_dot_files(filelist->hide_dot);
- filelist->numfiles = BLI_getdir(filelist->dir, &(filelist->filelist));
+ for (i=0; i<MAX_FILE_COLUMN; ++i) {
+ filelist->columns[i] = 0;
+ }
- chdir(wdir);
- filelist_setfiletypes(filelist, G.have_quicktime);
- filelist_filter(filelist);
-
- if (!filelist->threads.first) {
- BLI_init_threads(&filelist->threads, exec_loadimages, 2);
+ for (i=0; (i < filelist->numfiles); ++i)
+ {
+ struct direntry* file = filelist_file(filelist, i);
+ if (file) {
+ int len;
+ len = UI_GetStringWidth(G.font, file->relname,0);
+ if (len > filelist->columns[COLUMN_NAME]) filelist->columns[COLUMN_NAME] = len;
+ len = UI_GetStringWidth(G.font, file->date,0);
+ if (len > filelist->columns[COLUMN_DATE]) filelist->columns[COLUMN_DATE] = len;
+ len = UI_GetStringWidth(G.font, file->time,0);
+ if (len > filelist->columns[COLUMN_TIME]) filelist->columns[COLUMN_TIME] = len;
+ len = UI_GetStringWidth(G.font, file->size,0);
+ if (len > filelist->columns[COLUMN_SIZE]) filelist->columns[COLUMN_SIZE] = len;
+ len = UI_GetStringWidth(G.font, file->mode1,0);
+ if (len > filelist->columns[COLUMN_MODE1]) filelist->columns[COLUMN_MODE1] = len;
+ len = UI_GetStringWidth(G.font, file->mode2,0);
+ if (len > filelist->columns[COLUMN_MODE2]) filelist->columns[COLUMN_MODE2] = len;
+ len = UI_GetStringWidth(G.font, file->mode3,0);
+ if (len > filelist->columns[COLUMN_MODE3]) filelist->columns[COLUMN_MODE3] = len;
+ len = UI_GetStringWidth(G.font, file->owner,0);
+ if (len > filelist->columns[COLUMN_OWNER]) filelist->columns[COLUMN_OWNER] = len;
}
}
}
@@ -744,17 +746,6 @@ void filelist_setfiletypes(struct FileList* filelist, short has_quicktime)
if(BLO_has_bfile_extension(file->relname)) {
file->flags |= BLENDERFILE;
- if(filelist->type==FILE_LOADLIB) {
- char name[FILE_MAXDIR+FILE_MAXFILE];
- BLI_strncpy(name, filelist->dir, sizeof(name));
- strcat(name, file->relname);
-
- /* prevent current file being used as acceptable dir */
- if (BLI_streq(G.main->name, name)==0) {
- file->type &= ~S_IFMT;
- file->type |= S_IFDIR;
- }
- }
} else if(BLI_testextensie(file->relname, ".py")) {
file->flags |= PYSCRIPTFILE;
} else if(BLI_testextensie(file->relname, ".txt")) {
@@ -869,296 +860,6 @@ void filelist_swapselect(struct FileList* filelist)
}
}
-int filelist_islibrary(struct FileList* filelist, char* dir, char* group)
-{
- /* return ok when a blenderfile, in dir is the filename,
- * in group the type of libdata
- */
- int len;
- char *fd;
-
- strcpy(dir, filelist->dir);
- len= strlen(dir);
- if(len<7) return 0;
- if( dir[len-1] != '/' && dir[len-1] != '\\') return 0;
-
- group[0]= 0;
- dir[len-1]= 0;
-
- /* Find the last slash */
- fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
-
- if(fd==0) return 0;
- *fd= 0;
- if(BLO_has_bfile_extension(fd+1)) {
- *fd= '/';
- }
- else {
- char *gp = fd+1; // in case we have a .blend file, gp points to the group
-
- /* Find the last slash */
- fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
- if (!fd || !BLO_has_bfile_extension(fd+1)) return 0;
-
- /* now we know that we are in a blend file and it is safe to
- assume that gp actually points to a group */
- BLI_strncpy(group, gp, GROUP_MAX);
- }
- return 1;
-}
-
-void filelist_from_library(struct FileList* filelist)
-{
- LinkNode *l, *names, *previews;
- struct ImBuf* ima;
- int ok, i, nnames, idcode;
- char filename[FILE_MAXDIR+FILE_MAXFILE];
- char dir[FILE_MAX], group[GROUP_MAX];
-
- filelist->type = FILE_LOADLIB;
-
- /* name test */
- ok= filelist_islibrary(filelist, dir, group);
- if (!ok) {
- /* free */
- if(filelist->libfiledata) BLO_blendhandle_close(filelist->libfiledata);
- filelist->libfiledata= 0;
- return;
- }
-
- BLI_strncpy(filename, G.sce, sizeof(filename)); // G.sce = last file loaded, for UI
-
- /* there we go */
- /* for the time being only read filedata when libfiledata==0 */
- if (filelist->libfiledata==0) {
- filelist->libfiledata= BLO_blendhandle_from_file(dir);
- if(filelist->libfiledata==0) return;
- }
-
- idcode= BIF_groupname_to_code(group);
-
- // memory for strings is passed into filelist[i].relname
- // and free'd in freefilelist
- previews = NULL;
- if (idcode) {
- previews= BLO_blendhandle_get_previews(filelist->libfiledata, idcode);
- names= BLO_blendhandle_get_datablock_names(filelist->libfiledata, idcode);
- /* ugh, no rewind, need to reopen */
- BLO_blendhandle_close(filelist->libfiledata);
- filelist->libfiledata= BLO_blendhandle_from_file(dir);
-
- } else {
- names= BLO_blendhandle_get_linkable_groups(filelist->libfiledata);
- }
-
- nnames= BLI_linklist_length(names);
-
- filelist->numfiles= nnames + 2;
- filelist->filelist= malloc(filelist->numfiles * sizeof(*filelist->filelist));
- memset(filelist->filelist, 0, filelist->numfiles * sizeof(*filelist->filelist));
-
- filelist->filelist[0].relname= BLI_strdup(".");
- filelist->filelist[0].type |= S_IFDIR;
- filelist->filelist[1].relname= BLI_strdup("..");
- filelist->filelist[1].type |= S_IFDIR;
-
- for (i=0, l= names; i<nnames; i++, l= l->next) {
- char *blockname= l->link;
-
- filelist->filelist[i + 2].relname= BLI_strdup(blockname);
- if (!idcode)
- filelist->filelist[i + 2].type |= S_IFDIR;
- }
-
- if(previews) {
- for (i=0, l= previews; i<nnames; i++, l= l->next) {
- PreviewImage *img= l->link;
-
- if (img) {
- unsigned int w = img->w[PREVIEW_MIPMAP_LARGE];
- unsigned int h = img->h[PREVIEW_MIPMAP_LARGE];
- unsigned int *rect = img->rect[PREVIEW_MIPMAP_LARGE];
-
- /* first allocate imbuf for copying preview into it */
- if (w > 0 && h > 0 && rect) {
- ima = IMB_allocImBuf(w, h, 32, IB_rect, 0);
- memcpy(ima->rect, rect, w*h*sizeof(unsigned int));
- filelist->filelist[i + 2].image = ima;
- filelist->filelist[i + 2].flags = IMAGEFILE;
- }
- }
- }
- }
-
- BLI_linklist_free(names, free);
- if (previews) BLI_linklist_free(previews, (void(*)(void*)) MEM_freeN);
-
- filelist_sort(filelist, FILE_SORTALPHA);
-
- BLI_strncpy(G.sce, filename, sizeof(filename)); // prevent G.sce to change
-
- filelist->filter = 0;
- filelist_filter(filelist);
-}
-
-void filelist_append_library(struct FileList *filelist, char *dir, char *file, short flag, int idcode, struct Main *mainvar, struct Scene* scene)
-{
- // XXX todo: replace NULL with op->reports
- BLO_library_append(&filelist->libfiledata, filelist->filelist, filelist->numfiles, dir, file, flag, idcode, mainvar, scene, NULL);
-}
-
-void filelist_from_main(struct FileList *filelist)
-{
- ID *id;
- struct direntry *files, *firstlib = NULL;
- ListBase *lb;
- int a, fake, idcode, ok, totlib, totbl;
-
- filelist->type = FILE_MAIN;
-
- if(filelist->dir[0]=='/') filelist->dir[0]= 0;
-
- if(filelist->dir[0]) {
- idcode= BIF_groupname_to_code(filelist->dir);
- if(idcode==0) filelist->dir[0]= 0;
- }
-
- if( filelist->dir[0]==0) {
-
- /* make directories */
- filelist->numfiles= 23;
- filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
-
- for(a=0; a<filelist->numfiles; a++) {
- memset( &(filelist->filelist[a]), 0 , sizeof(struct direntry));
- filelist->filelist[a].type |= S_IFDIR;
- }
-
- filelist->filelist[0].relname= BLI_strdup("..");
- filelist->filelist[1].relname= BLI_strdup(".");
- filelist->filelist[2].relname= BLI_strdup("Scene");
- filelist->filelist[3].relname= BLI_strdup("Object");
- filelist->filelist[4].relname= BLI_strdup("Mesh");
- filelist->filelist[5].relname= BLI_strdup("Curve");
- filelist->filelist[6].relname= BLI_strdup("Metaball");
- filelist->filelist[7].relname= BLI_strdup("Material");
- filelist->filelist[8].relname= BLI_strdup("Texture");
- filelist->filelist[9].relname= BLI_strdup("Image");
- filelist->filelist[10].relname= BLI_strdup("Ika");
- filelist->filelist[11].relname= BLI_strdup("Wave");
- filelist->filelist[12].relname= BLI_strdup("Lattice");
- filelist->filelist[13].relname= BLI_strdup("Lamp");
- filelist->filelist[14].relname= BLI_strdup("Camera");
- filelist->filelist[15].relname= BLI_strdup("Ipo");
- filelist->filelist[16].relname= BLI_strdup("World");
- filelist->filelist[17].relname= BLI_strdup("Screen");
- filelist->filelist[18].relname= BLI_strdup("VFont");
- filelist->filelist[19].relname= BLI_strdup("Text");
- filelist->filelist[20].relname= BLI_strdup("Armature");
- filelist->filelist[21].relname= BLI_strdup("Action");
- filelist->filelist[22].relname= BLI_strdup("NodeTree");
- filelist_sort(filelist, FILE_SORTALPHA);
- }
- else {
-
- /* make files */
- idcode= BIF_groupname_to_code(filelist->dir);
-
- lb= wich_libbase(G.main, idcode );
- if(lb==0) return;
-
- id= lb->first;
- filelist->numfiles= 0;
- while(id) {
-
- if(filelist->has_func && idcode==ID_IP) {
- if(filelist->ipotype== ((Ipo *)id)->blocktype) filelist->numfiles++;
- }
- else if (!filelist->hide_dot || id->name[2] != '.') {
- filelist->numfiles++;
- }
-
- id= id->next;
- }
-
- if(!filelist->has_func) filelist->numfiles+= 2;
- filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry));
-
- files = filelist->filelist;
-
- if(!filelist->has_func) {
- memset( &(filelist->filelist[0]), 0 , sizeof(struct direntry));
- filelist->filelist[0].relname= BLI_strdup(".");
- filelist->filelist[0].type |= S_IFDIR;
- memset( &(filelist->filelist[1]), 0 , sizeof(struct direntry));
- filelist->filelist[1].relname= BLI_strdup("..");
- filelist->filelist[1].type |= S_IFDIR;
-
- files+= 2;
- }
-
- id= lb->first;
- totlib= totbl= 0;
-
- while(id) {
-
- ok= 0;
- if(filelist->has_func && idcode==ID_IP) {
- if(filelist->ipotype== ((Ipo *)id)->blocktype) ok= 1;
- }
- else ok= 1;
-
- if(ok) {
- /* TODO: hide dot files - elubie */
- memset( files, 0 , sizeof(struct direntry));
- if(id->lib==NULL)
- files->relname= BLI_strdup(id->name+2);
- else {
- files->relname= MEM_mallocN(FILE_MAXDIR+FILE_MAXFILE+32, "filename for lib");
- sprintf(files->relname, "%s | %s", id->lib->name, id->name+2);
- }
- /* files->type |= S_IFDIR; */
- if(!filelist->has_func) { /* F4 DATA BROWSE */
- if(idcode==ID_OB) {
- if( ((Object *)id)->flag & SELECT) files->flags |= ACTIVE;
- }
- else if(idcode==ID_SCE) {
- if( ((Scene *)id)->r.scemode & R_BG_RENDER) files->flags |= ACTIVE;
- }
- }
- files->nr= totbl+1;
- files->poin= id;
- fake= id->flag & LIB_FAKEUSER;
- if(idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
- files->flags |= IMAGEFILE;
- }
- if(id->lib && fake) sprintf(files->extra, "LF %d", id->us);
- else if(id->lib) sprintf(files->extra, "L %d", id->us);
- else if(fake) sprintf(files->extra, "F %d", id->us);
- else sprintf(files->extra, " %d", id->us);
-
- if(id->lib) {
- if(totlib==0) firstlib= files;
- totlib++;
- }
-
- files++;
- totbl++;
- }
-
- id= id->next;
- }
-
- /* only qsort of library blocks */
- if(totlib>1) {
- qsort(firstlib, totlib, sizeof(struct direntry), compare_name);
- }
- }
- filelist->filter = 0;
- filelist_filter(filelist);
-}
-
-
void filelist_settype(struct FileList* filelist, int type)
{
filelist->type = type;
@@ -1194,15 +895,3 @@ void filelist_sort(struct FileList* filelist, short sort)
}
filelist_filter(filelist);
}
-
-
-void filelist_setipotype(struct FileList* filelist, short ipotype)
-{
- filelist->ipotype = ipotype;
-}
-
-void filelist_hasfunc(struct FileList* filelist, int has_func)
-{
- filelist->has_func = has_func;
-}
-
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index e71bcbddb86..26a2d46f5a7 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -42,6 +42,19 @@ struct direntry;
struct BlendHandle;
struct Scene;
+#define MAX_FILE_COLUMN 8
+
+typedef enum FileListColumns {
+ COLUMN_NAME = 0,
+ COLUMN_DATE,
+ COLUMN_TIME,
+ COLUMN_SIZE,
+ COLUMN_MODE1,
+ COLUMN_MODE2,
+ COLUMN_MODE3,
+ COLUMN_OWNER
+} FileListColumns;
+
struct FileList * filelist_new();
void filelist_init_icons();
void filelist_free_icons();
@@ -62,23 +75,16 @@ void filelist_imgsize(struct FileList* filelist, short w, short h);
void filelist_loadimage(struct FileList* filelist, int index);
void filelist_loadimage_timer(struct FileList* filelist);
struct ImBuf * filelist_getimage(struct FileList* filelist, int index);
+struct ImBuf * filelist_geticon(struct FileList* filelist, int index);
short filelist_changed(struct FileList* filelist);
void filelist_readdir(struct FileList* filelist);
+int filelist_column_len(struct FileList* filelist, FileListColumns column);
int filelist_empty(struct FileList* filelist);
void filelist_parent(struct FileList* filelist);
void filelist_setfiletypes(struct FileList* filelist, short has_quicktime);
-int filelist_islibrary (struct FileList* filelist, char* dir, char* group);
-void filelist_from_main(struct FileList* filelist);
-void filelist_from_library(struct FileList* filelist);
-void filelist_append_library(struct FileList* filelist, char *dir, char* file, short flag, int idcode, struct Main *mainvar, struct Scene* scene);
void filelist_settype(struct FileList* filelist, int type);
short filelist_gettype(struct FileList* filelist);
-void filelist_setipotype(struct FileList* filelist, short ipotype);
-void filelist_hasfunc(struct FileList* filelist, int has_func);
-
-struct BlendHandle *filelist_lib(struct FileList* filelist);
-int groupname_to_code(char *group); /* TODO: where should this go */
#ifdef __cplusplus
}
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index f2eb7ad58ea..a422bda9503 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -58,6 +58,8 @@
#include "BKE_screen.h"
#include "BKE_global.h"
+#include "DNA_userdef_types.h"
+
#include "ED_screen.h"
#include "ED_util.h"
#include "ED_fileselect.h"
@@ -79,7 +81,7 @@
FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile)
{
if (!sfile->params) {
- ED_fileselect_set_params(sfile, FILE_UNIX, "", "/", 0, 0, 0);
+ ED_fileselect_set_params(sfile, FILE_UNIX, "", "/", 0, FILE_SHORTDISPLAY, 0);
}
return sfile->params;
}
@@ -132,3 +134,111 @@ void ED_fileselect_reset_params(SpaceFile *sfile)
sfile->params->flag = 0;
sfile->params->title[0] = '\0';
}
+
+
+int ED_fileselect_layout_offset(FileLayout* layout, int x, int y)
+{
+ int offsetx, offsety;
+ int active_file;
+
+ offsetx = (x)/(layout->tile_w + 2*layout->tile_border_x);
+ offsety = (y)/(layout->tile_h + 2*layout->tile_border_y);
+
+ if (offsetx > layout->columns-1) offsetx = layout->columns-1 ;
+ if (offsety > layout->rows-1) offsety = layout->rows-1 ;
+
+ if (layout->flag & FILE_LAYOUT_HOR)
+ active_file = layout->rows*offsetx + offsety;
+ else
+ active_file = offsetx + layout->columns*offsety;
+ printf("OFFSET %d %d %d %d %d\n", x,y, offsetx, offsety, active_file);
+ return active_file;
+}
+
+void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, short *x, short *y)
+{
+ if (layout->flag == FILE_LAYOUT_HOR) {
+ *x = layout->tile_border_x + (tile/layout->rows)*(layout->tile_w+2*layout->tile_border_x);
+ *y = layout->tile_border_y + (tile%layout->rows)*(layout->tile_h+2*layout->tile_border_y);
+ } else {
+ *x = layout->tile_border_x + ((tile)%layout->columns)*(layout->tile_w+2*layout->tile_border_x);
+ *y = layout->tile_border_y + ((tile)/layout->columns)*(layout->tile_h+2*layout->tile_border_y);
+ }
+}
+
+
+void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar)
+{
+ FileSelectParams* params = ED_fileselect_get_params(sfile);
+ View2D *v2d= &ar->v2d;
+ int maxlen = 0;
+ int numfiles = filelist_numfiles(sfile->files);
+
+ if (sfile->layout == 0) {
+ sfile->layout = MEM_callocN(sizeof(struct FileLayout), "file_layout");
+ }
+
+ if (params->display == FILE_IMGDISPLAY) {
+ sfile->layout->prv_w = 96;
+ sfile->layout->prv_h = 96;
+ sfile->layout->tile_border_x = 6;
+ sfile->layout->tile_border_y = 6;
+ sfile->layout->prv_border_x = 6;
+ sfile->layout->prv_border_y = 6;
+ sfile->layout->tile_w = sfile->layout->prv_w + 2*sfile->layout->prv_border_x;
+ sfile->layout->tile_h = sfile->layout->prv_h + 2*sfile->layout->prv_border_y + U.fontsize;
+ sfile->layout->width= (v2d->cur.xmax - v2d->cur.xmin - 2*sfile->layout->tile_border_x);
+ sfile->layout->columns= sfile->layout->width / (sfile->layout->tile_w + 2*sfile->layout->tile_border_x);
+ if(sfile->layout->columns > 0)
+ sfile->layout->rows= numfiles/sfile->layout->columns + 1; // XXX dirty, modulo is zero
+ else {
+ sfile->layout->columns = 1;
+ sfile->layout->rows= numfiles + 1; // XXX dirty, modulo is zero
+ }
+ sfile->layout->height= sfile->layout->rows*(sfile->layout->tile_h+2*sfile->layout->tile_border_y) + sfile->layout->tile_border_y*2;
+ sfile->layout->flag = FILE_LAYOUT_VER;
+ } else {
+ sfile->layout->prv_w = 0;
+ sfile->layout->prv_h = 0;
+ sfile->layout->tile_border_x = 8;
+ sfile->layout->tile_border_y = 2;
+ sfile->layout->prv_border_x = 0;
+ sfile->layout->prv_border_y = 0;
+ sfile->layout->tile_h = U.fontsize*3/2;
+ sfile->layout->height= v2d->cur.ymax - v2d->cur.ymin;
+ sfile->layout->rows = sfile->layout->height / (sfile->layout->tile_h + 2*sfile->layout->tile_border_y);;
+
+ if (params->display == FILE_SHORTDISPLAY) {
+ maxlen = filelist_column_len(sfile->files, COLUMN_NAME) +
+ filelist_column_len(sfile->files, COLUMN_SIZE);
+ maxlen += 20+2*10; // for icon and space between columns
+ } else {
+ maxlen = filelist_column_len(sfile->files, COLUMN_NAME) +
+ filelist_column_len(sfile->files, COLUMN_DATE) +
+ filelist_column_len(sfile->files, COLUMN_TIME) +
+ filelist_column_len(sfile->files, COLUMN_SIZE) /* +
+ filelist_column_len(sfile->files, COLUMN_MODE1) +
+ filelist_column_len(sfile->files, COLUMN_MODE2) +
+ filelist_column_len(sfile->files, COLUMN_MODE3) +
+ filelist_column_len(sfile->files, COLUMN_OWNER) */ ;
+ maxlen += 20+4*10; // for icon and space between columns
+ }
+ sfile->layout->tile_w = maxlen + 40;
+ if(sfile->layout->rows > 0)
+ sfile->layout->columns = numfiles/sfile->layout->rows + 1; // XXX dirty, modulo is zero
+ else {
+ sfile->layout->rows = 1;
+ sfile->layout->columns = numfiles + 1; // XXX dirty, modulo is zero
+ }
+ sfile->layout->width = sfile->layout->columns * (sfile->layout->tile_w + 2*sfile->layout->tile_border_x) + sfile->layout->tile_border_x*2;
+ sfile->layout->flag = FILE_LAYOUT_HOR;
+ }
+}
+
+FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar)
+{
+ if (!sfile->layout) {
+ ED_fileselect_init_layout(sfile, ar);
+ }
+ return sfile->layout;
+}
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 4ea62ea0397..6ef946c9697 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -59,106 +59,133 @@ struct _FSMenuEntry {
char *path;
short save;
+ short xs, ys;
};
-static FSMenuEntry *fsmenu= 0;
+typedef struct FSMenu
+{
+ FSMenuEntry *fsmenu_system;
+ FSMenuEntry *fsmenu_bookmarks;
+ FSMenuEntry *fsmenu_recent;
+
+ FSMenuCategory selected_category;
+ int selected_entry;
+
+} FSMenu;
+
+static FSMenu *g_fsmenu = NULL;
+
+struct FSMenu* fsmenu_get(void)
+{
+ if (!g_fsmenu) {
+ g_fsmenu=MEM_callocN(sizeof(struct FSMenu), "fsmenu");
+ }
+ return g_fsmenu;
+}
-int fsmenu_get_nentries(void)
+void fsmenu_select_entry(struct FSMenu* fsmenu, FSMenuCategory category, int index)
+{
+ fsmenu->selected_category = category;
+ fsmenu->selected_entry = index;
+}
+
+int fsmenu_is_selected(struct FSMenu* fsmenu, FSMenuCategory category, int index)
+{
+ return (category==fsmenu->selected_category) && (index==fsmenu->selected_entry);
+}
+
+static FSMenuEntry *fsmenu_get_category(struct FSMenu* fsmenu, FSMenuCategory category)
+{
+ FSMenuEntry *fsms = NULL;
+
+ switch(category) {
+ case FS_CATEGORY_SYSTEM:
+ fsms = fsmenu->fsmenu_system;
+ break;
+ case FS_CATEGORY_BOOKMARKS:
+ fsms = fsmenu->fsmenu_bookmarks;
+ break;
+ case FS_CATEGORY_RECENT:
+ fsms = fsmenu->fsmenu_recent;
+ break;
+ }
+ return fsms;
+}
+
+static void fsmenu_set_category(struct FSMenu* fsmenu, FSMenuCategory category, FSMenuEntry *fsms)
+{
+ switch(category) {
+ case FS_CATEGORY_SYSTEM:
+ fsmenu->fsmenu_system = fsms;
+ break;
+ case FS_CATEGORY_BOOKMARKS:
+ fsmenu->fsmenu_bookmarks = fsms;
+ break;
+ case FS_CATEGORY_RECENT:
+ fsmenu->fsmenu_recent = fsms;
+ break;
+ }
+}
+
+int fsmenu_get_nentries(struct FSMenu* fsmenu, FSMenuCategory category)
{
FSMenuEntry *fsme;
int count= 0;
- for (fsme= fsmenu; fsme; fsme= fsme->next)
+ for (fsme= fsmenu_get_category(fsmenu, category); fsme; fsme= fsme->next)
count++;
return count;
}
-int fsmenu_is_entry_a_separator(int idx)
+
+char *fsmenu_get_entry(struct FSMenu* fsmenu, FSMenuCategory category, int idx)
{
FSMenuEntry *fsme;
- for (fsme= fsmenu; fsme && idx; fsme= fsme->next)
+ for (fsme= fsmenu_get_category(fsmenu, category); fsme && idx; fsme= fsme->next)
idx--;
- return (fsme && !fsme->path)?1:0;
+ return fsme?fsme->path:NULL;
}
-char *fsmenu_get_entry(int idx)
+
+void fsmenu_set_pos(struct FSMenu* fsmenu, FSMenuCategory category, int idx, short xs, short ys)
{
FSMenuEntry *fsme;
- for (fsme= fsmenu; fsme && idx; fsme= fsme->next)
+ for (fsme= fsmenu_get_category(fsmenu, category); fsme && idx; fsme= fsme->next)
idx--;
- return fsme?fsme->path:NULL;
+ if (fsme) {
+ fsme->xs = xs;
+ fsme->ys = ys;
+ }
}
-char *fsmenu_build_menu(void)
+
+int fsmenu_get_pos (struct FSMenu* fsmenu, FSMenuCategory category, int idx, short* xs, short* ys)
{
- DynStr *ds= BLI_dynstr_new();
FSMenuEntry *fsme;
- char *menustr;
-
- for (fsme= fsmenu; fsme; fsme= fsme->next) {
- if (!fsme->path) {
- /* clean consecutive seperators and ignore trailing ones */
- if (fsme->next) {
- if (fsme->next->path) {
- BLI_dynstr_append(ds, "%l|");
- } else {
- FSMenuEntry *next= fsme->next;
- fsme->next= next->next;
- MEM_freeN(next);
- }
- }
- } else {
- if (fsme->save) {
- BLI_dynstr_append(ds, "o ");
- } else {
- BLI_dynstr_append(ds, " ");
- }
- BLI_dynstr_append(ds, fsme->path);
- if (fsme->next) BLI_dynstr_append(ds, "|");
- }
- }
- menustr= BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
- return menustr;
-}
-static FSMenuEntry *fsmenu_get_last_separator(void)
-{
- FSMenuEntry *fsme, *lsep=NULL;
+ for (fsme= fsmenu_get_category(fsmenu, category); fsme && idx; fsme= fsme->next)
+ idx--;
- for (fsme= fsmenu; fsme; fsme= fsme->next)
- if (!fsme->path)
- lsep= fsme;
+ if (fsme) {
+ *xs = fsme->xs;
+ *ys = fsme->ys;
+ return 1;
+ }
- return lsep;
+ return 0;
}
-static FSMenuEntry *fsmenu_get_first_separator(void)
-{
- FSMenuEntry *fsme, *lsep=NULL;
- for (fsme= fsmenu; fsme; fsme= fsme->next)
- if (!fsme->path) {
- lsep= fsme;
- break;
- }
-
- return lsep;
-}
-
-void fsmenu_insert_entry(char *path, int sorted, short save)
+void fsmenu_insert_entry(struct FSMenu* fsmenu, FSMenuCategory category, char *path, int sorted, short save)
{
FSMenuEntry *prev;
FSMenuEntry *fsme;
+ FSMenuEntry *fsms;
- if (save) {
- prev = fsmenu_get_first_separator();
- } else {
- prev = fsmenu_get_last_separator();
- }
- fsme= prev?prev->next:fsmenu;
+ fsms = fsmenu_get_category(fsmenu, category);
+ prev= fsme= fsms;
for (; fsme; prev= fsme, fsme= fsme->next) {
if (fsme->path) {
@@ -185,27 +212,17 @@ void fsmenu_insert_entry(char *path, int sorted, short save)
fsme->next= prev->next;
prev->next= fsme;
} else {
- fsme->next= fsmenu;
- fsmenu= fsme;
+ fsme->next= fsms;
+ fsmenu_set_category(fsmenu, category, fsme);
}
}
-void fsmenu_append_separator(void)
-{
- if (fsmenu) {
- FSMenuEntry *fsme= fsmenu;
-
- while (fsme->next) fsme= fsme->next;
- fsme->next= MEM_mallocN(sizeof(*fsme), "fsme");
- fsme->next->next= NULL;
- fsme->next->path= NULL;
- }
-}
-void fsmenu_remove_entry(int idx)
+void fsmenu_remove_entry(struct FSMenu* fsmenu, FSMenuCategory category, int idx)
{
- FSMenuEntry *prev= NULL, *fsme= fsmenu;
+ FSMenuEntry *prev= NULL, *fsme= NULL;
+ FSMenuEntry *fsms = fsmenu_get_category(fsmenu, category);
- for (fsme= fsmenu; fsme && idx; prev= fsme, fsme= fsme->next)
+ for (fsme= fsms; fsme && idx; prev= fsme, fsme= fsme->next)
idx--;
if (fsme) {
@@ -218,7 +235,8 @@ void fsmenu_remove_entry(int idx)
if (prev) {
prev->next= fsme->next;
} else {
- fsmenu= fsme->next;
+ fsms= fsme->next;
+ fsmenu_set_category(fsmenu, category, fsms);
}
/* free entry */
MEM_freeN(fsme->path);
@@ -227,14 +245,22 @@ void fsmenu_remove_entry(int idx)
}
}
-void fsmenu_write_file(const char *filename)
+void fsmenu_write_file(struct FSMenu* fsmenu, const char *filename)
{
- FSMenuEntry *fsme= fsmenu;
+ FSMenuEntry *fsme= NULL;
+ int count=FSMENU_RECENT_MAX;
FILE *fp = fopen(filename, "w");
if (!fp) return;
-
- for (fsme= fsmenu; fsme; fsme= fsme->next) {
+
+ fprintf(fp, "[Bookmarks]\n");
+ for (fsme= fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsme; fsme= fsme->next) {
+ if (fsme->path && fsme->save) {
+ fprintf(fp, "%s\n", fsme->path);
+ }
+ }
+ fprintf(fp, "[Recent]\n");
+ for (fsme= fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsme && count; fsme= fsme->next, --count) {
if (fsme->path && fsme->save) {
fprintf(fp, "%s\n", fsme->path);
}
@@ -242,9 +268,10 @@ void fsmenu_write_file(const char *filename)
fclose(fp);
}
-void fsmenu_read_file(const char *filename)
+void fsmenu_read_file(struct FSMenu* fsmenu, const char *filename)
{
char line[256];
+ FSMenuCategory category = FS_CATEGORY_BOOKMARKS;
FILE *fp;
#ifdef WIN32
@@ -264,19 +291,15 @@ void fsmenu_read_file(const char *filename)
tmps[2]='\\';
tmps[3]=0;
- fsmenu_insert_entry(tmps, 0, 0);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, 1, 0);
}
}
/* Adding Desktop and My Documents */
- fsmenu_append_separator();
-
SHGetSpecialFolderPath(0, folder, CSIDL_PERSONAL, 0);
- fsmenu_insert_entry(folder, 0, 0);
+ fsmenu_insert_entry(fsmenu,FS_CATEGORY_BOOKMARKS, folder, 1, 0);
SHGetSpecialFolderPath(0, folder, CSIDL_DESKTOPDIRECTORY, 0);
- fsmenu_insert_entry(folder, 0, 0);
-
- fsmenu_append_separator();
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, folder, 1, 0);
}
#endif
@@ -285,20 +308,26 @@ void fsmenu_read_file(const char *filename)
while ( fgets ( line, 256, fp ) != NULL ) /* read a line */
{
- int len = strlen(line);
- if (len>0) {
- if (line[len-1] == '\n') {
- line[len-1] = '\0';
+ if (strncmp(line, "[Bookmarks]", 11)==0){
+ category = FS_CATEGORY_BOOKMARKS;
+ } else if (strncmp(line, "[Recent]", 8)==0){
+ category = FS_CATEGORY_RECENT;
+ } else {
+ int len = strlen(line);
+ if (len>0) {
+ if (line[len-1] == '\n') {
+ line[len-1] = '\0';
+ }
+ fsmenu_insert_entry(fsmenu, category, line, 0, 1);
}
- fsmenu_insert_entry(line, 0, 1);
}
}
fclose(fp);
}
-void fsmenu_free(void)
+static void fsmenu_free_category(struct FSMenu* fsmenu, FSMenuCategory category)
{
- FSMenuEntry *fsme= fsmenu;
+ FSMenuEntry *fsme= fsmenu_get_category(fsmenu, category);
while (fsme) {
FSMenuEntry *n= fsme->next;
@@ -310,5 +339,11 @@ void fsmenu_free(void)
}
}
-
+void fsmenu_free(struct FSMenu* fsmenu)
+{
+ fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM);
+ fsmenu_free_category(fsmenu, FS_CATEGORY_BOOKMARKS);
+ fsmenu_free_category(fsmenu, FS_CATEGORY_RECENT);
+ MEM_freeN(fsmenu);
+}
diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h
index f4291673a3e..c51c45b7dc4 100644
--- a/source/blender/editors/space_file/fsmenu.h
+++ b/source/blender/editors/space_file/fsmenu.h
@@ -31,46 +31,54 @@
#ifndef BSE_FSMENU_H
#define BSE_FSMENU_H
- /** Returns the number of entries in the Fileselect Menu */
-int fsmenu_get_nentries (void);
+/* XXX could become UserPref */
+#define FSMENU_RECENT_MAX 10
- /** Returns true if the fsmenu entry at @a index exists and
- * is a seperator.
- */
-int fsmenu_is_entry_a_separator (int index);
+typedef enum FSMenuCategory {
+ FS_CATEGORY_SYSTEM,
+ FS_CATEGORY_BOOKMARKS,
+ FS_CATEGORY_RECENT
+} FSMenuCategory;
+
+struct FSMenu;
+
+struct FSMenu* fsmenu_get (void);
+
+ /** Returns the number of entries in the Fileselect Menu */
+int fsmenu_get_nentries (struct FSMenu* fsmenu, FSMenuCategory category);
/** Returns the fsmenu entry at @a index (or NULL if a bad index)
* or a separator.
*/
-char* fsmenu_get_entry (int index);
+char* fsmenu_get_entry (struct FSMenu* fsmenu, FSMenuCategory category, int index);
- /** Returns a new menu description string representing the
- * fileselect menu. Should be free'd with MEM_freeN.
- */
-char* fsmenu_build_menu (void);
+void fsmenu_select_entry (struct FSMenu* fsmenu, FSMenuCategory category, int index);
- /** Append a seperator to the FSMenu, inserts always follow the
- * last seperator.
- */
-void fsmenu_append_separator (void);
+int fsmenu_is_selected (struct FSMenu* fsmenu, FSMenuCategory category, int index);
+
+ /** Sets the position of the fsmenu entry at @a index */
+void fsmenu_set_pos (struct FSMenu* fsmenu, FSMenuCategory category, int index, short xs, short ys);
+
+ /** Returns the position of the fsmenu entry at @a index. return value is 1 if successful, 0 otherwise */
+int fsmenu_get_pos (struct FSMenu* fsmenu, FSMenuCategory category, int index, short* xs, short* ys);
/** Inserts a new fsmenu entry with the given @a path.
* Duplicate entries are not added.
* @param sorted Should entry be inserted in sorted order?
*/
-void fsmenu_insert_entry (char *path, int sorted, short save);
+void fsmenu_insert_entry (struct FSMenu* fsmenu, FSMenuCategory category, char *path, int sorted, short save);
/** Removes the fsmenu entry at the given @a index. */
-void fsmenu_remove_entry (int index);
+void fsmenu_remove_entry (struct FSMenu* fsmenu, FSMenuCategory category, int index);
/** saves the 'bookmarks' to the specified file */
-void fsmenu_write_file(const char *filename);
+void fsmenu_write_file (struct FSMenu* fsmenu, const char *filename);
/** reads the 'bookmarks' from the specified file */
-void fsmenu_read_file(const char *filename);
+void fsmenu_read_file (struct FSMenu* fsmenu, const char *filename);
/** Free's all the memory associated with the fsmenu */
-void fsmenu_free (void);
+void fsmenu_free (struct FSMenu* fsmenu);
#endif
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 70d7ad9cde5..084fcf1e5f6 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -62,6 +62,7 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+
#include "ED_markers.h"
#include "ED_fileselect.h"
@@ -83,13 +84,13 @@ static SpaceLink *file_new(const bContext *C)
ar= MEM_callocN(sizeof(ARegion), "header for file");
BLI_addtail(&sfile->regionbase, ar);
ar->regiontype= RGN_TYPE_HEADER;
- ar->alignment= RGN_ALIGN_BOTTOM;
+ ar->alignment= RGN_ALIGN_TOP;
/* channel list region */
ar= MEM_callocN(sizeof(ARegion), "channel area for file");
BLI_addtail(&sfile->regionbase, ar);
ar->regiontype= RGN_TYPE_CHANNELS;
- ar->alignment= RGN_ALIGN_LEFT;
+ ar->alignment= RGN_ALIGN_LEFT;
/* ui list region */
ar= MEM_callocN(sizeof(ARegion), "ui area for file");
@@ -117,7 +118,6 @@ static void file_free(SpaceLink *sl)
if(sfile->files) {
filelist_free(sfile->files);
- filelist_freelib(sfile->files);
MEM_freeN(sfile->files);
sfile->files= NULL;
}
@@ -128,6 +128,11 @@ static void file_free(SpaceLink *sl)
MEM_freeN(sfile->params);
sfile->params= NULL;
}
+
+ if (sfile->layout) {
+ MEM_freeN(sfile->layout);
+ sfile->layout = NULL;
+ }
}
@@ -153,6 +158,9 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
filelist_setdir(sfilen->files, sfilen->params->dir);
filelist_settype(sfilen->files, sfilen->params->type);
}
+ if (sfileo->layout) {
+ sfilen->layout= MEM_dupallocN(sfileo->layout);
+ }
return (SpaceLink *)sfilen;
}
@@ -175,7 +183,9 @@ static void file_main_area_draw(const bContext *C, ARegion *ar)
{
/* draw entirely, view changes should be handled here */
SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
- FileSelectParams* params = sfile->params;
+ FileSelectParams *params = ED_fileselect_get_params(sfile);
+ FileLayout *layout=NULL;
+
View2D *v2d= &ar->v2d;
View2DScrollers *scrollers;
float col[3];
@@ -187,6 +197,8 @@ static void file_main_area_draw(const bContext *C, ARegion *ar)
params->active_file = -1; // added this so it opens nicer (ton)
}
+ layout = ED_fileselect_get_layout(sfile, ar);
+
if (filelist_empty(sfile->files))
{
unsigned int filter = 0;
@@ -209,11 +221,17 @@ static void file_main_area_draw(const bContext *C, ARegion *ar)
glClear(GL_COLOR_BUFFER_BIT);
/* Allow dynamically sliders to be set, saves notifiers etc. */
- if (sfile->params && (sfile->params->display == FILE_IMGDISPLAY) )
+ if (layout && (layout->flag == FILE_LAYOUT_VER)) {
v2d->scroll = V2D_SCROLL_RIGHT;
- else
+ v2d->keepofs &= ~V2D_LOCKOFS_Y;
+ v2d->keepofs |= V2D_LOCKOFS_X;
+ }
+ else {
v2d->scroll = V2D_SCROLL_BOTTOM;
- /* v2d has initialized flag, so this call will only set the mask correct */
+ v2d->keepofs &= ~V2D_LOCKOFS_X;
+ v2d->keepofs |= V2D_LOCKOFS_Y;
+ }
+ /* v2d has initialized flag, so this call will only set the mask correct */
UI_view2d_region_reinit(v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* sets tile/border settings in sfile */
@@ -248,14 +266,16 @@ static void file_main_area_draw(const bContext *C, ARegion *ar)
void file_operatortypes(void)
{
WM_operatortype_append(FILE_OT_select);
- WM_operatortype_append(FILE_OT_select_all);
- WM_operatortype_append(FILE_OT_border_select);
+ WM_operatortype_append(FILE_OT_select_all_toggle);
+ WM_operatortype_append(FILE_OT_select_border);
WM_operatortype_append(FILE_OT_select_bookmark);
WM_operatortype_append(FILE_OT_loadimages);
WM_operatortype_append(FILE_OT_highlight);
WM_operatortype_append(FILE_OT_exec);
WM_operatortype_append(FILE_OT_cancel);
WM_operatortype_append(FILE_OT_parent);
+ WM_operatortype_append(FILE_OT_refresh);
+ WM_operatortype_append(FILE_OT_bookmark_toggle);
}
/* NOTE: do not add .blend file reading on this level */
@@ -263,8 +283,8 @@ void file_keymap(struct wmWindowManager *wm)
{
ListBase *keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0);
WM_keymap_add_item(keymap, "FILE_OT_select", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "FILE_OT_select_all", AKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "FILE_OT_border_select", BKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "FILE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "FILE_OT_select_border", BKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_highlight", MOUSEMOVE, KM_ANY, 0, 0);
WM_keymap_add_item(keymap, "FILE_OT_parent", PKEY, KM_PRESS, 0, 0);
@@ -291,7 +311,7 @@ static void file_channel_area_draw(const bContext *C, ARegion *ar)
View2D *v2d= &ar->v2d;
float col[3];
- UI_GetThemeColor3fv(TH_BACK, col);
+ UI_GetThemeColor3fv(TH_PANEL, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -339,7 +359,7 @@ static void file_ui_area_draw(const bContext *C, ARegion *ar)
{
float col[3];
/* clear */
- UI_GetThemeColor3fv(TH_BACK, col);
+ UI_GetThemeColor3fv(TH_PANEL, col);
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -392,7 +412,7 @@ void ED_spacetype_file(void)
/* regions: ui */
art= MEM_callocN(sizeof(ARegionType), "spacetype file region");
art->regionid = RGN_TYPE_UI;
- art->minsizey= 100;
+ art->minsizey= 60;
art->keymapflag= ED_KEYMAP_UI;
art->init= file_ui_area_init;
art->draw= file_ui_area_draw;
@@ -401,7 +421,7 @@ void ED_spacetype_file(void)
/* regions: channels (directories) */
art= MEM_callocN(sizeof(ARegionType), "spacetype file region");
art->regionid = RGN_TYPE_CHANNELS;
- art->minsizex= 200;
+ art->minsizex= 240;
art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
art->init= file_channel_area_init;
art->draw= file_channel_area_draw;
@@ -415,13 +435,13 @@ void ED_file_init(void)
{
char name[FILE_MAX];
BLI_make_file_string("/", name, BLI_gethome(), ".Bfs");
- fsmenu_read_file(name);
+ fsmenu_read_file(fsmenu_get(), name);
filelist_init_icons();
IMB_thumb_makedirs();
}
void ED_file_exit(void)
{
- fsmenu_free();
+ fsmenu_free(fsmenu_get());
filelist_free_icons();
}
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index 859aab9283e..5207d4843f7 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -52,6 +52,7 @@
#include "BKE_curve.h"
#include "BKE_customdata.h"
#include "BKE_depsgraph.h"
+#include "BKE_fcurve.h"
#include "BKE_object.h"
#include "BKE_global.h"
#include "BKE_scene.h"
@@ -132,7 +133,7 @@ static void graph_panel_properties(const bContext *C, ARegion *ar, short cntrl,
*/
}
-/* -------------- */
+/* ******************* drivers ******************************** */
#define B_IPO_DEPCHANGE 10
@@ -216,44 +217,595 @@ static void graph_panel_drivers(const bContext *C, ARegion *ar, short cntrl, bAn
}
}
-/* -------------- */
+/* ******************* f-modifiers ******************************** */
+
+#define B_FMODIFIER_REDRAW 20
static void do_graph_region_modifier_buttons(bContext *C, void *arg, int event)
{
- //Scene *scene= CTX_data_scene(C);
+ switch (event) {
+ case B_REDR:
+ case B_FMODIFIER_REDRAW: // XXX this should send depsgraph updates too
+ ED_area_tag_redraw(CTX_wm_area(C));
+ return; /* no notifier! */
+ }
+}
+
+/* macro for use here to draw background box and set height */
+// XXX for now, roundbox has it's callback func set to NULL to not intercept events
+#define DRAW_BACKDROP(height) \
+ { \
+ if (active) uiBlockSetCol(block, TH_BUT_ACTION); \
+ but= uiDefBut(block, ROUNDBOX, B_REDR, "", 10-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12.0, (float)rb_col, ""); \
+ uiButSetFunc(but, NULL, NULL, NULL); \
+ if (active) uiBlockSetCol(block, TH_AUTO); \
+ }
+
+/* callback to verify modifier data */
+static void validate_fmodifier_cb (bContext *C, void *fcu_v, void *fcm_v)
+{
+ FModifier *fcm= (FModifier *)fcm_v;
+ FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
- switch(event) {
+ /* call the verify callback on the modifier if applicable */
+ if (fmi && fmi->verify_data)
+ fmi->verify_data(fcm);
+}
+
+/* callback to set the active modifier */
+static void activate_fmodifier_cb (bContext *C, void *fcu_v, void *fcm_v)
+{
+ FCurve *fcu= (FCurve *)fcu_v;
+ FModifier *fcm= (FModifier *)fcm_v;
+
+ /* call API function to set the active modifier for active F-Curve */
+ fcurve_set_active_modifier(fcu, fcm);
+}
+/* callback to remove the given modifier */
+static void delete_fmodifier_cb (bContext *C, void *fcu_v, void *fcm_v)
+{
+ FCurve *fcu= (FCurve *)fcu_v;
+ FModifier *fcm= (FModifier *)fcm_v;
+
+ /* remove the given F-Modifier from the F-Curve */
+ fcurve_remove_modifier(fcu, fcm);
+}
+
+/* --------------- */
+
+/* draw settings for generator modifier */
+static void draw_modifier__generator(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco, short *height, short width, short active, int rb_col)
+{
+ FMod_Generator *data= (FMod_Generator *)fcm->data;
+ char gen_mode[]="Generator Type%t|Expanded Polynomial%x0|Factorised Polynomial%x1|Built-In Function%x2|Expression%x3";
+ char fn_type[]="Built-In Function%t|Sin%x0|Cos%x1|Tan%x2|Square Root%x3|Natural Log%x4";
+ int cy= *yco - 30;
+ uiBut *but;
+
+ /* set the height */
+ (*height) = 90;
+ switch (data->mode) {
+ case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
+ (*height) += 20*(data->poly_order+1) + 35;
+ break;
+ case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* factorised polynomial */
+ (*height) += 20 * data->poly_order;
+ break;
+ case FCM_GENERATOR_FUNCTION: /* builtin function */
+ (*height) += 50; // xxx
+ break;
+ case FCM_GENERATOR_EXPRESSION: /* py-expression */
+ // xxx nothing to draw
+ break;
}
- /* default for now */
- //WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+ /* basic settings (backdrop + mode selector + some padding) */
+ //DRAW_BACKDROP((*height)); // XXX buggy...
+ uiBlockBeginAlign(block);
+ but= uiDefButS(block, MENU, B_FMODIFIER_REDRAW, gen_mode, 10,cy,width-30,19, &data->mode, 0, 0, 0, 0, "Selects type of generator algorithm.");
+ uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm);
+ cy -= 20;
+
+ uiDefButBitS(block, TOG, FCM_GENERATOR_ADDITIVE, B_FMODIFIER_REDRAW, "Additive", 10,cy,width-30,19, &data->flag, 0, 0, 0, 0, "Values generated by this modifier are applied on top of the existing values instead of overwriting them");
+ cy -= 35;
+ uiBlockEndAlign(block);
+
+ /* now add settings for individual modes */
+ switch (data->mode) {
+ case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
+ {
+ float *cp = NULL;
+ char xval[32];
+ unsigned int i;
+
+ /* draw polynomial order selector */
+ but= uiDefButS(block, NUM, B_FMODIFIER_REDRAW, "Poly Order: ", 10,cy,width-30,19, &data->poly_order, 1, 100, 0, 0, "'Order' of the Polynomial - for a polynomial with n terms, 'order' is n-1");
+ uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm);
+ cy -= 35;
+
+ /* draw controls for each coefficient and a + sign at end of row */
+ uiDefBut(block, LABEL, 1, "y = ", 0, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
+
+ cp= data->coefficients;
+ for (i=0; (i < data->arraysize) && (cp); i++, cp++) {
+ /* coefficient */
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 50, cy, 150, 20, cp, -FLT_MAX, FLT_MAX, 10, 3, "Coefficient for polynomial");
+
+ /* 'x' param (and '+' if necessary) */
+ if (i == 0)
+ strcpy(xval, "");
+ else if (i == 1)
+ strcpy(xval, "x");
+ else
+ sprintf(xval, "x^%d", i);
+ uiDefBut(block, LABEL, 1, xval, 200, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "Power of x");
+
+ if ( (i != (data->arraysize - 1)) || ((i==0) && data->arraysize==2) )
+ uiDefBut(block, LABEL, 1, "+", 250, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+
+ cy -= 20;
+ }
+ }
+ break;
+
+ case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* factorised polynomial expression */
+ {
+ float *cp = NULL;
+ unsigned int i;
+
+ /* draw polynomial order selector */
+ but= uiDefButS(block, NUM, B_FMODIFIER_REDRAW, "Poly Order: ", 10,cy,width-30,19, &data->poly_order, 1, 100, 0, 0, "'Order' of the Polynomial - for a polynomial with n terms, 'order' is n-1");
+ uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm);
+ cy -= 35;
+
+ /* draw controls for each pair of coefficients */
+ uiDefBut(block, LABEL, 1, "y = ", 0, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
+
+ cp= data->coefficients;
+ for (i=0; (i < data->poly_order) && (cp); i++, cp+=2) {
+ /* opening bracket */
+ uiDefBut(block, LABEL, 1, "(", 40, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
+
+ /* coefficients */
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 50, cy, 100, 20, cp, -FLT_MAX, FLT_MAX, 10, 3, "Coefficient of x");
+
+ uiDefBut(block, LABEL, 1, "x + ", 150, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 180, cy, 100, 20, cp+1, -FLT_MAX, FLT_MAX, 10, 3, "Second coefficient");
+
+ /* closing bracket and '+' sign */
+ if ( (i != (data->poly_order - 1)) || ((i==0) && data->poly_order==2) )
+ uiDefBut(block, LABEL, 1, ") ×", 280, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+ else
+ uiDefBut(block, LABEL, 1, ")", 280, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+
+ cy -= 20;
+ }
+ }
+ break;
+
+ case FCM_GENERATOR_FUNCTION: /* built-in function */
+ {
+ float *cp= data->coefficients;
+
+ /* draw function selector */
+ but= uiDefButS(block, MENU, B_FMODIFIER_REDRAW, fn_type, 10,cy,width-30,19, &data->func_type, 0, 0, 0, 0, "Built-In Function to use");
+ uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm);
+ cy -= 35;
+
+ /* draw controls for equation of coefficients */
+ /* row 1 */
+ {
+ uiDefBut(block, LABEL, 1, "y = ", 0, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 50, cy, 150, 20, cp+3, -FLT_MAX, FLT_MAX, 10, 3, "Coefficient (D) for function");
+ uiDefBut(block, LABEL, 1, "+", 200, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+ cy -= 20;
+ }
+
+ /* row 2 */
+ {
+ char func_name[32];
+
+ /* coefficient outside bracket */
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, cy, 80, 20, cp, -FLT_MAX, FLT_MAX, 10, 3, "Coefficient (A) for function");
+
+ /* opening bracket */
+ switch (data->func_type)
+ {
+ case FCM_GENERATOR_FN_SIN: /* sine wave */
+ sprintf(func_name, "sin(");
+ break;
+ case FCM_GENERATOR_FN_COS: /* cosine wave */
+ sprintf(func_name, "cos(");
+ break;
+ case FCM_GENERATOR_FN_TAN: /* tangent wave */
+ sprintf(func_name, "tan(");
+ break;
+ case FCM_GENERATOR_FN_LN: /* natural log */
+ sprintf(func_name, "ln(");
+ break;
+ case FCM_GENERATOR_FN_SQRT: /* square root */
+ sprintf(func_name, "sqrt(");
+ break;
+ default: /* unknown */
+ sprintf(func_name, "<fn?>(");
+ break;
+ }
+ uiDefBut(block, LABEL, 1, func_name, 80, cy, 40, 20, NULL, 0.0, 0.0, 0, 0, "");
+
+ /* coefficients inside bracket */
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 115, cy, 75, 20, cp+1, -FLT_MAX, FLT_MAX, 10, 3, "Coefficient (B) of x");
+
+ uiDefBut(block, LABEL, 1, "x+", 190, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 220, cy, 80, 20, cp+2, -FLT_MAX, FLT_MAX, 10, 3, "Coefficient (C) of function");
+
+ /* closing bracket */
+ uiDefBut(block, LABEL, 1, ")", 300, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
+ cy -= 20;
+ }
+ }
+ break;
+
+ case FCM_GENERATOR_EXPRESSION: /* py-expression */
+ // TODO...
+ break;
+ }
+}
+
+/* --------------- */
+
+/* draw settings for cycles modifier */
+static void draw_modifier__cycles(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco, short *height, short width, short active, int rb_col)
+{
+ FMod_Cycles *data= (FMod_Cycles *)fcm->data;
+ char cyc_mode[]="Cycling Mode%t|No Cycles%x0|Repeat Motion%x1|Repeat with Offset%x2";
+ int cy= (*yco - 30), cy1= (*yco - 50), cy2= (*yco - 70);
+
+ /* set the height */
+ (*height) = 90;
+
+ /* basic settings (backdrop + some padding) */
+ //DRAW_BACKDROP((*height)); // XXX buggy...
+
+ /* 'before' range */
+ uiDefBut(block, LABEL, 1, "Before:", 10, cy, 80, 20, NULL, 0.0, 0.0, 0, 0, "Settings for cycling before first keyframe");
+ uiBlockBeginAlign(block);
+ uiDefButS(block, MENU, B_FMODIFIER_REDRAW, cyc_mode, 10,cy1,150,20, &data->before_mode, 0, 0, 0, 0, "Cycling mode to use before first keyframe");
+ uiDefButS(block, NUM, B_FMODIFIER_REDRAW, "Max Cycles:", 10, cy2, 150, 20, &data->before_cycles, 0, 10000, 10, 3, "Maximum number of cycles to allow (0 = infinite)");
+ uiBlockEndAlign(block);
+
+ /* 'after' range */
+ uiDefBut(block, LABEL, 1, "After:", 160, cy, 80, 20, NULL, 0.0, 0.0, 0, 0, "Settings for cycling after last keyframe");
+ uiBlockBeginAlign(block);
+ uiDefButS(block, MENU, B_FMODIFIER_REDRAW, cyc_mode, 170,cy1,150,20, &data->after_mode, 0, 0, 0, 0, "Cycling mode to use after first keyframe");
+ uiDefButS(block, NUM, B_FMODIFIER_REDRAW, "Max Cycles:", 170, cy2, 150, 20, &data->after_cycles, 0, 10000, 10, 3, "Maximum number of cycles to allow (0 = infinite)");
+ uiBlockEndAlign(block);
+}
+
+/* --------------- */
+
+#define BINARYSEARCH_FRAMEEQ_THRESH 0.0001
+
+/* Binary search algorithm for finding where to insert Envelope Data Point.
+ * Returns the index to insert at (data already at that index will be offset if replace is 0)
+ */
+static int binarysearch_fcm_envelopedata_index (FCM_EnvelopeData array[], float frame, int arraylen, short *exists)
+{
+ int start=0, end=arraylen;
+ int loopbreaker= 0, maxloop= arraylen * 2;
+
+ /* initialise exists-flag first */
+ *exists= 0;
+
+ /* sneaky optimisations (don't go through searching process if...):
+ * - keyframe to be added is to be added out of current bounds
+ * - keyframe to be added would replace one of the existing ones on bounds
+ */
+ if ((arraylen <= 0) || (array == NULL)) {
+ printf("Warning: binarysearch_fcm_envelopedata_index() encountered invalid array \n");
+ return 0;
+ }
+ else {
+ /* check whether to add before/after/on */
+ float framenum;
+
+ /* 'First' Point (when only one point, this case is used) */
+ framenum= array[0].time;
+ if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
+ *exists = 1;
+ return 0;
+ }
+ else if (frame < framenum)
+ return 0;
+
+ /* 'Last' Point */
+ framenum= array[(arraylen-1)].time;
+ if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
+ *exists= 1;
+ return (arraylen - 1);
+ }
+ else if (frame > framenum)
+ return arraylen;
+ }
+
+
+ /* most of the time, this loop is just to find where to put it
+ * - 'loopbreaker' is just here to prevent infinite loops
+ */
+ for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
+ /* compute and get midpoint */
+ int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */
+ float midfra= array[mid].time;
+
+ /* check if exactly equal to midpoint */
+ if (IS_EQT(frame, midfra, BINARYSEARCH_FRAMEEQ_THRESH)) {
+ *exists = 1;
+ return mid;
+ }
+
+ /* repeat in upper/lower half */
+ if (frame > midfra)
+ start= mid + 1;
+ else if (frame < midfra)
+ end= mid - 1;
+ }
+
+ /* print error if loop-limit exceeded */
+ if (loopbreaker == (maxloop-1)) {
+ printf("Error: binarysearch_fcm_envelopedata_index() was taking too long \n");
+
+ // include debug info
+ printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
+ }
+
+ /* not found, so return where to place it */
+ return start;
+}
+
+/* callback to add new envelope data point */
+// TODO: should we have a separate file for things like this?
+static void fmod_envelope_addpoint_cb (bContext *C, void *fcm_dv, void *dummy)
+{
+ Scene *scene= CTX_data_scene(C);
+ FMod_Envelope *env= (FMod_Envelope *)fcm_dv;
+ FCM_EnvelopeData *fedn;
+ FCM_EnvelopeData fed;
+
+ /* init template data */
+ fed.min= -1.0f;
+ fed.max= 1.0f;
+ fed.time= (float)scene->r.cfra; // XXX make this int for ease of use?
+ fed.f1= fed.f2= 0;
+
+ /* check that no data exists for the current frame... */
+ if (env->data) {
+ short exists = -1;
+ int i= binarysearch_fcm_envelopedata_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
+
+ /* binarysearch_...() will set exists by default to 0, so if it is non-zero, that means that the point exists already */
+ if (exists)
+ return;
+
+ /* add new */
+ fedn= MEM_callocN((env->totvert+1)*sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
+
+ /* add the points that should occur before the point to be pasted */
+ if (i > 0)
+ memcpy(fedn, env->data, i*sizeof(FCM_EnvelopeData));
+
+ /* add point to paste at index i */
+ *(fedn + i)= fed;
+
+ /* add the points that occur after the point to be pasted */
+ if (i < env->totvert)
+ memcpy(fedn+i+1, env->data+i, (env->totvert-i)*sizeof(FCM_EnvelopeData));
+
+ /* replace (+ free) old with new */
+ MEM_freeN(env->data);
+ env->data= fedn;
+
+ env->totvert++;
+ }
+ else {
+ env->data= MEM_callocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
+ *(env->data)= fed;
+
+ env->totvert= 1;
+ }
+}
+
+/* callback to remove envelope data point */
+// TODO: should we have a separate file for things like this?
+static void fmod_envelope_deletepoint_cb (bContext *C, void *fcm_dv, void *ind_v)
+{
+ FMod_Envelope *env= (FMod_Envelope *)fcm_dv;
+ FCM_EnvelopeData *fedn;
+ int index= GET_INT_FROM_POINTER(ind_v);
+
+ /* check that no data exists for the current frame... */
+ if (env->totvert > 1) {
+ /* allocate a new smaller array */
+ fedn= MEM_callocN(sizeof(FCM_EnvelopeData)*(env->totvert-1), "FCM_EnvelopeData");
+
+ memcpy(fedn, &env->data, sizeof(FCM_EnvelopeData)*(index));
+ memcpy(&fedn[index], &env->data[index+1], sizeof(FCM_EnvelopeData)*(env->totvert-index-1));
+
+ /* free old array, and set the new */
+ MEM_freeN(env->data);
+ env->data= fedn;
+ env->totvert--;
+ }
+ else {
+ /* just free array, since the only vert was deleted */
+ if (env->data)
+ MEM_freeN(env->data);
+ env->totvert= 0;
+ }
+}
+
+/* draw settings for envelope modifier */
+static void draw_modifier__envelope(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco, short *height, short width, short active, int rb_col)
+{
+ FMod_Envelope *env= (FMod_Envelope *)fcm->data;
+ FCM_EnvelopeData *fed;
+ uiBut *but;
+ int cy= (*yco - 30);
+ int i;
+
+ /* set the height:
+ * - basic settings + variable height from envelope controls
+ */
+ (*height) = 96 + (25 * env->totvert);
+
+ /* basic settings (backdrop + general settings + some padding) */
+ //DRAW_BACKDROP((*height)); // XXX buggy...
+
+ /* General Settings */
+ uiDefBut(block, LABEL, 1, "Envelope:", 10, cy, 100, 20, NULL, 0.0, 0.0, 0, 0, "Settings for cycling before first keyframe");
+ cy -= 20;
+
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Reference Val:", 10, cy, 300, 20, &env->midval, -FLT_MAX, FLT_MAX, 10, 3, "");
+ cy -= 20;
+
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Min:", 10, cy, 150, 20, &env->min, -FLT_MAX, env->max, 10, 3, "Minimum value (relative to Reference Value) that is used as the 'normal' minimum value");
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Max:", 160, cy, 150, 20, &env->max, env->min, FLT_MAX, 10, 3, "Maximum value (relative to Reference Value) that is used as the 'normal' maximum value");
+ cy -= 35;
+ uiBlockEndAlign(block);
+
+
+ /* Points header */
+ uiDefBut(block, LABEL, 1, "Control Points:", 10, cy, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
+
+ but= uiDefBut(block, BUT, B_FMODIFIER_REDRAW, "Add Point", 160,cy,150,19, NULL, 0, 0, 0, 0, "Adds a new control-point to the envelope on the current frame");
+ uiButSetFunc(but, fmod_envelope_addpoint_cb, env, NULL);
+ cy -= 35;
+
+ /* Points List */
+ for (i=0, fed=env->data; i < env->totvert; i++, fed++) {
+ uiBlockBeginAlign(block);
+ but=uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Fra:", 5, cy, 100, 20, &fed->time, -FLT_MAX, FLT_MAX, 10, 3, "Frame that envelope point occurs");
+ uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm);
+
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Min:", 105, cy, 100, 20, &fed->min, -FLT_MAX, FLT_MAX, 10, 3, "Minimum bound of envelope at this point");
+ uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Max:", 205, cy, 100, 20, &fed->max, -FLT_MAX, FLT_MAX, 10, 3, "Maximum bound of envelope at this point");
+
+ but= uiDefIconBut(block, BUT, B_FMODIFIER_REDRAW, ICON_X, 305, cy, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Delete envelope control point");
+ uiButSetFunc(but, fmod_envelope_deletepoint_cb, env, SET_INT_IN_POINTER(i));
+ uiBlockBeginAlign(block);
+ cy -= 25;
+ }
+}
+
+/* --------------- */
+
+static void graph_panel_modifier_draw(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco)
+{
+ FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
+ uiBut *but;
+ short active= (fcm->flag & FMODIFIER_FLAG_ACTIVE);
+ short width= 314;
+ short height = 0;
+ int rb_col;
+
+ /* draw header */
+ {
+ uiBlockSetEmboss(block, UI_EMBOSSN);
+
+ /* rounded header */
+#if 0 // XXX buggy...
+ if (active) uiBlockSetCol(block, TH_BUT_ACTION);
+ rb_col= (active)?-20:20;
+ but= uiDefBut(block, ROUNDBOX, B_REDR, "", 10-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15.0, (float)(rb_col-20), "");
+ if (active) uiBlockSetCol(block, TH_AUTO);
+#endif // XXX buggy
+
+ /* expand */
+ uiDefIconButBitS(block, ICONTOG, FMODIFIER_FLAG_EXPANDED, B_REDR, ICON_TRIA_RIGHT, 5, *yco-1, 20, 20, &fcm->flag, 0.0, 0.0, 0, 0, "Modifier is expanded");
+
+ /* checkbox for 'active' status (for now) */
+ but= uiDefIconButBitS(block, ICONTOG, FMODIFIER_FLAG_ACTIVE, B_REDR, ICON_RADIOBUT_OFF, 25, *yco-1, 20, 20, &fcm->flag, 0.0, 0.0, 0, 0, "Modifier is active one");
+ uiButSetFunc(but, activate_fmodifier_cb, fcu, fcm);
+
+ /* name */
+ if (fmi)
+ but= uiDefBut(block, LABEL, 1, fmi->name, 10+40, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "F-Curve Modifier Type. Click to make modifier active one.");
+ else
+ but= uiDefBut(block, LABEL, 1, "<Unknown Modifier>", 10+40, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "F-Curve Modifier Type. Click to make modifier active one.");
+
+ /* delete button */
+ but= uiDefIconBut(block, BUT, B_REDR, ICON_X, 10+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete F-Curve Modifier.");
+ uiButSetFunc(but, delete_fmodifier_cb, fcu, fcm);
+
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ }
+
+ /* when modifier is expanded, draw settings */
+ if (fcm->flag & FMODIFIER_FLAG_EXPANDED) {
+ /* draw settings for individual modifiers */
+ switch (fcm->type) {
+ case FMODIFIER_TYPE_GENERATOR: /* Generator */
+ draw_modifier__generator(block, fcu, fcm, yco, &height, width, active, rb_col);
+ break;
+
+ case FMODIFIER_TYPE_CYCLES: /* Cycles */
+ draw_modifier__cycles(block, fcu, fcm, yco, &height, width, active, rb_col);
+ break;
+
+ case FMODIFIER_TYPE_ENVELOPE: /* Envelope */
+ draw_modifier__envelope(block, fcu, fcm, yco, &height, width, active, rb_col);
+ break;
+
+ default: /* unknown type */
+ height= 96;
+ //DRAW_BACKDROP(height); // XXX buggy...
+ break;
+ }
+ }
+
+ /* adjust height for new to start */
+ (*yco) -= (height + 27);
}
static void graph_panel_modifiers(const bContext *C, ARegion *ar, short cntrl, bAnimListElem *ale)
{
- //FCurve *fcu= (FCurve *)ale->data;
- //FModifier *fcm;
+ FCurve *fcu= (FCurve *)ale->data;
+ FModifier *fcm;
uiBlock *block;
-
+ int yco= 190;
+
block= uiBeginBlock(C, ar, "graph_panel_modifiers", UI_EMBOSS, UI_HELV);
if (uiNewPanel(C, ar, block, "Modifiers", "Graph", 340, 30, 318, 254)==0) return;
uiBlockSetHandleFunc(block, do_graph_region_modifier_buttons, NULL);
-
- /* to force height */
- uiNewPanelHeight(block, 204); // XXX variable height!
+ uiNewPanelHeight(block, 204);
+
+ /* 'add modifier' button at top of panel */
+ // XXX for now, this will be a operator button which calls a temporary 'add modifier' operator
+ uiDefButO(block, BUT, "GRAPHEDIT_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, "Add Modifier", 10, 225, 150, 20, "Adds a new F-Curve Modifier for the active F-Curve");
+ /* draw each modifier */
+ for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next)
+ graph_panel_modifier_draw(block, fcu, fcm, &yco);
+
+ /* since these buttons can have variable height */
+ if (yco < 0)
+ uiNewPanelHeight(block, (204 - yco));
+ else
+ uiNewPanelHeight(block, 204);
}
-/* -------------- */
+/* ******************* general ******************************** */
/* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).
* We return the 'wrapper' since it contains valuable context info (about hierarchy), which will need to be freed
* when the caller is done with it.
*/
// TODO: move this to anim api with another name?
-static bAnimListElem *get_active_fcurve_channel (bAnimContext *ac)
+bAnimListElem *get_active_fcurve_channel (bAnimContext *ac)
{
ListBase anim_data = {NULL, NULL};
int filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE | ANIMFILTER_CURVESONLY);
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 1efa257c317..46d3f102b89 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -27,6 +27,7 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
+#include <float.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -90,7 +91,57 @@ extern void ui_rasterpos_safe(float x, float y, float aspect);
extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad);
/* *************************** */
-/* Curve Drawing */
+/* F-Curve Modifier Drawing */
+
+/* Envelope -------------- */
+
+// TODO: draw a shaded poly showing the region of influence too!!!
+static void draw_fcurve_modifier_controls_envelope (FCurve *fcu, FModifier *fcm, View2D *v2d)
+{
+ FMod_Envelope *env= (FMod_Envelope *)fcm->data;
+ FCM_EnvelopeData *fed;
+ const float fac= 0.05f * (v2d->cur.xmax - v2d->cur.xmin);
+ int i;
+
+ /* draw two black lines showing the standard reference levels */
+ glColor3f(0.0f, 0.0f, 0.0f);
+ setlinestyle(5);
+
+ glBegin(GL_LINES);
+ glVertex2f(v2d->cur.xmin, env->midval+env->min);
+ glVertex2f(v2d->cur.xmax, env->midval+env->min);
+
+ glVertex2f(v2d->cur.xmin, env->midval+env->max);
+ glVertex2f(v2d->cur.xmax, env->midval+env->max);
+ glEnd(); // GL_LINES
+ setlinestyle(0);
+
+ /* set size of vertices (non-adjustable for now) */
+ glPointSize(2.0f);
+
+ // for now, point color is fixed, and is white
+ glColor3f(1.0f, 1.0f, 1.0f);
+
+ /* we use bgl points not standard gl points, to workaround vertex
+ * drawing bugs that some drivers have (probably legacy ones only though)
+ */
+ bglBegin(GL_POINTS);
+ for (i=0, fed=env->data; i < env->totvert; i++, fed++) {
+ /* only draw if visible
+ * - min/max here are fixed, not relative
+ */
+ if IN_RANGE(fed->time, (v2d->cur.xmin - fac), (v2d->cur.xmax + fac)) {
+ glVertex2f(fed->time, fed->min);
+ glVertex2f(fed->time, fed->max);
+ }
+ }
+ bglEnd();
+
+ glPointSize(1.0f);
+}
+
+/* *************************** */
+/* F-Curve Drawing */
/* Points ---------------- */
@@ -401,9 +452,62 @@ static void draw_fcurve_samples (SpaceIpo *sipo, ARegion *ar, FCurve *fcu)
/* Curve ---------------- */
+/* minimum pixels per gridstep
+ * XXX: defined in view2d.c - must keep these in sync or relocate to View2D header!
+ */
+#define MINGRIDSTEP 35
+
+/* helper func - just draw the F-Curve by sampling the visible region (for drawing curves with modifiers) */
+static void draw_fcurve_curve (FCurve *fcu, SpaceIpo *sipo, View2D *v2d, View2DGrid *grid)
+{
+ ChannelDriver *driver;
+ float samplefreq, ctime;
+ float stime, etime;
+
+ /* disable any drivers temporarily */
+ driver= fcu->driver;
+ fcu->driver= NULL;
+
+
+ /* Note about sampling frequency:
+ * Ideally, this is chosen such that we have 1-2 pixels = 1 segment
+ * which means that our curves can be as smooth as possible. However,
+ * this does mean that curves may not be fully accurate (i.e. if they have
+ * sudden spikes which happen at the sampling point, we may have problems).
+ * Also, this may introduce lower performance on less densely detailed curves,'
+ * though it is impossible to predict this from the modifiers!
+ *
+ * If the automatically determined sampling frequency is likely to cause an infinite
+ * loop (i.e. too close to FLT_EPSILON), fall back to default of 0.001
+ */
+ /* grid->dx is the first float in View2DGrid struct, so just cast to float pointer, and use it
+ * It represents the number of 'frames' between gridlines, but we divide by MINGRIDSTEP to get pixels-steps
+ */
+ // TODO: perhaps we should have 1.0 frames as upper limit so that curves don't get too distorted?
+ samplefreq= *((float *)grid) / MINGRIDSTEP;
+ if (IS_EQ(samplefreq, 0)) samplefreq= 0.001f;
+
+
+ /* the start/end times are simply the horizontal extents of the 'cur' rect */
+ stime= v2d->cur.xmin;
+ etime= v2d->cur.xmax;
+
+
+ /* at each sampling interval, add a new vertex */
+ glBegin(GL_LINE_STRIP);
+
+ for (ctime= stime; ctime <= etime; ctime += samplefreq)
+ glVertex2f( ctime, evaluate_fcurve(fcu, ctime) );
+
+ glEnd();
+
+ /* restore driver */
+ fcu->driver= driver;
+}
+
/* helper func - draw a samples-based F-Curve */
// TODO: add offset stuff...
-static void draw_fcurve_repeat_samples (FCurve *fcu, View2D *v2d)
+static void draw_fcurve_curve_samples (FCurve *fcu, View2D *v2d)
{
FPoint *prevfpt= fcu->fpt;
FPoint *fpt= prevfpt + 1;
@@ -412,26 +516,23 @@ static void draw_fcurve_repeat_samples (FCurve *fcu, View2D *v2d)
glBegin(GL_LINE_STRIP);
- /* extrapolate to left? */
- if ( (fcu->modifiers.first == NULL)/* || ( ((FModifier *)fcu->modifiers.first)->type != FMODIFIER_TYPE_CYCLES) */) {
- /* left-side of view comes before first keyframe, so need to extend as not cyclic */
- if (prevfpt->vec[0] > v2d->cur.xmin) {
- v[0]= v2d->cur.xmin;
-
- /* y-value depends on the interpolation */
- if ((fcu->extend==FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (fcu->totvert==1)) {
- /* just extend across the first keyframe's value */
- v[1]= prevfpt->vec[1];
- }
- else {
- /* extrapolate linear dosnt use the handle, use the next points center instead */
- fac= (prevfpt->vec[0]-fpt->vec[0])/(prevfpt->vec[0]-v[0]);
- if (fac) fac= 1.0f/fac;
- v[1]= prevfpt->vec[1]-fac*(prevfpt->vec[1]-fpt->vec[1]);
- }
-
- glVertex2fv(v);
+ /* extrapolate to left? - left-side of view comes before first keyframe? */
+ if (prevfpt->vec[0] > v2d->cur.xmin) {
+ v[0]= v2d->cur.xmin;
+
+ /* y-value depends on the interpolation */
+ if ((fcu->extend==FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (fcu->totvert==1)) {
+ /* just extend across the first keyframe's value */
+ v[1]= prevfpt->vec[1];
+ }
+ else {
+ /* extrapolate linear dosnt use the handle, use the next points center instead */
+ fac= (prevfpt->vec[0]-fpt->vec[0])/(prevfpt->vec[0]-v[0]);
+ if (fac) fac= 1.0f/fac;
+ v[1]= prevfpt->vec[1]-fac*(prevfpt->vec[1]-fpt->vec[1]);
}
+
+ glVertex2fv(v);
}
/* if only one sample, add it now */
@@ -440,7 +541,6 @@ static void draw_fcurve_repeat_samples (FCurve *fcu, View2D *v2d)
/* loop over samples, drawing segments */
/* draw curve between first and last keyframe (if there are enough to do so) */
- // XXX this doesn't take into account modifiers, or sample data
while (b--) {
/* Linear interpolation: just add one point (which should add a new line segment) */
glVertex2fv(prevfpt->vec);
@@ -455,95 +555,90 @@ static void draw_fcurve_repeat_samples (FCurve *fcu, View2D *v2d)
}
/* extrapolate to right? (see code for left-extrapolation above too) */
- if ( (fcu->modifiers.first == NULL)/* || ( ((FModifier *)fcu->modifiers.first)->type != FMODIFIER_TYPE_CYCLES) */) {
- if (prevfpt->vec[0] < v2d->cur.xmax) {
- v[0]= v2d->cur.xmax;
-
- /* y-value depends on the interpolation */
- if ((fcu->extend==FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (fcu->totvert==1)) {
- /* based on last keyframe's value */
- v[1]= prevfpt->vec[1];
- }
- else {
- /* extrapolate linear dosnt use the handle, use the previous points center instead */
- fpt = prevfpt-1;
- fac= (prevfpt->vec[0]-fpt->vec[0])/(prevfpt->vec[0]-v[0]);
- if (fac) fac= 1.0f/fac;
- v[1]= prevfpt->vec[1]-fac*(prevfpt->vec[1]-fpt->vec[1]);
- }
-
- glVertex2fv(v);
+ if (prevfpt->vec[0] < v2d->cur.xmax) {
+ v[0]= v2d->cur.xmax;
+
+ /* y-value depends on the interpolation */
+ if ((fcu->extend==FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (fcu->totvert==1)) {
+ /* based on last keyframe's value */
+ v[1]= prevfpt->vec[1];
+ }
+ else {
+ /* extrapolate linear dosnt use the handle, use the previous points center instead */
+ fpt = prevfpt-1;
+ fac= (prevfpt->vec[0]-fpt->vec[0])/(prevfpt->vec[0]-v[0]);
+ if (fac) fac= 1.0f/fac;
+ v[1]= prevfpt->vec[1]-fac*(prevfpt->vec[1]-fpt->vec[1]);
}
+
+ glVertex2fv(v);
}
glEnd();
}
/* helper func - draw one repeat of an F-Curve */
-static void draw_fcurve_repeat (FCurve *fcu, View2D *v2d, float cycxofs, float cycyofs, float *facp)
+static void draw_fcurve_curve_bezts (FCurve *fcu, View2D *v2d, View2DGrid *grid)
{
BezTriple *prevbezt= fcu->bezt;
BezTriple *bezt= prevbezt+1;
float v1[2], v2[2], v3[2], v4[2];
float *fp, data[120];
- float fac= *(facp);
+ float fac= 0.0f;
int b= fcu->totvert-1;
int resol;
glBegin(GL_LINE_STRIP);
/* extrapolate to left? */
- if ( (fcu->modifiers.first == NULL)/* || ( ((FModifier *)fcu->modifiers.first)->type != FMODIFIER_TYPE_CYCLES) */) {
+ if (prevbezt->vec[1][0] > v2d->cur.xmin) {
/* left-side of view comes before first keyframe, so need to extend as not cyclic */
- if (prevbezt->vec[1][0] > v2d->cur.xmin) {
- v1[0]= v2d->cur.xmin;
-
- /* y-value depends on the interpolation */
- if ((fcu->extend==FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (prevbezt->ipo==BEZT_IPO_CONST) || (fcu->totvert==1)) {
- /* just extend across the first keyframe's value */
- v1[1]= prevbezt->vec[1][1];
- }
- else if (prevbezt->ipo==BEZT_IPO_LIN) {
- /* extrapolate linear dosnt use the handle, use the next points center instead */
- fac= (prevbezt->vec[1][0]-bezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
- if (fac) fac= 1.0f/fac;
- v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[1][1]-bezt->vec[1][1]);
- }
- else {
- /* based on angle of handle 1 (relative to keyframe) */
- fac= (prevbezt->vec[0][0]-prevbezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
- if (fac) fac= 1.0f/fac;
- v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[0][1]-prevbezt->vec[1][1]);
- }
-
- glVertex2fv(v1);
+ v1[0]= v2d->cur.xmin;
+
+ /* y-value depends on the interpolation */
+ if ((fcu->extend==FCURVE_EXTRAPOLATE_CONSTANT) || (prevbezt->ipo==BEZT_IPO_CONST) || (fcu->totvert==1)) {
+ /* just extend across the first keyframe's value */
+ v1[1]= prevbezt->vec[1][1];
+ }
+ else if (prevbezt->ipo==BEZT_IPO_LIN) {
+ /* extrapolate linear dosnt use the handle, use the next points center instead */
+ fac= (prevbezt->vec[1][0]-bezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
+ if (fac) fac= 1.0f/fac;
+ v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[1][1]-bezt->vec[1][1]);
+ }
+ else {
+ /* based on angle of handle 1 (relative to keyframe) */
+ fac= (prevbezt->vec[0][0]-prevbezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
+ if (fac) fac= 1.0f/fac;
+ v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[0][1]-prevbezt->vec[1][1]);
}
+
+ glVertex2fv(v1);
}
/* if only one keyframe, add it now */
if (fcu->totvert == 1) {
- v1[0]= prevbezt->vec[1][0] + cycxofs;
- v1[1]= prevbezt->vec[1][1] + cycyofs;
+ v1[0]= prevbezt->vec[1][0];
+ v1[1]= prevbezt->vec[1][1];
glVertex2fv(v1);
}
/* draw curve between first and last keyframe (if there are enough to do so) */
- // XXX this doesn't take into account modifiers, or sample data
while (b--) {
- if ((fcu->flag & FCURVE_INT_VALUES) || (prevbezt->ipo==BEZT_IPO_CONST)) {
+ if (prevbezt->ipo==BEZT_IPO_CONST) {
/* Constant-Interpolation: draw segment between previous keyframe and next, but holding same value */
- v1[0]= prevbezt->vec[1][0]+cycxofs;
- v1[1]= prevbezt->vec[1][1]+cycyofs;
+ v1[0]= prevbezt->vec[1][0];
+ v1[1]= prevbezt->vec[1][1];
glVertex2fv(v1);
- v1[0]= bezt->vec[1][0]+cycxofs;
- v1[1]= prevbezt->vec[1][1]+cycyofs;
+ v1[0]= bezt->vec[1][0];
+ v1[1]= prevbezt->vec[1][1];
glVertex2fv(v1);
}
else if (prevbezt->ipo==BEZT_IPO_LIN) {
/* Linear interpolation: just add one point (which should add a new line segment) */
- v1[0]= prevbezt->vec[1][0]+cycxofs;
- v1[1]= prevbezt->vec[1][1]+cycyofs;
+ v1[0]= prevbezt->vec[1][0];
+ v1[1]= prevbezt->vec[1][1];
glVertex2fv(v1);
}
else {
@@ -560,23 +655,23 @@ static void draw_fcurve_repeat (FCurve *fcu, View2D *v2d, float cycxofs, float c
if (resol < 2) {
/* only draw one */
- v1[0]= prevbezt->vec[1][0]+cycxofs;
- v1[1]= prevbezt->vec[1][1]+cycyofs;
+ v1[0]= prevbezt->vec[1][0];
+ v1[1]= prevbezt->vec[1][1];
glVertex2fv(v1);
}
else {
/* clamp resolution to max of 32 */
if (resol > 32) resol= 32;
- v1[0]= prevbezt->vec[1][0]+cycxofs;
- v1[1]= prevbezt->vec[1][1]+cycyofs;
- v2[0]= prevbezt->vec[2][0]+cycxofs;
- v2[1]= prevbezt->vec[2][1]+cycyofs;
+ v1[0]= prevbezt->vec[1][0];
+ v1[1]= prevbezt->vec[1][1];
+ v2[0]= prevbezt->vec[2][0];
+ v2[1]= prevbezt->vec[2][1];
- v3[0]= bezt->vec[0][0]+cycxofs;
- v3[1]= bezt->vec[0][1]+cycyofs;
- v4[0]= bezt->vec[1][0]+cycxofs;
- v4[1]= bezt->vec[1][1]+cycyofs;
+ v3[0]= bezt->vec[0][0];
+ v3[1]= bezt->vec[0][1];
+ v4[0]= bezt->vec[1][0];
+ v4[1]= bezt->vec[1][1];
correct_bezpart(v1, v2, v3, v4);
@@ -594,152 +689,41 @@ static void draw_fcurve_repeat (FCurve *fcu, View2D *v2d, float cycxofs, float c
/* last point? */
if (b == 0) {
- v1[0]= prevbezt->vec[1][0]+cycxofs;
- v1[1]= prevbezt->vec[1][1]+cycyofs;
+ v1[0]= prevbezt->vec[1][0];
+ v1[1]= prevbezt->vec[1][1];
glVertex2fv(v1);
}
}
/* extrapolate to right? (see code for left-extrapolation above too) */
- if ( (fcu->modifiers.first == NULL)/* || ( ((FModifier *)fcu->modifiers.first)->type != FMODIFIER_TYPE_CYCLES) */) {
- if (prevbezt->vec[1][0] < v2d->cur.xmax) {
- v1[0]= v2d->cur.xmax;
-
- /* y-value depends on the interpolation */
- if ((fcu->extend==FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (prevbezt->ipo==BEZT_IPO_CONST) || (fcu->totvert==1)) {
- /* based on last keyframe's value */
- v1[1]= prevbezt->vec[1][1];
- }
- else if (prevbezt->ipo==BEZT_IPO_LIN) {
- /* extrapolate linear dosnt use the handle, use the previous points center instead */
- bezt = prevbezt-1;
- fac= (prevbezt->vec[1][0]-bezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
- if (fac) fac= 1.0f/fac;
- v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[1][1]-bezt->vec[1][1]);
- }
- else {
- /* based on angle of handle 1 (relative to keyframe) */
- fac= (prevbezt->vec[2][0]-prevbezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
- if (fac) fac= 1.0f/fac;
- v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[2][1]-prevbezt->vec[1][1]);
- }
-
- glVertex2fv(v1);
+ if (prevbezt->vec[1][0] < v2d->cur.xmax) {
+ v1[0]= v2d->cur.xmax;
+
+ /* y-value depends on the interpolation */
+ if ((fcu->extend==FCURVE_EXTRAPOLATE_CONSTANT) || (fcu->flag & FCURVE_INT_VALUES) || (prevbezt->ipo==BEZT_IPO_CONST) || (fcu->totvert==1)) {
+ /* based on last keyframe's value */
+ v1[1]= prevbezt->vec[1][1];
+ }
+ else if (prevbezt->ipo==BEZT_IPO_LIN) {
+ /* extrapolate linear dosnt use the handle, use the previous points center instead */
+ bezt = prevbezt-1;
+ fac= (prevbezt->vec[1][0]-bezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
+ if (fac) fac= 1.0f/fac;
+ v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[1][1]-bezt->vec[1][1]);
+ }
+ else {
+ /* based on angle of handle 1 (relative to keyframe) */
+ fac= (prevbezt->vec[2][0]-prevbezt->vec[1][0])/(prevbezt->vec[1][0]-v1[0]);
+ if (fac) fac= 1.0f/fac;
+ v1[1]= prevbezt->vec[1][1]-fac*(prevbezt->vec[2][1]-prevbezt->vec[1][1]);
}
+
+ glVertex2fv(v1);
}
glEnd();
-
- /* return fac, as we alter it */
- *(facp) = fac;
}
-#if 0 // XXX old animation system unconverted code!
-
-/* draw all ipo-curves */
-static void draw_ipocurves(SpaceIpo *sipo, ARegion *ar, int sel)
-{
- View2D *v2d= &ar->v2d;
- EditIpo *ei;
- int nr, val/*, pickselcode=0*/;
-
- /* if we're drawing for GL_SELECT, reset pickselcode first
- * - there's only one place that will do this, so it should be fine
- */
- //if (G.f & G_PICKSEL)
- // pickselcode= 1;
-
- ei= sipo->editipo;
- for (nr=0; nr<sipo->totipo; nr++, ei++) {
- if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) {
- /* val is used to indicate if curve can be edited */
- //if (G.f & G_PICKSEL) {
- // /* when using OpenGL to select stuff (on mouseclick) */
- // glLoadName(pickselcode++);
- // val= 1;
- //}
- //else {
- /* filter to only draw those that are selected or unselected (based on drawing mode */
- val= (ei->flag & (IPO_SELECT+IPO_EDIT)) != 0;
- val= (val==sel);
- //}
-
- /* only draw those curves that we can draw */
- if (val) {
- IpoCurve *icu= ei->icu;
- float cycdx=0.0f, cycdy=0.0f, cycxofs=0.0f, cycyofs=0.0f;
- const int lastindex= (icu->totvert-1);
- float fac= 0.0f;
- int cycount=1;
-
- /* set color for curve curve:
- * - bitflag curves (evil) must always be drawn coloured as they cannot work with IPO-Keys
- * - when IPO-Keys are shown, individual curves are not editable, so we show by drawing them all black
- */
- if ((sipo->showkey) && (ei->disptype!=IPO_DISPBITS)) UI_ThemeColor(TH_TEXT);
- else cpack(ei->col);
-
- /* cyclic curves - get offset and number of repeats to display */
- if (icu->extrap & IPO_CYCL) {
- BezTriple *bezt= icu->bezt;
- BezTriple *lastbezt= bezt + lastindex;
-
- /* calculate cycle length and amplitude */
- cycdx= lastbezt->vec[1][0] - bezt->vec[1][0];
- cycdy= lastbezt->vec[1][1] - bezt->vec[1][1];
-
- /* check that the cycle does have some length */
- if (cycdx > 0.01f) {
- /* count cycles before first frame */
- while (icu->bezt->vec[1][0]+cycxofs > v2d->cur.xmin) {
- cycxofs -= cycdx;
- if (icu->extrap & IPO_DIR) cycyofs-= cycdy;
- cycount++;
- }
-
- /* count cycles after last frame (and adjust offset) */
- fac= 0.0f;
- while (lastbezt->vec[1][0]+fac < v2d->cur.xmax) {
- cycount++;
- fac += cycdx;
- }
- }
- }
-
- /* repeat process for each repeat */
- while (cycount--) {
- /* bitflag curves are drawn differently to normal curves */
- if (ei->disptype==IPO_DISPBITS)
- draw_ipocurve_repeat_bits(icu, v2d, cycxofs);
- else
- draw_ipocurve_repeat_normal(icu, v2d, cycxofs, cycyofs, &fac);
-
- /* prepare for next cycle by adjusing offsets */
- cycxofs += cycdx;
- if (icu->extrap & IPO_DIR) cycyofs += cycdy;
- }
-
- /* vertical line that indicates the end of a speed curve */
- if ((sipo->blocktype==ID_CU) && (icu->adrcode==CU_SPEED)) {
- int b= icu->totvert-1;
-
- if (b) {
- BezTriple *bezt= icu->bezt+b;
-
- glColor3ub(0, 0, 0);
-
- glBegin(GL_LINES);
- glVertex2f(bezt->vec[1][0], 0.0f);
- glVertex2f(bezt->vec[1][0], bezt->vec[1][1]);
- glEnd();
- }
- }
- }
- }
- }
-}
-#endif // XXX old animation system unconverted code
-
#if 0
static void draw_ipokey(SpaceIpo *sipo, ARegion *ar)
{
@@ -758,7 +742,9 @@ static void draw_ipokey(SpaceIpo *sipo, ARegion *ar)
}
#endif
-void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
+/* Public Curve-Drawing API ---------------- */
+
+void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid *grid)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
@@ -774,20 +760,22 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
*/
for (ale=anim_data.first; ale; ale=ale->next) {
FCurve *fcu= (FCurve *)ale->key_data;
- Object *nob= ANIM_nla_mapping_get(ac, ale);
- float fac=0.0f; // dummy var
+ FModifier *fcm= fcurve_find_active_modifier(fcu);
+ //Object *nob= ANIM_nla_mapping_get(ac, ale);
/* map keyframes for drawing if scaled F-Curve */
- if (nob)
- ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 0, 0);
+ //if (nob)
+ // ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 0, 0);
- /* draw curve - if there's an active modifier (or a stack of modifiers) drawing these takes presidence,
- * unless modifiers in use will not alter any of the values within the keyframed area...
+ /* draw curve:
+ * - curve line may be result of one or more destructive modifiers or just the raw data,
+ * so we need to check which method should be used
+ * - controls from active modifier take precidence over keyframes
+ * (XXX! editing tools need to take this into account!)
*/
-
-
- /* draw curve - as defined by keyframes */
- if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) {
+
+ /* 1) draw curve line */
+ {
/* set color/drawing style for curve itself */
if ( ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) || (fcu->flag & FCURVE_PROTECTED) ) {
/* protected curves (non editable) are drawn with dotted lines */
@@ -803,18 +791,50 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
glColor3fv(fcu->color);
}
+ /* anti-aliased lines for less jagged appearance */
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+
/* draw F-Curve */
- if (fcu->bezt)
- draw_fcurve_repeat(fcu, &ar->v2d, 0, 0, &fac); // XXX this call still needs a lot more work
- else if (fcu->fpt)
- draw_fcurve_repeat_samples(fcu, &ar->v2d);
- /*else modifiers? */
+ if ((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) {
+ /* draw a curve affected by modifiers or only allowed to have integer values
+ * by sampling it at various small-intervals over the visible region
+ */
+ draw_fcurve_curve(fcu, sipo, &ar->v2d, grid);
+ }
+ else if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) {
+ /* just draw curve based on defined data (i.e. no modifiers) */
+ if (fcu->bezt)
+ draw_fcurve_curve_bezts(fcu, &ar->v2d, grid);
+ else if (fcu->fpt)
+ draw_fcurve_curve_samples(fcu, &ar->v2d);
+ }
/* restore settings */
setlinestyle(0);
-
- /* draw handles and vertices as appropriate */
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_BLEND);
+ }
+
+ /* 2) draw handles and vertices as appropriate based on active */
+ if ( ((fcm) && (fcm->type != FMODIFIER_TYPE_CYCLES)) || (fcu->modifiers.first && !fcm) ) {
+ /* draw controls for the 'active' modifier
+ * - there may not be an 'active' modifier on this curve to draw
+ * - this curve may not be active, so modifier controls shouldn't get drawn either
+ *
+ * NOTE: cycles modifier is currently an exception where the original points can still be edited, so
+ * this branch is skipped... (TODO: set up the generic system for this so that we don't need special hacks like this)
+ */
+ if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) {
+ switch (fcm->type) {
+ case FMODIFIER_TYPE_ENVELOPE: /* envelope */
+ draw_fcurve_modifier_controls_envelope(fcu, fcm, &ar->v2d);
+ break;
+ }
+ }
+ }
+ else if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) {
if (fcu->bezt) {
/* only draw handles/vertices on keyframes */
draw_fcurve_handles(sipo, ar, fcu);
@@ -827,8 +847,8 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
}
/* undo mapping of keyframes for drawing if scaled F-Curve */
- if (nob)
- ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 1, 0);
+ //if (nob)
+ // ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 1, 0);
}
/* free list of curves */
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 932b22c0a6e..de020e8ce70 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -177,11 +177,11 @@ static int graphkeys_previewrange_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_set_previewrange (wmOperatorType *ot)
+void GRAPHEDIT_OT_previewrange_set (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Auto-Set Preview Range";
- ot->idname= "GRAPHEDIT_OT_set_previewrange";
+ ot->idname= "GRAPHEDIT_OT_previewrange_set";
/* api callbacks */
ot->exec= graphkeys_previewrange_exec;
@@ -256,7 +256,7 @@ static short copy_graph_keys (bAnimContext *ac)
free_anim_copybuf();
/* filter data */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* copy keyframes */
@@ -1011,6 +1011,91 @@ void GRAPHEDIT_OT_keyframes_handletype (wmOperatorType *ot)
/* ************************************************************************** */
/* TRANSFORM STUFF */
+/* ***************** 'Euler Filter' Operator **************************** */
+/* Euler filter tools (as seen in Maya), are necessary for working with 'baked'
+ * rotation curves (with Euler rotations). The main purpose of such tools is to
+ * resolve any discontinuities that may arise in the curves due to the clamping
+ * of values to -180 degrees to 180 degrees.
+ */
+
+#if 0 // XXX this is not ready for the primetime yet
+
+/* set of three euler-rotation F-Curves */
+typedef struct tEulerFilter {
+ ID *id; /* ID-block which owns the channels */
+ FCurve *fcu1, *fcu2, *fcu3; /* x,y,z rotation curves */
+ int i1, i2, i3; /* current index for each curve */
+} tEulerFilter;
+
+static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+
+ ListBase anim_data= {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ ListBase eulers = {NULL, NULL};
+ tEulerFilter *euf= NULL;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* The process is done in two passes:
+ * 1) Sets of three related rotation curves are identified from the selected channels,
+ * and are stored as a single 'operation unit' for the next step
+ * 2) Each set of three F-Curves is processed for each keyframe, with the values being
+ * processed according to one of several ways.
+ */
+
+ /* step 1: extract only the rotation f-curves */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* check if this is an appropriate F-Curve
+ * - only rotation curves
+ * - for pchan curves, make sure we're only using the euler curves
+ */
+ if (ELEM(0, fcu->rna_path, strstr(fcu->rna_path, "rotation")))
+ continue;
+ if (strstr(fcu->rna_path, "pose.pose_channels")) {
+ if (strstr(fcu->rna_path, "euler_rotation") == 0)
+ continue;
+ }
+
+ /* check if current set of 3-curves is suitable to add this curve to
+ * - things like whether the current set of curves is 'full' should be checked later only
+ * - first check if id-blocks are compatible
+ */
+ if ((euf) && (ale->id != euf->id)) {
+
+ }
+ }
+
+ // XXX for now
+ return OPERATOR_CANCELLED;
+}
+
+void GRAPHEDIT_OT_keyframes_euler_filter (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Euler Filter";
+ ot->idname= "GRAPHEDIT_OT_keyframes_euler_filter";
+
+ /* api callbacks */
+ ot->exec= graphkeys_euler_filter_exec;
+ ot->poll= ED_operator_areaactive;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+#endif // XXX this is not ready for the primetime yet
+
/* ***************** Snap Current Frame Operator *********************** */
/* helper callback for graphkeys_cfrasnap_exec() -> used to help get the average time of all selected beztriples */
@@ -1332,3 +1417,81 @@ void GRAPHEDIT_OT_keyframes_smooth (wmOperatorType *ot)
}
/* ************************************************************************** */
+/* F-CURVE MODIFIERS */
+
+/* ******************** Add F-Curve Modifier Operator *********************** */
+
+/* F-Modifier types - duplicate of existing codes... */
+ // XXX how can we have this list from the RNA definitions instead?
+EnumPropertyItem prop_fmodifier_types[] = {
+ {FMODIFIER_TYPE_GENERATOR, "GENERATOR", "Generator", ""},
+ {FMODIFIER_TYPE_ENVELOPE, "ENVELOPE", "Envelope", ""},
+ {FMODIFIER_TYPE_CYCLES, "CYCLES", "Cycles", ""},
+ {FMODIFIER_TYPE_NOISE, "NOISE", "Noise", ""},
+ {FMODIFIER_TYPE_FILTER, "FILTER", "Filter", ""},
+ {FMODIFIER_TYPE_PYTHON, "PYTHON", "Python", ""},
+ {0, NULL, NULL, NULL}
+};
+
+static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ bAnimListElem *ale;
+ FCurve *fcu;
+ FModifier *fcm;
+ short type;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ // xxx call the raw methods here instead?
+ ale= get_active_fcurve_channel(&ac);
+ if (ale == NULL)
+ return OPERATOR_CANCELLED;
+
+ fcu= (FCurve *)ale->data;
+ MEM_freeN(ale);
+ if (fcu == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* get type of modifier to add */
+ type= RNA_enum_get(op->ptr, "type");
+
+ /* add F-Modifier of specified type to active F-Curve, and make it the active one */
+ fcm= fcurve_add_modifier(fcu, type);
+ if (fcm)
+ fcurve_set_active_modifier(fcu, fcm);
+ else {
+ BKE_report(op->reports, RPT_ERROR, "Modifier couldn't be added. See console for details.");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* validate keyframes after editing */
+ ANIM_editkeyframes_refresh(&ac);
+
+ /* set notifier that things have changed */
+ ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH);
+
+ return OPERATOR_FINISHED;
+}
+
+void GRAPHEDIT_OT_fmodifier_add (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add F-Curve Modifier";
+ ot->idname= "GRAPHEDIT_OT_fmodifier_add";
+
+ /* api callbacks */
+ ot->invoke= WM_menu_invoke;
+ ot->exec= graph_fmodifier_add_exec;
+ ot->poll= ED_operator_areaactive; // XXX need active F-Curve
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* id-props */
+ RNA_def_enum(ot->srna, "type", prop_fmodifier_types, 0, "Type", "");
+}
+
+/* ************************************************************************** */
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 6144556378a..06fda53fc67 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -31,9 +31,11 @@
struct bContext;
struct wmWindowManager;
struct bAnimContext;
+struct bAnimListElem;
struct SpaceIpo;
struct ScrArea;
struct ARegion;
+struct View2DGrid;
/* internal exports only */
@@ -44,7 +46,7 @@ struct ARegion *graph_has_buttons_region(struct ScrArea *sa);
/* ***************************************** */
/* graph_draw.c */
void graph_draw_channel_names(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar);
-void graph_draw_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar);
+void graph_draw_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar, struct View2DGrid *grid);
/* ***************************************** */
/* graph_header.c */
@@ -53,8 +55,8 @@ void graph_header_buttons(const bContext *C, struct ARegion *ar);
/* ***************************************** */
/* graph_select.c */
-void GRAPHEDIT_OT_keyframes_deselectall(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_borderselect(struct wmOperatorType *ot);
+void GRAPHEDIT_OT_keyframes_select_all_toggle(struct wmOperatorType *ot);
+void GRAPHEDIT_OT_keyframes_select_border(struct wmOperatorType *ot);
void GRAPHEDIT_OT_keyframes_columnselect(struct wmOperatorType *ot);
void GRAPHEDIT_OT_keyframes_clickselect(struct wmOperatorType *ot);
@@ -77,7 +79,7 @@ enum {
/* ***************************************** */
/* graph_edit.c */
-void GRAPHEDIT_OT_set_previewrange(struct wmOperatorType *ot);
+void GRAPHEDIT_OT_previewrange_set(struct wmOperatorType *ot);
void GRAPHEDIT_OT_view_all(struct wmOperatorType *ot);
void GRAPHEDIT_OT_keyframes_copy(struct wmOperatorType *ot);
@@ -119,11 +121,17 @@ enum {
GRAPHKEYS_MIRROR_MARKER,
} eGraphKeys_Mirror_Mode;
+/* ----------- */
+
+void GRAPHEDIT_OT_fmodifier_add(struct wmOperatorType *ot);
+
/* ***************************************** */
/* graph_buttons.c */
void GRAPHEDIT_OT_properties(struct wmOperatorType *ot);
void graph_region_buttons(const struct bContext *C, struct ARegion *ar);
+struct bAnimListElem *get_active_fcurve_channel(struct bAnimContext *ac);
+
/* ***************************************** */
/* graph_ops.c */
void graphedit_keymap(struct wmWindowManager *wm);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 80b8dcbf0ff..4ff566489ae 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -84,7 +84,7 @@ void GRAPHEDIT_OT_view_togglehandles (wmOperatorType *ot)
{
/* identification */
ot->name= "Show/Hide All Handles";
- ot->idname= "GRAPHEDIT_OT_view_toggle_handles";
+ ot->idname= "GRAPHEDIT_OT_handles_view_toggle";
/* callbacks */
ot->exec= view_toggle_handles_exec;
@@ -97,15 +97,15 @@ void graphedit_operatortypes(void)
{
/* view */
WM_operatortype_append(GRAPHEDIT_OT_view_togglehandles);
- WM_operatortype_append(GRAPHEDIT_OT_set_previewrange);
+ WM_operatortype_append(GRAPHEDIT_OT_previewrange_set);
WM_operatortype_append(GRAPHEDIT_OT_view_all);
WM_operatortype_append(GRAPHEDIT_OT_properties);
/* keyframes */
/* selection */
WM_operatortype_append(GRAPHEDIT_OT_keyframes_clickselect);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_deselectall);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_borderselect);
+ WM_operatortype_append(GRAPHEDIT_OT_keyframes_select_all_toggle);
+ WM_operatortype_append(GRAPHEDIT_OT_keyframes_select_border);
WM_operatortype_append(GRAPHEDIT_OT_keyframes_columnselect);
/* editing */
@@ -126,6 +126,10 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPHEDIT_OT_keyframes_paste);
//TODO: insertkey...
+
+ /* F-Curve Modifiers */
+ // XXX temporary?
+ WM_operatortype_append(GRAPHEDIT_OT_fmodifier_add);
}
/* ************************** registration - keymaps **********************************/
@@ -133,23 +137,23 @@ void graphedit_operatortypes(void)
static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
{
/* view */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_view_toggle_handles", HKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "GRAPHEDIT_OT_handles_view_toggle", HKEY, KM_PRESS, KM_CTRL, 0);
/* graph_select.c - selection tools */
/* click-select */
// TODO: column to alt, left-right to ctrl (for select-linked consistency)
WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "column_select", 1);
- RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend_select", 1);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "column", 1);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
RNA_enum_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "left_right", GRAPHKEYS_LRSEL_TEST);
/* deselect all */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_deselectall", AKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_deselectall", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
+ WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_select_all_toggle", AKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
/* borderselect */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_borderselect", BKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_borderselect", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1);
+ WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_select_border", BKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_select_border", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1);
/* column select */
// XXX KKEY would be nice to keep for 'keyframe' lines
@@ -192,9 +196,14 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_paste", VKEY, KM_PRESS, KM_CTRL, 0);
/* auto-set range */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_set_previewrange", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ WM_keymap_add_item(keymap, "GRAPHEDIT_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
WM_keymap_add_item(keymap, "GRAPHEDIT_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ /* F-Curve Modifiers */
+ // XXX these are temporary? operators...
+ WM_keymap_add_item(keymap, "GRAPHEDIT_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+
+
/* transform system */
transform_keymap_for_space(wm, keymap, SPACE_IPO);
}
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index e4cb2f64071..d6f738b5285 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -176,11 +176,11 @@ static int graphkeys_deselectall_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_deselectall (wmOperatorType *ot)
+void GRAPHEDIT_OT_keyframes_select_all_toggle (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select All";
- ot->idname= "GRAPHEDIT_OT_keyframes_deselectall";
+ ot->idname= "GRAPHEDIT_OT_keyframes_select_all_toggle";
/* api callbacks */
ot->exec= graphkeys_deselectall_exec;
@@ -307,11 +307,11 @@ static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_borderselect(wmOperatorType *ot)
+void GRAPHEDIT_OT_keyframes_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Border Select";
- ot->idname= "GRAPHEDIT_OT_keyframes_borderselect";
+ ot->idname= "GRAPHEDIT_OT_keyframes_select_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
@@ -613,6 +613,7 @@ static short findnearest_fcurve_vert (bAnimContext *ac, int mval[2], FCurve **fc
}
/* handles - only do them if they're visible */
+ // XXX also need to check for int-values only?
if ((sipo->flag & SIPO_NOHANDLES)==0) {
/* first handle only visible if previous segment had handles */
if ( (!prevbezt && (bezt1->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) )
@@ -853,7 +854,7 @@ static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *ev
/* select mode is either replace (deselect all, then add) or add/extend */
// XXX this is currently only available for normal select only
- if (RNA_boolean_get(op->ptr, "extend_select"))
+ if (RNA_boolean_get(op->ptr, "extend"))
selectmode= SELECT_INVERT;
else
selectmode= SELECT_REPLACE;
@@ -871,7 +872,7 @@ static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *ev
graphkeys_select_leftright(&ac, RNA_enum_get(op->ptr, "left_right"), selectmode);
}
- else if (RNA_boolean_get(op->ptr, "column_select")) {
+ else if (RNA_boolean_get(op->ptr, "column")) {
/* select all the keyframes that occur on the same frame as where the mouse clicked */
float x;
@@ -904,8 +905,8 @@ void GRAPHEDIT_OT_keyframes_clickselect (wmOperatorType *ot)
/* id-props */
// XXX should we make this into separate operators?
RNA_def_enum(ot->srna, "left_right", NULL /* XXX prop_graphkeys_clickselect_items */, 0, "Left Right", ""); // ALTKEY
- RNA_def_boolean(ot->srna, "extend_select", 0, "Extend Select", ""); // SHIFTKEY
- RNA_def_boolean(ot->srna, "column_select", 0, "Column Select", ""); // CTRLKEY
+ RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
+ RNA_def_boolean(ot->srna, "column", 0, "Column Select", ""); // CTRLKEY
}
/* ************************************************************************** */
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index a43f8ee3502..72e52f15a65 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -83,7 +83,7 @@ ARegion *graph_has_buttons_region(ScrArea *sa)
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype= RGN_TYPE_UI;
- arnew->alignment= RGN_ALIGN_TOP|RGN_SPLIT_PREV;
+ arnew->alignment= RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV;
arnew->flag = RGN_FLAG_HIDDEN;
@@ -227,15 +227,16 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar)
UI_view2d_view_ortho(C, v2d);
/* grid */
- unitx= (sipo->flag & SIPO_DRAWTIME)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
+ unitx= (sipo->flag & SIPO_DRAWTIME)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMESCALE;
grid= UI_view2d_grid_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy);
UI_view2d_grid_draw(C, v2d, grid, V2D_GRIDLINES_ALL);
- UI_view2d_grid_free(grid);
/* draw data */
- if (ANIM_animdata_get_context(C, &ac)) {
- graph_draw_curves(&ac, sipo, ar);
- }
+ if (ANIM_animdata_get_context(C, &ac))
+ graph_draw_curves(&ac, sipo, ar, grid);
+
+ /* only free grid after drawing data, as we need to use it to determine sampling rate */
+ UI_view2d_grid_free(grid);
/* current frame */
if (sipo->flag & SIPO_DRAWTIME) flag |= DRAWCFRA_UNIT_SECONDS;
@@ -568,9 +569,9 @@ void ED_spacetype_ipo(void)
/* regions: UI buttons */
art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
art->regionid = RGN_TYPE_UI;
- art->minsizey= 160;
- art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
- art->listener= NULL; // graph_region_listener;
+ art->minsizey= 200;
+ art->keymapflag= ED_KEYMAP_UI;
+ art->listener= graph_region_listener;
art->init= graph_buttons_area_init;
art->draw= graph_buttons_area_draw;
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index 1b7a96459ff..ab042fce41f 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -144,7 +144,7 @@ static void draw_render_info(SpaceImage *sima, ARegion *ar)
/* clear header rect */
UI_GetThemeColor3fv(TH_BACK, colf);
glColor3f(colf[0]+0.1f, colf[1]+0.1f, colf[2]+0.1f);
- glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ glRecti(rect.xmin, rect.ymin, rect.xmax, rect.ymax+1);
UI_ThemeColor(TH_TEXT_HI);
glRasterPos2i(12, rect.ymin + 5);
diff --git a/source/blender/editors/space_image/image_header.c b/source/blender/editors/space_image/image_header.c
index 2b6078b71a8..80ace5500b8 100644
--- a/source/blender/editors/space_image/image_header.c
+++ b/source/blender/editors/space_image/image_header.c
@@ -164,12 +164,12 @@ static void image_viewmenu(bContext *C, uiMenuItem *head, void *arg_unused)
static void image_selectmenu(bContext *C, uiMenuItem *head, void *arg_unused)
{
- uiMenuItemO(head, 0, "UV_OT_border_select");
- uiMenuItemBooleanO(head, "Border Select Pinned", 0, "UV_OT_border_select", "pinned", 1); // Border Select Pinned|Shift B
+ uiMenuItemO(head, 0, "UV_OT_select_border");
+ uiMenuItemBooleanO(head, "Border Select Pinned", 0, "UV_OT_select_border", "pinned", 1); // Border Select Pinned|Shift B
uiMenuSeparator(head);
- uiMenuItemO(head, 0, "UV_OT_de_select_all");
+ uiMenuItemO(head, 0, "UV_OT_select_all_toggle");
uiMenuItemO(head, 0, "UV_OT_select_invert");
uiMenuItemO(head, 0, "UV_OT_unlink_selection");
@@ -381,7 +381,7 @@ static void image_uvsmenu(bContext *C, uiMenuItem *head, void *arg_unused)
static void image_menu_uvlayers(Object *obedit, char *menustr, int *active)
{
Mesh *me= (Mesh*)obedit->data;
- EditMesh *em= me->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(me);
CustomDataLayer *layer;
int i, count = 0;
@@ -397,6 +397,8 @@ static void image_menu_uvlayers(Object *obedit, char *menustr, int *active)
}
*active= CustomData_get_active_layer(&em->fdata, CD_MTFACE);
+
+ EM_EndEditMesh(me, em);
}
static void do_image_buttons(bContext *C, void *arg, int event)
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index 20f12fecaf5..c592e2cb004 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -75,7 +75,7 @@ void IMAGE_OT_pack(struct wmOperatorType *ot);
void IMAGE_OT_unpack(struct wmOperatorType *ot);
void IMAGE_OT_sample(struct wmOperatorType *ot);
-void IMAGE_OT_set_curves_point(struct wmOperatorType *ot);
+void IMAGE_OT_curves_point_set(struct wmOperatorType *ot);
void IMAGE_OT_record_composite(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 8038e6a00ff..934d58926e2 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1403,7 +1403,7 @@ void IMAGE_OT_sample(wmOperatorType *ot)
/******************** set curve point operator ********************/
-void IMAGE_OT_set_curves_point(wmOperatorType *ot)
+void IMAGE_OT_curves_point_set(wmOperatorType *ot)
{
static EnumPropertyItem point_items[]= {
{0, "BLACK_POINT", "Black Point", ""},
@@ -1412,7 +1412,7 @@ void IMAGE_OT_set_curves_point(wmOperatorType *ot)
/* identifiers */
ot->name= "Set Curves Point";
- ot->idname= "IMAGE_OT_set_curves_point";
+ ot->idname= "IMAGE_OT_curves_point_set";
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
diff --git a/source/blender/editors/space_image/image_panels.c b/source/blender/editors/space_image/image_panels.c
index c0fe8afd036..b6da7415f1f 100644
--- a/source/blender/editors/space_image/image_panels.c
+++ b/source/blender/editors/space_image/image_panels.c
@@ -249,7 +249,7 @@ static void image_editvertex_buts(const bContext *C, uiBlock *block)
image_transform_but_attr(sima, &imx, &imy, &step, &digits);
- em= ((Mesh *)obedit->data)->edit_mesh;
+ em= EM_GetEditMesh((Mesh *)obedit->data);
for (efa= em->faces.first; efa; efa= efa->next) {
tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
if (simaFaceDraw_Check(efa, tf)) {
@@ -338,6 +338,8 @@ static void image_editvertex_buts(const bContext *C, uiBlock *block)
WM_event_add_notifier(C, NC_IMAGE, sima->image);
}
+
+ EM_EndEditMesh(obedit->data, em);
}
@@ -441,7 +443,7 @@ static void image_panel_view_properties(const bContext *C, ARegion *ar)
if (obedit && obedit->type==OB_MESH) {
Mesh *me= obedit->data;
- EditMesh *em= me->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(me);
if(EM_texFaceCheck(em)) {
uiDefBut(block, LABEL, B_NOP, "Draw Type:", 10, 80,120,19, 0, 0, 0, 0, 0, "");
@@ -459,6 +461,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) {
@@ -468,7 +471,8 @@ static void image_panel_view_properties(const bContext *C, ARegion *ar)
uiBlockEndAlign(block);
}
}
-
+
+ EM_EndEditMesh(me, em);
}
image_editcursor_buts(C, &ar->v2d, block);
}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 419eb913edd..db8bdbdacc8 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -192,7 +192,7 @@ void image_operatortypes(void)
WM_operatortype_append(IMAGE_OT_unpack);
WM_operatortype_append(IMAGE_OT_sample);
- WM_operatortype_append(IMAGE_OT_set_curves_point);
+ WM_operatortype_append(IMAGE_OT_curves_point_set);
WM_operatortype_append(IMAGE_OT_record_composite);
@@ -237,8 +237,8 @@ void image_keymap(struct wmWindowManager *wm)
RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH);
WM_keymap_add_item(keymap, "IMAGE_OT_sample", ACTIONMOUSE, KM_PRESS, 0, 0);
- RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_set_curves_point", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "point", 0);
- RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_set_curves_point", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "point", 1);
+ RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "point", 0);
+ RNA_enum_set(WM_keymap_add_item(keymap, "IMAGE_OT_curves_point_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "point", 1);
WM_keymap_add_item(keymap, "IMAGE_OT_toolbox", SPACEKEY, KM_PRESS, 0, 0);
}
@@ -255,7 +255,7 @@ static void image_refresh(const bContext *C, ScrArea *sa)
if(ima && (ima->source==IMA_SRC_VIEWER || sima->pin));
else if(obedit && obedit->type == OB_MESH) {
Mesh *me= (Mesh*)obedit->data;
- EditMesh *em= me->edit_mesh;
+ EditMesh *em= EM_GetEditMesh(me);
MTFace *tf;
if(em && EM_texFaceCheck(em)) {
@@ -278,6 +278,8 @@ static void image_refresh(const bContext *C, ScrArea *sa)
}
}
}
+
+ EM_EndEditMesh(obedit->data, em);
}
}
@@ -304,16 +306,12 @@ static void image_listener(ScrArea *sa, wmNotifier *wmn)
}
}
-static int image_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
+static int image_context(const bContext *C, const char *member, bContextDataResult *result)
{
SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
- if(member == CTX_DATA_EDIT_IMAGE) {
- CTX_data_pointer_set(result, ED_space_image(sima));
- return 1;
- }
- else if(member == CTX_DATA_EDIT_IMAGE_BUFFER) {
- CTX_data_pointer_set(result, ED_space_image_buffer(sima));
+ if(CTX_data_equals(member, "edit_image")) {
+ CTX_data_id_pointer_set(result, (ID*)ED_space_image(sima));
return 1;
}
@@ -759,8 +757,15 @@ int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
if(ED_space_image_show_paint(sima))
return 0;
- if(obedit && obedit->type == OB_MESH)
- return EM_texFaceCheck(((Mesh*)obedit->data)->edit_mesh);
+ if(obedit && obedit->type == OB_MESH) {
+ EditMesh *em = EM_GetEditMesh(obedit->data);
+ int ret;
+
+ ret = EM_texFaceCheck(em);
+
+ EM_EndEditMesh(obedit->data, em);
+ return ret;
+ }
return 0;
}
@@ -771,8 +776,15 @@ int ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
return 0;
if(ED_space_image_show_paint(sima))
- if(obedit && obedit->type == OB_MESH)
- return EM_texFaceCheck(((Mesh*)obedit->data)->edit_mesh);
+ if(obedit && obedit->type == OB_MESH) {
+ EditMesh *em = EM_GetEditMesh(obedit->data);
+ int ret;
+
+ ret = EM_texFaceCheck(em);
+
+ EM_EndEditMesh(obedit->data, em);
+ return ret;
+ }
return 0;
}
diff --git a/source/blender/editors/space_info/Makefile b/source/blender/editors/space_info/Makefile
index 13f7a0d169f..bc04ddc7824 100644
--- a/source/blender/editors/space_info/Makefile
+++ b/source/blender/editors/space_info/Makefile
@@ -44,6 +44,7 @@ CPPFLAGS += -I../../blenloader
CPPFLAGS += -I../../blenkernel
CPPFLAGS += -I../../blenlib
CPPFLAGS += -I../../makesdna
+CPPFLAGS += -I../../makesrna
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../python
CPPFLAGS += -I../../blenfont
diff --git a/source/blender/editors/space_info/SConscript b/source/blender/editors/space_info/SConscript
index faedcbfa587..05afcae162e 100644
--- a/source/blender/editors/space_info/SConscript
+++ b/source/blender/editors/space_info/SConscript
@@ -3,7 +3,15 @@ Import ('env')
sources = env.Glob('*.c')
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf ../../blenfont'
+incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../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_info/info_header.c b/source/blender/editors/space_info/info_header.c
index 8b72e20ec51..69f33df3005 100644
--- a/source/blender/editors/space_info/info_header.c
+++ b/source/blender/editors/space_info/info_header.c
@@ -404,7 +404,7 @@ void info_header_buttons(const bContext *C, ARegion *ar)
uiBlockSetEmboss(block, UI_EMBOSSP);
xmax= GetButStringLength("File");
- uiDefMenuBut(block, info_filemenu, NULL, "File", xco, yco, xmax-3, 24, "");
+ uiDefMenuBut(block, info_filemenu, NULL, "File", xco, yco, xmax-3, 22, "");
xco+= xmax;
xmax= GetButStringLength("Add");
diff --git a/source/blender/editors/space_nla/Makefile b/source/blender/editors/space_nla/Makefile
index 85405a2a3f5..43f010e6adc 100644
--- a/source/blender/editors/space_nla/Makefile
+++ b/source/blender/editors/space_nla/Makefile
@@ -44,6 +44,7 @@ CPPFLAGS += -I../../blenloader
CPPFLAGS += -I../../blenkernel
CPPFLAGS += -I../../blenlib
CPPFLAGS += -I../../makesdna
+CPPFLAGS += -I../../makesrna
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../python
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
diff --git a/source/blender/editors/space_nla/SConscript b/source/blender/editors/space_nla/SConscript
index c6a4f34292f..790e3ad822c 100644
--- a/source/blender/editors/space_nla/SConscript
+++ b/source/blender/editors/space_nla/SConscript
@@ -3,7 +3,7 @@ Import ('env')
sources = env.Glob('*.c')
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
env.BlenderLib ( 'bf_editors_space_nla', sources, Split(incs), [], libtype=['core'], priority=[85] )
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 68e9d38e192..d77d2aa09cb 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -2518,12 +2518,12 @@ static int node_delete_selection_exec(bContext *C, wmOperator *op)
/* operators */
-void NODE_OT_delete_selection(wmOperatorType *ot)
+void NODE_OT_delete(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Delete";
- ot->idname= "NODE_OT_delete_selection";
+ ot->idname= "NODE_OT_delete";
/* api callbacks */
ot->exec= node_delete_selection_exec;
diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c
index d2e7df55e54..14545b87cd4 100644
--- a/source/blender/editors/space_node/node_header.c
+++ b/source/blender/editors/space_node/node_header.c
@@ -75,7 +75,7 @@ static void do_node_selectmenu(bContext *C, void *arg, int event)
switch(event) {
case 1: /* border select */
- WM_operator_name_call(C, "NODE_OT_border_select", WM_OP_INVOKE_REGION_WIN, NULL);
+ WM_operator_name_call(C, "NODE_OT_select_border", WM_OP_INVOKE_REGION_WIN, NULL);
break;
case 2: /* select/deselect all */
// XXX node_deselectall(snode, 1);
@@ -582,13 +582,13 @@ static void do_node_viewmenu(bContext *C, void *arg, int event)
switch(event) {
case 1: /* Zoom in */
- WM_operator_name_call(C, "View2D_OT_view_zoomin", WM_OP_EXEC_REGION_WIN, NULL);
+ WM_operator_name_call(C, "VIEW2D_OT_zoom_in", WM_OP_EXEC_REGION_WIN, NULL);
break;
case 2: /* View all */
- WM_operator_name_call(C, "View2D_OT_view_zoomout", WM_OP_EXEC_REGION_WIN, NULL);
+ WM_operator_name_call(C, "VIEW2D_OT_zoom_out", WM_OP_EXEC_REGION_WIN, NULL);
break;
case 3: /* View all */
- WM_operator_name_call(C, "NODE_OT_fit_all", WM_OP_EXEC_REGION_WIN, NULL);
+ WM_operator_name_call(C, "NODE_OT_view_all", WM_OP_EXEC_REGION_WIN, NULL);
break;
case 4: /* Grease Pencil */
// XXX add_blockhandler(sa, NODES_HANDLER_GREASEPENCIL, UI_PNL_UNSTOW);
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index de3999ae5cb..4796db98e95 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -55,10 +55,10 @@ void node_keymap(wmWindowManager *wm);
/* node_select.c */
void NODE_OT_select(struct wmOperatorType *ot);
-void NODE_OT_extend_select(struct wmOperatorType *ot);
+void NODE_OT_select_extend(struct wmOperatorType *ot);
void NODE_OT_visibility_toggle(struct wmOperatorType *ot);
-void NODE_OT_fit_all(struct wmOperatorType *ot);
-void NODE_OT_border_select(struct wmOperatorType *ot);
+void NODE_OT_view_all(struct wmOperatorType *ot);
+void NODE_OT_select_border(struct wmOperatorType *ot);
/* drawnode.c */
void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link);
@@ -83,7 +83,7 @@ bNode *snode_get_editgroup(SpaceNode *snode);
void snode_autoconnect(SpaceNode *snode, bNode *node_to, int flag);
void NODE_OT_link(struct wmOperatorType *ot);
-void NODE_OT_delete_selection(struct wmOperatorType *ot);
+void NODE_OT_delete(struct wmOperatorType *ot);
void NODE_OT_size_widget(struct wmOperatorType *ot);
void NODE_OT_links_cut(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index dc6ae03cef9..cef867faa1f 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -51,11 +51,11 @@
void node_operatortypes(void)
{
WM_operatortype_append(NODE_OT_select);
- WM_operatortype_append(NODE_OT_extend_select);
+ WM_operatortype_append(NODE_OT_select_extend);
WM_operatortype_append(NODE_OT_visibility_toggle);
- WM_operatortype_append(NODE_OT_fit_all);
- WM_operatortype_append(NODE_OT_border_select);
- WM_operatortype_append(NODE_OT_delete_selection);
+ WM_operatortype_append(NODE_OT_view_all);
+ WM_operatortype_append(NODE_OT_select_border);
+ WM_operatortype_append(NODE_OT_delete);
WM_operatortype_append(NODE_OT_link);
WM_operatortype_append(NODE_OT_size_widget);
WM_operatortype_append(NODE_OT_links_cut);
@@ -68,17 +68,17 @@ void node_keymap(struct wmWindowManager *wm)
/* mouse select in nodes used to be both keys, it's UI elements... */
RNA_enum_set(WM_keymap_add_item(keymap, "NODE_OT_select", ACTIONMOUSE, KM_PRESS, 0, 0)->ptr, "select_type", NODE_SELECT_MOUSE);
RNA_enum_set(WM_keymap_add_item(keymap, "NODE_OT_select", SELECTMOUSE, KM_PRESS, 0, 0)->ptr, "select_type", NODE_SELECT_MOUSE);
- RNA_enum_set(WM_keymap_add_item(keymap, "NODE_OT_extend_select", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "select_type", NODE_SELECT_MOUSE);
- RNA_enum_set(WM_keymap_add_item(keymap, "NODE_OT_extend_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "select_type", NODE_SELECT_MOUSE);
+ RNA_enum_set(WM_keymap_add_item(keymap, "NODE_OT_select_extend", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "select_type", NODE_SELECT_MOUSE);
+ RNA_enum_set(WM_keymap_add_item(keymap, "NODE_OT_select_extend", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "select_type", NODE_SELECT_MOUSE);
WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_size_widget", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_visibility_toggle", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "NODE_OT_fit_all", HOMEKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "NODE_OT_border_select", BKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "NODE_OT_delete_selection", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_select_border", BKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_delete", XKEY, KM_PRESS, 0, 0);
transform_keymap_for_space(wm, keymap, SPACE_NODE);
}
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index 0006d227d1a..3c37793e8d6 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -180,11 +180,12 @@ static EnumPropertyItem prop_select_items[] = {
{NODE_SELECT_MOUSE, "NORMAL", "Normal Select", "Select using the mouse"},
{0, NULL, NULL, NULL}};
-void NODE_OT_extend_select(wmOperatorType *ot)
+void NODE_OT_select_extend(wmOperatorType *ot)
{
+ // XXX - Todo - This should just be a toggle option for NODE_OT_select not its own op
/* identifiers */
ot->name= "Activate/Select (Shift)";
- ot->idname= "NODE_OT_extend_select";
+ ot->idname= "NODE_OT_select_extend";
/* api callbacks */
ot->invoke= node_extend_select_invoke;
@@ -265,11 +266,11 @@ static int node_borderselect_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void NODE_OT_border_select(wmOperatorType *ot)
+void NODE_OT_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Border Select";
- ot->idname= "NODE_OT_border_select";
+ ot->idname= "NODE_OT_select_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
diff --git a/source/blender/editors/space_node/node_state.c b/source/blender/editors/space_node/node_state.c
index ee3bfbf0fbf..f05a24ef05a 100644
--- a/source/blender/editors/space_node/node_state.c
+++ b/source/blender/editors/space_node/node_state.c
@@ -193,11 +193,11 @@ static int node_fit_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void NODE_OT_fit_all(wmOperatorType *ot)
+void NODE_OT_view_all(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Fit All";
- ot->idname= "NODE_OT_fit_all";
+ ot->idname= "NODE_OT_view_all";
/* api callbacks */
ot->exec= node_fit_all_exec;
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 1d2aa148e18..493ef6954b5 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -60,6 +60,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "RNA_access.h"
+
#include "node_intern.h" // own include
/* ******************** default callbacks for node space ***************** */
@@ -277,16 +279,16 @@ static void node_region_listener(ARegion *ar, wmNotifier *wmn)
}
}
-static int node_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
+static int node_context(const bContext *C, const char *member, bContextDataResult *result)
{
SpaceNode *snode= (SpaceNode*)CTX_wm_space_data(C);
- if(member == CTX_DATA_SELECTED_NODES) {
+ if(CTX_data_equals(member, "selected_nodes")) {
bNode *node;
for(next_node(snode->edittree); (node=next_node(NULL));) {
if(node->flag & SELECT) {
- CTX_data_list_add(result, node);
+ CTX_data_list_add(result, &snode->edittree->id, &RNA_Node, node);
}
}
return 1;
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index 220fd7b8dc8..54652587c53 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -50,7 +50,7 @@
#include "DNA_modifier_types.h"
#include "DNA_nla_types.h"
#include "DNA_object_types.h"
-#include "DNA_oops_types.h"
+#include "DNA_outliner_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -3063,9 +3063,9 @@ enum {
static int ed_operator_outliner_datablocks_active(bContext *C)
{
ScrArea *sa= CTX_wm_area(C);
- if ((sa) && (sa->spacetype==SPACE_OOPS)) {
+ if ((sa) && (sa->spacetype==SPACE_OUTLINER)) {
SpaceOops *so= (SpaceOops *)CTX_wm_space_data(C);
- return ((so->type == SO_OUTLINER) && (so->outlinevis == SO_DATABLOCKS));
+ return (so->outlinevis == SO_DATABLOCKS);
}
return 0;
}
@@ -4204,13 +4204,13 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
prop= te->directdata;
if(!(RNA_property_type(ptr, prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0))
- uiDefAutoButR(block, ptr, prop, -1, "", sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
+ uiDefAutoButR(block, ptr, prop, -1, "", 0, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
}
else if(tselem->type == TSE_RNA_ARRAY_ELEM) {
ptr= &te->rnaptr;
prop= te->directdata;
- uiDefAutoButR(block, ptr, prop, te->index, "", sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
+ uiDefAutoButR(block, ptr, prop, te->index, "", 0, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
}
}
diff --git a/source/blender/editors/space_outliner/outliner_header.c b/source/blender/editors/space_outliner/outliner_header.c
index b42f6ec16ff..ecff2d8a417 100644
--- a/source/blender/editors/space_outliner/outliner_header.c
+++ b/source/blender/editors/space_outliner/outliner_header.c
@@ -88,9 +88,6 @@ static void do_viewmenu(bContext *C, void *arg, int event)
/* using event B_FULL */
break;
break;
- case 14: /* show outliner viewer */
- soops->type= SO_OUTLINER;
- break;
case 6:
//outliner_toggle_visible(curarea);
break;
@@ -124,23 +121,21 @@ static uiBlock *outliner_viewmenu(bContext *C, ARegion *ar, void *arg_unused)
block= uiBeginBlock(C, ar, "outliner_viewmenu", UI_EMBOSSP, UI_HELV);
uiBlockSetButmFunc(block, do_viewmenu, NULL);
- if(soops->type==SO_OUTLINER) {
- if (soops->flag & SO_HIDE_RESTRICTCOLS)
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Show Restriction Columns", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
- else
- uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Show Restriction Columns", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Expand One Level|NumPad +", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Collapse One Level|NumPad -", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
-
- uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show/Hide All", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Hierarchy|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Active|NumPad .", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
- }
+ if (soops->flag & SO_HIDE_RESTRICTCOLS)
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Show Restriction Columns", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
+ else
+ uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Show Restriction Columns", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Expand One Level|NumPad +", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Collapse One Level|NumPad -", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
+
+ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show/Hide All", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Hierarchy|Home", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Show Active|NumPad .", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
// uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
// if(!curarea->full) uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Maximize Window|Ctrl UpArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
@@ -239,73 +234,71 @@ void outliner_header_buttons(const bContext *C, ARegion *ar)
uiBlockSetEmboss(block, UI_EMBOSS);
}
- //if (outliner->type==SO_OUTLINER) {
- /* data selector*/
- if(G.main->library.first)
- uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12", xco, yco, 120, 20, &soutliner->outlinevis, 0, 0, 0, 0, "");
- else
- uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12", xco, yco, 120, 20, &soutliner->outlinevis, 0, 0, 0, 0, "");
- xco += 120;
+ /* data selector*/
+ if(G.main->library.first)
+ uiDefButS(block, MENU, B_REDR, "Outliner Display%t|Libraries %x7|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12", xco, yco, 120, 20, &soutliner->outlinevis, 0, 0, 0, 0, "");
+ else
+ uiDefButS(block, MENU, B_REDR, "Outliner Display%t|All Scenes %x0|Current Scene %x1|Visible Layers %x2|Groups %x6|Same Types %x5|Selected %x3|Active %x4|Sequence %x10|Datablocks %x11|User Preferences %x12", xco, yco, 120, 20, &soutliner->outlinevis, 0, 0, 0, 0, "");
+ xco += 120;
+
+ /* KeyingSet editing buttons */
+ if ((soutliner->flag & SO_HIDE_KEYINGSETINFO)==0 && (soutliner->outlinevis==SO_DATABLOCKS)) {
+ KeyingSet *ks= NULL;
+ char *menustr= NULL;
- /* KeyingSet editing buttons */
- if ((soutliner->flag & SO_HIDE_KEYINGSETINFO)==0 && (soutliner->outlinevis==SO_DATABLOCKS)) {
- KeyingSet *ks= NULL;
- char *menustr= NULL;
-
- xco+= (int)(XIC*1.5);
+ xco+= (int)(XIC*1.5);
+
+ if (scene->active_keyingset)
+ ks= (KeyingSet *)BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
+
+ uiBlockBeginAlign(block);
+ /* currently 'active' KeyingSet */
+ menustr= ANIM_build_keyingsets_menu(&scene->keyingsets, 1);
+ uiDefButI(block, MENU, B_KEYINGSET_CHANGE, menustr, xco,yco, 18,20, &scene->active_keyingset, 0, 0, 0, 0, "Browse Keying Sets");
+ MEM_freeN(menustr);
+ xco += 18;
- if (scene->active_keyingset)
- ks= (KeyingSet *)BLI_findlink(&scene->keyingsets, scene->active_keyingset-1);
+ /* currently 'active' KeyingSet - change name */
+ if (ks) {
+ /* active KeyingSet */
+ uiDefBut(block, TEX, B_KEYINGSET_CHANGE,"", xco,yco,120,20, ks->name, 0, 63, 0, 0, "Name of Active Keying Set");
+ xco += 120;
+ uiDefIconBut(block, BUT, B_KEYINGSET_REMOVE, VICON_X, xco, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Keying Set");
+ xco += 20;
+ }
+ else {
+ /* no active KeyingSet... so placeholder instead */
+ uiDefBut(block, LABEL, 0,"<No Keying Set Active>", xco,yco,140,20, NULL, 0, 63, 0, 0, "Name of Active Keying Set");
+ xco += 140;
+ }
+ uiBlockEndAlign(block);
+
+ /* current 'active' KeyingSet */
+ if (ks) {
+ xco += 5;
+ /* operator buttons to add/remove selected items from set */
uiBlockBeginAlign(block);
- /* currently 'active' KeyingSet */
- menustr= ANIM_build_keyingsets_menu(&scene->keyingsets, 1);
- uiDefButI(block, MENU, B_KEYINGSET_CHANGE, menustr, xco,yco, 18,20, &scene->active_keyingset, 0, 0, 0, 0, "Browse Keying Sets");
- MEM_freeN(menustr);
- xco += 18;
-
- /* currently 'active' KeyingSet - change name */
- if (ks) {
- /* active KeyingSet */
- uiDefBut(block, TEX, B_KEYINGSET_CHANGE,"", xco,yco,120,20, ks->name, 0, 63, 0, 0, "Name of Active Keying Set");
- xco += 120;
- uiDefIconBut(block, BUT, B_KEYINGSET_REMOVE, VICON_X, xco, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Remove this Keying Set");
- xco += 20;
- }
- else {
- /* no active KeyingSet... so placeholder instead */
- uiDefBut(block, LABEL, 0,"<No Keying Set Active>", xco,yco,140,20, NULL, 0, 63, 0, 0, "Name of Active Keying Set");
- xco += 140;
- }
+ // XXX the icons here are temporary
+ uiDefIconButO(block, BUT, "OUTLINER_OT_keyingset_remove_selected", WM_OP_INVOKE_REGION_WIN, ICON_ZOOMOUT, xco,yco,XIC,YIC, "Remove selected properties from active Keying Set (Alt-K)");
+ xco += XIC;
+ uiDefIconButO(block, BUT, "OUTLINER_OT_keyingset_add_selected", WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, xco,yco,XIC,YIC, "Add selected properties to active Keying Set (K)");
+ xco += XIC;
uiBlockEndAlign(block);
- /* current 'active' KeyingSet */
- if (ks) {
- xco += 5;
-
- /* operator buttons to add/remove selected items from set */
- uiBlockBeginAlign(block);
- // XXX the icons here are temporary
- uiDefIconButO(block, BUT, "OUTLINER_OT_keyingset_remove_selected", WM_OP_INVOKE_REGION_WIN, ICON_ZOOMOUT, xco,yco,XIC,YIC, "Remove selected properties from active Keying Set (Alt-K)");
- xco += XIC;
- uiDefIconButO(block, BUT, "OUTLINER_OT_keyingset_add_selected", WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, xco,yco,XIC,YIC, "Add selected properties to active Keying Set (K)");
- xco += XIC;
- uiBlockEndAlign(block);
-
- xco += 10;
-
- /* operator buttons to insert/delete keyframes for the active set */
- uiBlockBeginAlign(block);
- uiDefIconButO(block, BUT, "ANIM_OT_delete_keyframe", WM_OP_INVOKE_REGION_WIN, ICON_KEY_DEHLT, xco,yco,XIC,YIC, "Delete Keyframes for the Active Keying Set (Alt-I)");
- xco+= XIC;
- uiDefIconButO(block, BUT, "ANIM_OT_insert_keyframe", WM_OP_INVOKE_REGION_WIN, ICON_KEY_HLT, xco,yco,XIC,YIC, "Insert Keyframes for the Active Keying Set (I)");
- xco+= XIC;
- uiBlockEndAlign(block);
- }
+ xco += 10;
- xco += XIC*2;
+ /* operator buttons to insert/delete keyframes for the active set */
+ uiBlockBeginAlign(block);
+ uiDefIconButO(block, BUT, "ANIM_OT_delete_keyframe", WM_OP_INVOKE_REGION_WIN, ICON_KEY_DEHLT, xco,yco,XIC,YIC, "Delete Keyframes for the Active Keying Set (Alt-I)");
+ xco+= XIC;
+ uiDefIconButO(block, BUT, "ANIM_OT_insert_keyframe", WM_OP_INVOKE_REGION_WIN, ICON_KEY_HLT, xco,yco,XIC,YIC, "Insert Keyframes for the Active Keying Set (I)");
+ xco+= XIC;
+ uiBlockEndAlign(block);
}
- //}
+
+ xco += XIC*2;
+ }
/* always as last */
UI_view2d_totRect_set(&ar->v2d, xco+XIC+100, (int)(ar->v2d.tot.ymax-ar->v2d.tot.ymin));
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 8ed4c9ed986..920ccb62a7a 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -51,7 +51,7 @@ void outliner_operatortypes(void)
void outliner_keymap(wmWindowManager *wm)
{
- ListBase *keymap= WM_keymap_listbase(wm, "Outliner", SPACE_OOPS, 0);
+ ListBase *keymap= WM_keymap_listbase(wm, "Outliner", SPACE_OUTLINER, 0);
WM_keymap_verify_item(keymap, "OUTLINER_OT_activate_click", LEFTMOUSE, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index b8187309c0d..4add1e88986 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -31,7 +31,7 @@
#include "DNA_color_types.h"
#include "DNA_object_types.h"
-#include "DNA_oops_types.h"
+#include "DNA_outliner_types.h"
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -78,7 +78,7 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
/* own keymap */
- keymap= WM_keymap_listbase(wm, "Outliner", SPACE_OOPS, 0); /* XXX weak? */
+ keymap= WM_keymap_listbase(wm, "Outliner", SPACE_OUTLINER, 0); /* XXX weak? */
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
@@ -190,7 +190,7 @@ static SpaceLink *outliner_new(const bContext *C)
SpaceOops *soutliner;
soutliner= MEM_callocN(sizeof(SpaceOops), "initoutliner");
- soutliner->spacetype= SPACE_OOPS;
+ soutliner->spacetype= SPACE_OUTLINER;
/* header */
ar= MEM_callocN(sizeof(ARegion), "header for outliner");
@@ -214,27 +214,10 @@ static SpaceLink *outliner_new(const bContext *C)
return (SpaceLink*)soutliner;
}
-static void free_oops(Oops *oops) /* also oops itself */
-{
- BLI_freelistN(&oops->link);
- MEM_freeN(oops);
-}
-
/* not spacelink itself */
static void outliner_free(SpaceLink *sl)
{
SpaceOops *soutliner= (SpaceOops*)sl;
- Oops *oops;
-
- if(soutliner->rnapath) {
- MEM_freeN(soutliner->rnapath);
- soutliner->rnapath= NULL;
- }
-
- while( (oops= soutliner->oops.first) ) {
- BLI_remlink(&soutliner->oops, oops);
- free_oops(oops);
- }
outliner_free_tree(&soutliner->tree);
if(soutliner->treestore) {
@@ -255,10 +238,6 @@ static SpaceLink *outliner_duplicate(SpaceLink *sl)
SpaceOops *soutliner= (SpaceOops *)sl;
SpaceOops *soutlinern= MEM_dupallocN(soutliner);
- if(soutlinern->rnapath)
- soutlinern->rnapath= MEM_dupallocN(soutlinern->rnapath);
-
- soutlinern->oops.first= soutlinern->oops.last= NULL;
soutlinern->tree.first= soutlinern->tree.last= NULL;
soutlinern->treestore= NULL;
@@ -271,7 +250,7 @@ void ED_spacetype_outliner(void)
SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype time");
ARegionType *art;
- st->spaceid= SPACE_OOPS;
+ st->spaceid= SPACE_OUTLINER;
strncpy(st->name, "Outliner", BKE_ST_MAXNAME);
st->new= outliner_new;
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index 054033fd987..c7f280f439e 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -157,10 +157,12 @@ static void script_main_area_draw(const bContext *C, ARegion *ar)
/* data... */
// BPY_run_python_script(C, "/root/blender-svn/blender25/test.py", NULL);
+#ifndef DISABLE_PYTHON
if (sscript->script) {
//BPY_run_python_script_space(scpt->script.filename, NULL);
BPY_run_script_space_draw(C, sscript);
}
+#endif
/* reset view matrix */
UI_view2d_view_restore(C);
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 0068c03f6f9..e71abec8e4b 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -264,7 +264,7 @@ static void drawseqwave(Scene *scene, View2D *v2d, Sequence *seq, float x1, floa
uint8_t *stream;
// XXX audio_makestream(seq->sound);
-// if(seq->sound==NULL || seq->sound->stream==NULL) return;
+ if(seq->sound==NULL || seq->sound->stream==NULL) return;
if (seq->flag & SEQ_MUTE) glColor3ub(0x70, 0x80, 0x80); else glColor3ub(0x70, 0xc0, 0xc0);
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index a9a3591c54f..1ae9d19a10e 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)) {
@@ -1805,12 +1805,12 @@ static int sequencer_add_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *
return OPERATOR_FINISHED;
}
-void SEQUENCER_OT_add_duplicate(wmOperatorType *ot)
+void SEQUENCER_OT_duplicate_add(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add Duplicate";
- ot->idname= "SEQUENCER_OT_add_duplicate";
+ ot->idname= "SEQUENCER_OT_duplicate_add";
/* api callbacks */
ot->invoke= sequencer_add_duplicate_invoke;
diff --git a/source/blender/editors/space_sequencer/sequencer_header.c b/source/blender/editors/space_sequencer/sequencer_header.c
index 71d7ff728d3..a701a9dd55b 100644
--- a/source/blender/editors/space_sequencer/sequencer_header.c
+++ b/source/blender/editors/space_sequencer/sequencer_header.c
@@ -158,7 +158,7 @@ static void seq_selectmenu(bContext *C, uiMenuItem *head, void *arg_unused)
uiMenuItemO(head, 0, "SEQUENCER_OT_select_linked");
uiMenuSeparator(head);
uiMenuItemO(head, 0, "SEQUENCER_OT_select_linked");
- uiMenuItemO(head, 0, "SEQUENCER_OT_deselect_all");
+ uiMenuItemO(head, 0, "SEQUENCER_OT_select_all_toggle");
uiMenuItemO(head, 0, "SEQUENCER_OT_select_invert");
}
@@ -275,7 +275,7 @@ static void seq_editmenu(bContext *C, uiMenuItem *head, void *arg_unused)
uiMenuItemO(head, 0, "SEQUENCER_OT_separate_images");
uiMenuSeparator(head);
- uiMenuItemO(head, 0, "SEQUENCER_OT_add_duplicate");
+ uiMenuItemO(head, 0, "SEQUENCER_OT_duplicate_add");
uiMenuItemO(head, 0, "SEQUENCER_OT_delete");
if (ed && ed->act_seq) {
@@ -439,7 +439,7 @@ void sequencer_header_buttons(const bContext *C, ARegion *ar)
0, 0, 0, 0,
"Zooms view in and out (Ctrl MiddleMouse)");
xco += XIC;
- uiDefIconButO(block, BUT, "View2D_OT_view_borderzoom", WM_OP_INVOKE_REGION_WIN, ICON_BORDERMOVE, xco,yco,XIC,YIC, "Zooms view to fit area");
+ uiDefIconButO(block, BUT, "VIEW2D_OT_zoom_border", WM_OP_INVOKE_REGION_WIN, ICON_BORDERMOVE, xco,yco,XIC,YIC, "Zooms view to fit area");
uiBlockEndAlign(block);
xco += 8 + XIC;
diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h
index 18c08d94094..8a56d15e1da 100644
--- a/source/blender/editors/space_sequencer/sequencer_intern.h
+++ b/source/blender/editors/space_sequencer/sequencer_intern.h
@@ -78,7 +78,7 @@ void SEQUENCER_OT_lock(struct wmOperatorType *ot);
void SEQUENCER_OT_unlock(struct wmOperatorType *ot);
void SEQUENCER_OT_reload(struct wmOperatorType *ot);
void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot);
-void SEQUENCER_OT_add_duplicate(struct wmOperatorType *ot);
+void SEQUENCER_OT_duplicate_add(struct wmOperatorType *ot);
void SEQUENCER_OT_delete(struct wmOperatorType *ot);
void SEQUENCER_OT_separate_images(struct wmOperatorType *ot);
void SEQUENCER_OT_meta_toggle(struct wmOperatorType *ot);
@@ -89,15 +89,15 @@ void SEQUENCER_OT_view_all(struct wmOperatorType *ot);
void SEQUENCER_OT_view_selected(struct wmOperatorType *ot);
/* sequencer_select.c */
-void SEQUENCER_OT_deselect_all(struct wmOperatorType *ot);
+void SEQUENCER_OT_select_all_toggle(struct wmOperatorType *ot);
void SEQUENCER_OT_select(struct wmOperatorType *ot);
void SEQUENCER_OT_select_more(struct wmOperatorType *ot);
void SEQUENCER_OT_select_less(struct wmOperatorType *ot);
void SEQUENCER_OT_select_linked(struct wmOperatorType *ot);
-void SEQUENCER_OT_select_pick_linked(struct wmOperatorType *ot);
+void SEQUENCER_OT_select_linked_pick(struct wmOperatorType *ot);
void SEQUENCER_OT_select_handles(struct wmOperatorType *ot);
void SEQUENCER_OT_select_active_side(struct wmOperatorType *ot);
-void SEQUENCER_OT_borderselect(struct wmOperatorType *ot);
+void SEQUENCER_OT_select_border(struct wmOperatorType *ot);
void SEQUENCER_OT_select_invert(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c
index d7ca063f4c5..a159a4828da 100644
--- a/source/blender/editors/space_sequencer/sequencer_ops.c
+++ b/source/blender/editors/space_sequencer/sequencer_ops.c
@@ -71,7 +71,7 @@ void sequencer_operatortypes(void)
WM_operatortype_append(SEQUENCER_OT_unlock);
WM_operatortype_append(SEQUENCER_OT_reload);
WM_operatortype_append(SEQUENCER_OT_refresh_all);
- WM_operatortype_append(SEQUENCER_OT_add_duplicate);
+ WM_operatortype_append(SEQUENCER_OT_duplicate_add);
WM_operatortype_append(SEQUENCER_OT_delete);
WM_operatortype_append(SEQUENCER_OT_separate_images);
WM_operatortype_append(SEQUENCER_OT_meta_toggle);
@@ -82,16 +82,16 @@ void sequencer_operatortypes(void)
WM_operatortype_append(SEQUENCER_OT_view_selected);
/* sequencer_select.c */
- WM_operatortype_append(SEQUENCER_OT_deselect_all);
+ WM_operatortype_append(SEQUENCER_OT_select_all_toggle);
WM_operatortype_append(SEQUENCER_OT_select_invert);
WM_operatortype_append(SEQUENCER_OT_select);
WM_operatortype_append(SEQUENCER_OT_select_more);
WM_operatortype_append(SEQUENCER_OT_select_less);
- WM_operatortype_append(SEQUENCER_OT_select_pick_linked);
+ WM_operatortype_append(SEQUENCER_OT_select_linked_pick);
WM_operatortype_append(SEQUENCER_OT_select_linked);
WM_operatortype_append(SEQUENCER_OT_select_handles);
WM_operatortype_append(SEQUENCER_OT_select_active_side);
- WM_operatortype_append(SEQUENCER_OT_borderselect);
+ WM_operatortype_append(SEQUENCER_OT_select_border);
/* sequencer_add.c */
WM_operatortype_append(SEQUENCER_OT_add_scene_strip);
@@ -107,7 +107,7 @@ void sequencer_keymap(wmWindowManager *wm)
ListBase *keymap= WM_keymap_listbase(wm, "Sequencer", SPACE_SEQ, 0);
wmKeymapItem *kmi;
- WM_keymap_add_item(keymap, "SEQUENCER_OT_deselect_all", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SEQUENCER_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_cut", KKEY, KM_PRESS, 0, 0)->ptr, "type", SEQ_CUT_SOFT);
@@ -124,7 +124,7 @@ void sequencer_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "SEQUENCER_OT_reload", RKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "SEQUENCER_OT_add_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "SEQUENCER_OT_duplicate_add", DKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_delete", XKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_delete", DELKEY, KM_PRESS, 0, 0);
@@ -168,12 +168,12 @@ void sequencer_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "SEQUENCER_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "SEQUENCER_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "SEQUENCER_OT_select_pick_linked", LKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_select_pick_linked", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
+ WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
WM_keymap_add_item(keymap, "SEQUENCER_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "SEQUENCER_OT_borderselect", BKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "SEQUENCER_OT_select_border", BKEY, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "ANIM_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index f7548aa556a..bfd89ccdffb 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -227,11 +227,11 @@ static int sequencer_deselect_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void SEQUENCER_OT_deselect_all(struct wmOperatorType *ot)
+void SEQUENCER_OT_select_all_toggle(struct wmOperatorType *ot)
{
/* identifiers */
ot->name= "(De)Select All";
- ot->idname= "SEQUENCER_OT_deselect_all";
+ ot->idname= "SEQUENCER_OT_select_all_toggle";
/* api callbacks */
ot->exec= sequencer_deselect_exec;
@@ -575,7 +575,7 @@ void SEQUENCER_OT_select_less(wmOperatorType *ot)
/* select pick linked operator (uses the mouse) */
-static int sequencer_select_pick_linked_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Scene *scene= CTX_data_scene(C);
ARegion *ar= CTX_wm_region(C);
@@ -611,14 +611,14 @@ static int sequencer_select_pick_linked_invoke(bContext *C, wmOperator *op, wmEv
return OPERATOR_FINISHED;
}
-void SEQUENCER_OT_select_pick_linked(wmOperatorType *ot)
+void SEQUENCER_OT_select_linked_pick(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select pick linked";
- ot->idname= "SEQUENCER_OT_select_pick_linked";
+ ot->idname= "SEQUENCER_OT_select_linked_pick";
/* api callbacks */
- ot->invoke= sequencer_select_pick_linked_invoke;
+ ot->invoke= sequencer_select_linked_pick_invoke;
ot->poll= ED_operator_sequencer_active;
/* flags */
@@ -794,11 +794,11 @@ static int sequencer_borderselect_exec(bContext *C, wmOperator *op)
/* ****** Border Select ****** */
-void SEQUENCER_OT_borderselect(wmOperatorType *ot)
+void SEQUENCER_OT_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Border Select";
- ot->idname= "SEQUENCER_OT_borderselect";
+ ot->idname= "SEQUENCER_OT_select_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
diff --git a/source/blender/editors/space_sound/Makefile b/source/blender/editors/space_sound/Makefile
index 9b1e95bf3a6..4d375282223 100644
--- a/source/blender/editors/space_sound/Makefile
+++ b/source/blender/editors/space_sound/Makefile
@@ -44,6 +44,7 @@ CPPFLAGS += -I../../blenloader
CPPFLAGS += -I../../blenkernel
CPPFLAGS += -I../../blenlib
CPPFLAGS += -I../../makesdna
+CPPFLAGS += -I../../makesrna
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../python
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
diff --git a/source/blender/editors/space_sound/SConscript b/source/blender/editors/space_sound/SConscript
index 9e57223cc2a..e4fffb53e4c 100644
--- a/source/blender/editors/space_sound/SConscript
+++ b/source/blender/editors/space_sound/SConscript
@@ -3,7 +3,7 @@ Import ('env')
sources = env.Glob('*.c')
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
env.BlenderLib ( 'bf_editors_space_sound', sources, Split(incs), [], libtype=['core'], priority=[75] )
diff --git a/source/blender/editors/space_text/SConscript b/source/blender/editors/space_text/SConscript
index c35772becbc..3d5ccc318e1 100644
--- a/source/blender/editors/space_text/SConscript
+++ b/source/blender/editors/space_text/SConscript
@@ -10,4 +10,4 @@ incs += ' #/intern/bmfont ../../python ../../makesrna ../../blenfont'
if not env['WITH_BF_PYTHON']:
defs.append('DISABLE_PYTHON')
-env.BlenderLib ( 'bf_editors_space_text', sources, Split(incs), [], libtype=['core'], priority=[95] )
+env.BlenderLib ( 'bf_editors_space_text', sources, Split(incs), defs, libtype=['core'], priority=[95] )
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 160b93d185e..89852955ca3 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -74,7 +74,6 @@ static SpaceLink *text_new(const bContext *C)
stext= MEM_callocN(sizeof(SpaceText), "inittext");
stext->spacetype= SPACE_TEXT;
- stext->font_id= 5;
stext->lheight= 12;
stext->tabnumber= 4;
@@ -164,7 +163,7 @@ static void text_operatortypes(void)
WM_operatortype_append(TEXT_OT_unindent);
WM_operatortype_append(TEXT_OT_indent);
- WM_operatortype_append(TEXT_OT_clear_all_markers);
+ WM_operatortype_append(TEXT_OT_markers_clear);
WM_operatortype_append(TEXT_OT_next_marker);
WM_operatortype_append(TEXT_OT_previous_marker);
@@ -175,9 +174,9 @@ static void text_operatortypes(void)
WM_operatortype_append(TEXT_OT_move);
WM_operatortype_append(TEXT_OT_move_select);
WM_operatortype_append(TEXT_OT_delete);
- WM_operatortype_append(TEXT_OT_toggle_overwrite);
+ WM_operatortype_append(TEXT_OT_overwrite_toggle);
- WM_operatortype_append(TEXT_OT_set_cursor);
+ WM_operatortype_append(TEXT_OT_cursor_set);
WM_operatortype_append(TEXT_OT_scroll);
WM_operatortype_append(TEXT_OT_scroll_bar);
WM_operatortype_append(TEXT_OT_line_number);
@@ -185,7 +184,8 @@ static void text_operatortypes(void)
WM_operatortype_append(TEXT_OT_line_break);
WM_operatortype_append(TEXT_OT_insert);
- WM_operatortype_append(TEXT_OT_find_and_replace);
+ WM_operatortype_append(TEXT_OT_properties);
+
WM_operatortype_append(TEXT_OT_find);
WM_operatortype_append(TEXT_OT_find_set_selected);
WM_operatortype_append(TEXT_OT_replace);
@@ -220,8 +220,8 @@ static void text_keymap(struct wmWindowManager *wm)
WM_keymap_add_item(keymap, "TEXT_OT_jump", JKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "TEXT_OT_find", FKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "TEXT_OT_find_and_replace", FKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "TEXT_OT_find_and_replace", FKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "TEXT_OT_properties", FKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "TEXT_OT_replace", HKEY, KM_PRESS, KM_CTRL, 0);
@@ -268,12 +268,12 @@ static void text_keymap(struct wmWindowManager *wm)
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", DELKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_WORD);
RNA_enum_set(WM_keymap_add_item(keymap, "TEXT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_PREV_WORD);
- WM_keymap_add_item(keymap, "TEXT_OT_toggle_overwrite", INSERTKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "TEXT_OT_overwrite_toggle", INSERTKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "TEXT_OT_scroll", MIDDLEMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "TEXT_OT_scroll_bar", LEFTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "TEXT_OT_set_cursor", LEFTMOUSE, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "TEXT_OT_set_cursor", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "select", 1);
+ WM_keymap_add_item(keymap, "TEXT_OT_cursor_set", LEFTMOUSE, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "TEXT_OT_cursor_set", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "select", 1);
RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELUPMOUSE, KM_PRESS, 0, 0)->ptr, "lines", -1);
RNA_int_set(WM_keymap_add_item(keymap, "TEXT_OT_scroll", WHEELDOWNMOUSE, KM_PRESS, 0, 0)->ptr, "lines", 1);
@@ -284,12 +284,12 @@ static void text_keymap(struct wmWindowManager *wm)
WM_keymap_add_item(keymap, "TEXT_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last!
}
-static int text_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
+static int text_context(const bContext *C, const char *member, bContextDataResult *result)
{
SpaceText *st= CTX_wm_space_text(C);
- if(member == CTX_DATA_EDIT_TEXT) {
- CTX_data_pointer_set(result, st->text);
+ if(CTX_data_equals(member, "edit_text")) {
+ CTX_data_id_pointer_set(result, &st->text->id);
return 1;
}
@@ -344,58 +344,25 @@ static void text_cursor(wmWindow *win, ScrArea *sa, ARegion *ar)
static void text_header_area_init(wmWindowManager *wm, ARegion *ar)
{
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
+ ar->v2d.flag &= ~(V2D_PIXELOFS_X|V2D_PIXELOFS_Y); // XXX temporary
}
static void text_header_area_draw(const bContext *C, ARegion *ar)
{
- float col[3];
-
- /* clear */
- if(ED_screen_area_active(C))
- UI_GetThemeColor3fv(TH_HEADER, col);
- else
- UI_GetThemeColor3fv(TH_HEADERDESEL, col);
-
- glClearColor(col[0], col[1], col[2], 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- /* set view2d view matrix for scrolling (without scrollers) */
- UI_view2d_view_ortho(C, &ar->v2d);
-
- text_header_buttons(C, ar);
-
- /* restore view matrix? */
- UI_view2d_view_restore(C);
+ uiRegionHeaderLayout(C, ar);
}
-/****************** find & replace region ******************/
+/****************** properties region ******************/
/* add handlers, stuff you only do once or on area/region changes */
-static void text_find_area_init(wmWindowManager *wm, ARegion *ar)
+static void text_properties_area_init(wmWindowManager *wm, ARegion *ar)
{
- UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
+ UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_PANELS_UI, ar->winx, ar->winy);
}
-static void text_find_area_draw(const bContext *C, ARegion *ar)
+static void text_properties_area_draw(const bContext *C, ARegion *ar)
{
- float col[3];
-
- /* clear */
- if(ED_screen_area_active(C))
- UI_GetThemeColor3fv(TH_HEADER, col);
- else
- UI_GetThemeColor3fv(TH_HEADERDESEL, col);
-
- glClearColor(col[0], col[1], col[2], 0.0);
- glClear(GL_COLOR_BUFFER_BIT);
-
- /* set view2d view matrix for scrolling (without scrollers) */
- UI_view2d_view_ortho(C, &ar->v2d);
-
- text_find_buttons(C, ar);
-
- /* restore view matrix? */
- UI_view2d_view_restore(C);
+ uiRegionPanelLayout(C, ar, 1, NULL);
}
/********************* registration ********************/
@@ -426,28 +393,32 @@ void ED_spacetype_text(void)
BLI_addhead(&st->regiontypes, art);
- /* regions: header */
+ /* regions: properties */
art= MEM_callocN(sizeof(ARegionType), "spacetype text region");
- art->regionid = RGN_TYPE_HEADER;
- art->minsizey= HEADERY;
+ art->regionid = RGN_TYPE_UI;
+ art->minsizex= UI_COMPACT_PANEL_WIDTH;
art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
- art->init= text_header_area_init;
- art->draw= text_header_area_draw;
+ art->init= text_properties_area_init;
+ art->draw= text_properties_area_draw;
+ text_properties_register(art);
+
BLI_addhead(&st->regiontypes, art);
- /* regions: find & replace */
+ /* regions: header */
art= MEM_callocN(sizeof(ARegionType), "spacetype text region");
- art->regionid = RGN_TYPE_UI;
+ art->regionid = RGN_TYPE_HEADER;
art->minsizey= HEADERY;
art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
- art->init= text_find_area_init;
- art->draw= text_find_area_draw;
+ art->init= text_header_area_init;
+ art->draw= text_header_area_draw;
+ text_header_register(art);
+
BLI_addhead(&st->regiontypes, art);
-
+
BKE_spacetype_register(st);
}
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index ea0005fd716..63e3bca1ad0 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -93,7 +93,7 @@ static void do_text_template_scriptsmenu(bContext *C, void *arg, int event)
// XXX BPY_menu_do_python(PYMENU_SCRIPTTEMPLATE, event);
}
-uiBlock *text_template_scriptsmenu(bContext *C, void *args_unused)
+static uiBlock *text_template_scriptsmenu(bContext *C, void *args_unused)
{
ARegion *ar= CTX_wm_region(C);
uiBlock *block;
@@ -126,7 +126,7 @@ static void do_text_plugin_scriptsmenu(bContext *C, void *arg, int event)
// XXX BPY_menu_do_python(PYMENU_TEXTPLUGIN, event);
}
-uiBlock *text_plugin_scriptsmenu(bContext *C, void *args_unused)
+static uiBlock *text_plugin_scriptsmenu(bContext *C, void *args_unused)
{
ARegion *ar= CTX_wm_region(C);
uiBlock *block;
@@ -169,7 +169,7 @@ static void text_editmenu_selectmenu(bContext *C, uiMenuItem *head, void *arg_un
static void text_editmenu_markermenu(bContext *C, uiMenuItem *head, void *arg_unused)
{
- uiMenuItemO(head, 0, "TEXT_OT_clear_all_markers");
+ uiMenuItemO(head, 0, "TEXT_OT_markers_clear");
uiMenuItemO(head, 0, "TEXT_OT_next_marker");
uiMenuItemO(head, 0, "TEXT_OT_previous_marker");
}
@@ -195,6 +195,11 @@ static void text_editmenu_to3dmenu(bContext *C, uiMenuItem *head, void *arg_unus
uiMenuItemBooleanO(head, "One Object Per Line", 0, "TEXT_OT_to_3d_object", "split_lines", 1);
}
+static int text_menu_edit_poll(bContext *C)
+{
+ return (CTX_data_edit_text(C) != NULL);
+}
+
static void text_editmenu(bContext *C, uiMenuItem *head, void *arg_unused)
{
uiMenuItemO(head, 0, "ED_OT_undo");
@@ -215,7 +220,7 @@ static void text_editmenu(bContext *C, uiMenuItem *head, void *arg_unused)
uiMenuSeparator(head);
uiMenuItemO(head, 0, "TEXT_OT_jump");
- uiMenuItemO(head, 0, "TEXT_OT_find_and_replace");
+ uiMenuItemO(head, 0, "TEXT_OT_properties");
uiMenuSeparator(head);
@@ -353,89 +358,43 @@ static void text_idpoin_handle(bContext *C, ID *id, int event)
/********************** header buttons ***********************/
-void text_header_buttons(const bContext *C, ARegion *ar)
+static void text_header_draw(const bContext *C, uiLayout *layout)
{
bScreen *sc= CTX_wm_screen(C);
SpaceText *st= (SpaceText*)CTX_wm_space_data(C);
PointerRNA spaceptr;
Text *text= st->text;
- ScrArea *sa= CTX_wm_area(C);
- uiBlock *block;
- int xco, yco= 3, xmax, oldcol;
RNA_pointer_create(&sc->id, &RNA_SpaceTextEditor, st, &spaceptr);
- block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS, UI_HELV);
-
- xco= ED_area_header_standardbuttons(C, block, yco);
-
- if((sa->flag & HEADER_NO_PULLDOWN)==0) {
- /* pull down menus */
- uiBlockSetEmboss(block, UI_EMBOSSP);
-
- xmax= GetButStringLength("Text");
- uiDefMenuBut(block, text_filemenu, NULL, "Text", xco, yco-2, xmax-3, 24, "");
- xco+=xmax;
-
- if(text) {
- xmax= GetButStringLength("Edit");
- uiDefMenuBut(block, text_editmenu, NULL, "Edit", xco, yco-2, xmax-3, 24, "");
- xco+=xmax;
-
- xmax= GetButStringLength("Format");
- uiDefMenuBut(block, text_formatmenu, NULL, "Format", xco, yco-2, xmax-3, 24, "");
- xco+=xmax;
- }
+ uiTemplateHeaderMenus(layout);
+ uiItemMenu(layout, UI_TSLOT_HEADER, "Text", 0, text_filemenu);
+ if(text) {
+ uiItemMenu(layout, UI_TSLOT_HEADER, "Edit", 0, text_editmenu);
+ uiItemMenu(layout, UI_TSLOT_HEADER, "Format", 0, text_formatmenu);
}
-
- uiBlockSetEmboss(block, UI_EMBOSS);
-
- uiBlockBeginAlign(block);
- uiDefIconButR(block, ICONTOG, 0, ICON_LINENUMBERS_OFF, xco, yco,XIC,YIC, &spaceptr, "line_numbers", 0, 0, 0, 0, 0, NULL);
- uiDefIconButR(block, ICONTOG, 0, ICON_WORDWRAP_OFF, xco+=XIC, yco,XIC,YIC, &spaceptr, "word_wrap", 0, 0, 0, 0, 0, NULL);
- uiDefIconButR(block, ICONTOG, 0, ICON_SYNTAX_OFF, xco+=XIC, yco,XIC,YIC, &spaceptr, "syntax_highlight", 0, 0, 0, 0, 0, NULL);
- // uiDefIconButR(block, ICONTOG, 0, ICON_SCRIPTPLUGINS, xco+=XIC, yco,XIC,YIC, &spaceptr, "do_python_plugins", 0, 0, 0, 0, 0, "Enables Python text plugins");
- uiBlockEndAlign(block);
-
+
/* warning button if text is out of date */
if(text && text_file_modified(text)) {
- xco+= XIC;
-
- oldcol= uiBlockGetCol(block);
- uiBlockSetCol(block, TH_REDALERT);
- uiDefIconButO(block, BUT, "TEXT_OT_resolve_conflict", WM_OP_INVOKE_DEFAULT, ICON_HELP, xco+=XIC,yco,XIC,YIC, "External text is out of sync, click for options to resolve the conflict");
- uiBlockSetCol(block, oldcol);
+ uiTemplateHeaderButtons(layout);
+ uiTemplateSetColor(layout, TH_REDALERT);
+ uiItemO(layout, UI_TSLOT_HEADER, "", ICON_HELP, "TEXT_OT_resolve_conflict");
}
-
- /* browse text datablock */
- xco+= 2*XIC;
- xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID*)st->text, ID_TXT, NULL, xco, yco,
- text_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE);
- xco+=XIC;
-
- /*
- if(st->text) {
- if(st->text->flags & TXT_ISDIRTY && (st->text->flags & TXT_ISEXT || !(st->text->flags & TXT_ISMEM)))
- uiDefIconBut(block, BUT,0, ICON_ERROR, xco+=XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "The text has been changed");
- if(st->text->flags & TXT_ISEXT)
- uiDefBut(block, BUT,B_TEXTSTORE, ICON(), xco+=XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Stores text in project file");
- else
- uiDefBut(block, BUT,B_TEXTSTORE, ICON(), xco+=XIC,yco,XIC,YIC, 0, 0, 0, 0, 0, "Disables storing of text in project file");
- xco+=10;
- }
- */
-
- /* display settings */
- if(st->font_id>1) st->font_id= 0;
- uiDefButR(block, MENU, 0, NULL, xco,yco,100,YIC, &spaceptr, "font_size", 0, 0, 0, 0, 0, NULL);
- xco+=105;
-
- uiDefButR(block, NUM, 0, "Tab:", xco,yco,XIC+50,YIC, &spaceptr, "tab_width", 0, 0, 0, 0, 0, NULL);
- xco+= XIC+50;
+
+ uiTemplateHeaderButtons(layout);
+ uiItemR(layout, UI_TSLOT_HEADER, "", ICON_LINENUMBERS_OFF, &spaceptr, "line_numbers");
+ uiItemR(layout, UI_TSLOT_HEADER, "", ICON_WORDWRAP_OFF, &spaceptr, "word_wrap");
+ uiItemR(layout, UI_TSLOT_HEADER, "", ICON_SYNTAX_OFF, &spaceptr, "syntax_highlight");
+ // XXX uiItemR(layout, "", ICON_SCRIPTPLUGINS, &spaceptr, "do_python_plugins");
+
+ uiTemplateHeaderID(layout, &spaceptr, "text",
+ UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE,
+ text_idpoin_handle);
/* file info */
if(text) {
- char fname[HEADER_PATH_MAX], headtxt[HEADER_PATH_MAX+17];
+ char fname[HEADER_PATH_MAX];
+ static char headtxt[HEADER_PATH_MAX+17];
int len;
if(text->name) {
@@ -452,74 +411,97 @@ void text_header_buttons(const bContext *C, ARegion *ar)
else
sprintf(headtxt, text->id.lib? "Text: External": "Text: Internal");
- UI_ThemeColor(TH_MENU_TEXT);
- UI_RasterPos(xco+=XIC, yco+6);
-
- UI_DrawString(G.font, headtxt, 0);
- xco += UI_GetStringWidth(G.font, headtxt, 0);
+ uiTemplateHeaderButtons(layout);
+ uiItemLabel(layout, UI_TSLOT_HEADER, headtxt, 0);
}
+}
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
-
- /* always as last */
- UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
+void text_header_register(ARegionType *art)
+{
+ HeaderType *ht;
+
+ /* header */
+ ht= MEM_callocN(sizeof(HeaderType), "spacetype text header");
+ ht->idname= "TEXT_HT_header";
+ ht->name= "Header";
+ ht->draw= text_header_draw;
+ BLI_addhead(&art->headertypes, ht);
}
-/************************* find & replace ***************************/
+/************************** properties ******************************/
-void text_find_buttons(const bContext *C, ARegion *ar)
+static void text_properties_panel_draw(const bContext *C, Panel *panel)
{
bScreen *sc= CTX_wm_screen(C);
SpaceText *st= CTX_wm_space_text(C);
+ uiLayout *layout= panel->layout;
PointerRNA spaceptr;
- uiBlock *block;
- int xco= 5, yco= 3;
RNA_pointer_create(&sc->id, &RNA_SpaceTextEditor, st, &spaceptr);
- block= uiBeginBlock(C, ar, "find buttons", UI_EMBOSS, UI_HELV);
+ uiTemplateColumn(layout);
+ uiItemR(layout, UI_TSLOT_COLUMN_1, NULL, ICON_LINENUMBERS_OFF, &spaceptr, "line_numbers");
+ uiItemR(layout, UI_TSLOT_COLUMN_1, NULL, ICON_WORDWRAP_OFF, &spaceptr, "word_wrap");
+ uiItemR(layout, UI_TSLOT_COLUMN_1, NULL, ICON_SYNTAX_OFF, &spaceptr, "syntax_highlight");
+
+ uiTemplateColumn(layout);
+ uiItemR(layout, UI_TSLOT_COLUMN_1, NULL, 0, &spaceptr, "font_size");
+ uiItemR(layout, UI_TSLOT_COLUMN_1, NULL, 0, &spaceptr, "tab_width");
+}
+
+static void text_find_panel_draw(const bContext *C, Panel *panel)
+{
+ bScreen *sc= CTX_wm_screen(C);
+ SpaceText *st= CTX_wm_space_text(C);
+ uiLayout *layout= panel->layout;
+ PointerRNA spaceptr;
+
+ RNA_pointer_create(&sc->id, &RNA_SpaceTextEditor, st, &spaceptr);
/* find */
- uiBlockBeginAlign(block);
- uiDefButR(block, TEX, 0, "Find: ", xco, yco,220,20, &spaceptr, "find_text", 0, 0, 0, 0, 0, NULL);
- xco += 220;
- uiDefIconButO(block, BUT, "TEXT_OT_find_set_selected", WM_OP_INVOKE_DEFAULT, ICON_TEXT, xco,yco,20,20, "Copy from selection");
- xco += 20+XIC;
- uiBlockEndAlign(block);
+ uiTemplateLeftRight(layout);
+ uiItemR(layout, UI_TSLOT_LR_LEFT, "", 0, &spaceptr, "find_text");
+ uiItemO(layout, UI_TSLOT_LR_RIGHT, "", ICON_TEXT, "TEXT_OT_find_set_selected");
+ uiTemplateColumn(layout);
+ uiItemO(layout, UI_TSLOT_COLUMN_1, NULL, 0, "TEXT_OT_find");
/* replace */
- uiBlockBeginAlign(block);
- uiDefButR(block, TEX, 0, "Replace: ", xco, yco,220,20, &spaceptr, "replace_text", 0, 0, 0, 0, 0, NULL);
- xco += 220;
- uiDefIconButO(block, BUT, "TEXT_OT_replace_set_selected", WM_OP_INVOKE_DEFAULT, ICON_TEXT, xco,yco,20,20, "Copy from selection");
- xco += 20+XIC;
- uiBlockEndAlign(block);
-
- uiBlockBeginAlign(block);
- uiDefButR(block, TOG, 0, "Wrap", xco, yco,60,20, &spaceptr, "find_wrap", 0, 0, 0, 0, 0, NULL);
- xco += 60;
- uiDefButR(block, TOG, 0, "All", xco, yco,60,20, &spaceptr, "find_all", 0, 0, 0, 0, 0, NULL);
- xco += 50+XIC;
- uiBlockEndAlign(block);
-
- uiBlockBeginAlign(block);
- uiDefButO(block, BUT, "TEXT_OT_find", WM_OP_INVOKE_REGION_WIN, "Find", xco,yco,50,20, "Find next.");
- xco += 50;
- uiDefButO(block, BUT, "TEXT_OT_replace", WM_OP_INVOKE_REGION_WIN, "Replace", xco,yco,70,20, "Replace then find next.");
- xco += 70;
- uiDefButO(block, BUT, "TEXT_OT_mark_all", WM_OP_INVOKE_REGION_WIN, "Mark All", xco,yco,80,20, "Mark each occurrence to edit all from one");
- xco += 80;
- uiBlockEndAlign(block);
-
- uiEndBlock(C, block);
- uiDrawBlock(C, block);
+ uiTemplateLeftRight(layout);
+ uiItemR(layout, UI_TSLOT_LR_LEFT, "", 0, &spaceptr, "replace_text");
+ uiItemO(layout, UI_TSLOT_LR_RIGHT, "", ICON_TEXT, "TEXT_OT_replace_set_selected");
+ uiTemplateColumn(layout);
+ uiItemO(layout, UI_TSLOT_COLUMN_1, NULL, 0, "TEXT_OT_replace");
+
+ /* mark */
+ uiTemplateColumn(layout);
+ uiItemO(layout, UI_TSLOT_COLUMN_1, NULL, 0, "TEXT_OT_mark_all");
+
+ /* settings */
+ uiTemplateColumn(layout);
+ uiItemR(layout, UI_TSLOT_COLUMN_1, "Wrap", 0, &spaceptr, "find_wrap");
+ uiItemR(layout, UI_TSLOT_COLUMN_2, "All", 0, &spaceptr, "find_all");
+}
- /* always as last */
- UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
+void text_properties_register(ARegionType *art)
+{
+ PanelType *pt;
+
+ /* panels: properties */
+ pt= MEM_callocN(sizeof(PanelType), "spacetype text panel");
+ pt->idname= "TEXT_PT_properties";
+ pt->name= "Properties";
+ pt->draw= text_properties_panel_draw;
+ BLI_addtail(&art->paneltypes, pt);
+
+ /* panels: find */
+ pt= MEM_callocN(sizeof(PanelType), "spacetype text panel");
+ pt->idname= "TEXT_PT_find";
+ pt->name= "Find";
+ pt->draw= text_find_panel_draw;
+ BLI_addtail(&art->paneltypes, pt);
}
-ARegion *text_has_find_region(ScrArea *sa)
+ARegion *text_has_properties_region(ScrArea *sa)
{
ARegion *ar, *arnew;
@@ -535,18 +517,18 @@ ARegion *text_has_find_region(ScrArea *sa)
/* is error! */
if(ar==NULL) return NULL;
- arnew= MEM_callocN(sizeof(ARegion), "find and replace region");
+ arnew= MEM_callocN(sizeof(ARegion), "properties region");
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype= RGN_TYPE_UI;
- arnew->alignment= RGN_ALIGN_BOTTOM;
+ arnew->alignment= RGN_ALIGN_LEFT;
arnew->flag = RGN_FLAG_HIDDEN;
return arnew;
}
-static int find_and_replace_poll(bContext *C)
+static int properties_poll(bContext *C)
{
SpaceText *st= CTX_wm_space_text(C);
Text *text= CTX_data_edit_text(C);
@@ -554,10 +536,10 @@ static int find_and_replace_poll(bContext *C)
return (st && text);
}
-static int find_and_replace_exec(bContext *C, wmOperator *op)
+static int properties_exec(bContext *C, wmOperator *op)
{
ScrArea *sa= CTX_wm_area(C);
- ARegion *ar= text_has_find_region(sa);
+ ARegion *ar= text_has_properties_region(sa);
if(ar) {
ar->flag ^= RGN_FLAG_HIDDEN;
@@ -570,15 +552,15 @@ static int find_and_replace_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void TEXT_OT_find_and_replace(wmOperatorType *ot)
+void TEXT_OT_properties(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Find and Replace";
- ot->idname= "TEXT_OT_find_and_replace";
+ ot->name= "Properties";
+ ot->idname= "TEXT_OT_properties";
/* api callbacks */
- ot->exec= find_and_replace_exec;
- ot->poll= find_and_replace_poll;
+ ot->exec= properties_exec;
+ ot->poll= properties_poll;
}
/******************** XXX popup menus *******************/
diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h
index b7e45501047..7ec75e292ce 100644
--- a/source/blender/editors/space_text/text_intern.h
+++ b/source/blender/editors/space_text/text_intern.h
@@ -31,6 +31,7 @@
/* internal exports only */
struct ARegion;
+struct ARegionType;
struct bContext;
struct BMF_Font;
struct ReportList;
@@ -42,8 +43,8 @@ struct wmOperatorType;
struct wmWindowManager;
/* text_header.c */
-void text_header_buttons(const struct bContext *C, struct ARegion *ar);
-void text_find_buttons(const struct bContext *C, struct ARegion *ar);
+void text_properties_register(struct ARegionType *art);
+void text_header_register(struct ARegionType *art);
/* text_draw.c */
void draw_text_main(struct SpaceText *st, struct ARegion *ar);
@@ -124,7 +125,7 @@ void TEXT_OT_indent(struct wmOperatorType *ot);
void TEXT_OT_line_break(struct wmOperatorType *ot);
void TEXT_OT_insert(struct wmOperatorType *ot);
-void TEXT_OT_clear_all_markers(struct wmOperatorType *ot);
+void TEXT_OT_markers_clear(struct wmOperatorType *ot);
void TEXT_OT_next_marker(struct wmOperatorType *ot);
void TEXT_OT_previous_marker(struct wmOperatorType *ot);
@@ -135,14 +136,15 @@ void TEXT_OT_jump(struct wmOperatorType *ot);
void TEXT_OT_move(struct wmOperatorType *ot);
void TEXT_OT_move_select(struct wmOperatorType *ot);
void TEXT_OT_delete(struct wmOperatorType *ot);
-void TEXT_OT_toggle_overwrite(struct wmOperatorType *ot);
+void TEXT_OT_overwrite_toggle(struct wmOperatorType *ot);
void TEXT_OT_scroll(struct wmOperatorType *ot);
void TEXT_OT_scroll_bar(struct wmOperatorType *ot);
-void TEXT_OT_set_cursor(struct wmOperatorType *ot);
+void TEXT_OT_cursor_set(struct wmOperatorType *ot);
void TEXT_OT_line_number(struct wmOperatorType *ot);
-void TEXT_OT_find_and_replace(struct wmOperatorType *ot);
+void TEXT_OT_properties(struct wmOperatorType *ot);
+
void TEXT_OT_find(struct wmOperatorType *ot);
void TEXT_OT_find_set_selected(struct wmOperatorType *ot);
void TEXT_OT_replace(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index a77bea4c640..c7fe02975ef 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -78,11 +78,6 @@ static int text_new_poll(bContext *C)
return 1;
}
-static int text_valid_poll(bContext *C)
-{
- return CTX_data_edit_text(C) ? 1:0;
-}
-
static int text_edit_poll(bContext *C)
{
Text *text= CTX_data_edit_text(C);
@@ -1162,11 +1157,11 @@ static int clear_all_markers_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void TEXT_OT_clear_all_markers(wmOperatorType *ot)
+void TEXT_OT_markers_clear(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clear All Markers";
- ot->idname= "TEXT_OT_clear_all_markers";
+ ot->idname= "TEXT_OT_markers_clear";
/* api callbacks */
ot->exec= clear_all_markers_exec;
@@ -1578,11 +1573,11 @@ static int toggle_overwrite_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void TEXT_OT_toggle_overwrite(wmOperatorType *ot)
+void TEXT_OT_overwrite_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Toggle Overwrite";
- ot->idname= "TEXT_OT_toggle_overwrite";
+ ot->idname= "TEXT_OT_overwrite_toggle";
/* api callbacks */
ot->exec= toggle_overwrite_exec;
@@ -1742,7 +1737,7 @@ void TEXT_OT_scroll(wmOperatorType *ot)
ot->poll= text_space_edit_poll;
/* properties */
- RNA_def_int(ot->srna, "lines", INT_MIN, INT_MAX, 1, "Lines", "Number of lines to scroll.", -100, 100);
+ RNA_def_int(ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll.", -100, 100);
}
/******************** scroll bar operator *******************/
@@ -1786,7 +1781,7 @@ void TEXT_OT_scroll_bar(wmOperatorType *ot)
ot->poll= text_region_edit_poll;
/* properties */
- RNA_def_int(ot->srna, "lines", INT_MIN, INT_MAX, 1, "Lines", "Number of lines to scroll.", -100, 100);
+ RNA_def_int(ot->srna, "lines", 1, INT_MIN, INT_MAX, "Lines", "Number of lines to scroll.", -100, 100);
}
/******************* set cursor operator **********************/
@@ -2043,11 +2038,11 @@ static int set_cursor_cancel(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void TEXT_OT_set_cursor(wmOperatorType *ot)
+void TEXT_OT_cursor_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Cursor";
- ot->idname= "TEXT_OT_set_cursor";
+ ot->idname= "TEXT_OT_cursor_set";
/* api callbacks */
ot->invoke= set_cursor_invoke;
@@ -2489,6 +2484,7 @@ void TEXT_OT_resolve_conflict(wmOperatorType *ot)
/* identifiers */
ot->name= "Resolve Conflict";
ot->idname= "TEXT_OT_resolve_conflict";
+ ot->description= "When external text is out of sync, resolve the conflict.";
/* api callbacks */
ot->exec= resolve_conflict_exec;
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 ab4781a25a8..78f3ea73aaf 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/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 4e2a0090244..b7682225fe3 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -62,6 +62,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "RNA_access.h"
+
#include "view3d_intern.h" // own include
/* ******************** manage regions ********************* */
@@ -241,6 +243,13 @@ static void view3d_modal_keymaps(wmWindowManager *wm, ARegion *ar, int stype)
else
WM_event_remove_keymap_handler(&ar->handlers, keymap);
+ /* armature sketching needs to take over mouse */
+ keymap= WM_keymap_listbase(wm, "Armature_Sketch", 0, 0);
+ if(stype==NS_EDITMODE_TEXT)
+ WM_event_add_keymap_handler_priority(&ar->handlers, keymap, 10);
+ else
+ WM_event_remove_keymap_handler(&ar->handlers, keymap);
+
keymap= WM_keymap_listbase(wm, "Particle", 0, 0);
if(stype==NS_MODE_PARTICLE)
WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -519,7 +528,7 @@ static int object_is_libdata(Object *ob)
return 0;
}
-static int view3d_context(const bContext *C, bContextDataMember member, bContextDataResult *result)
+static int view3d_context(const bContext *C, const char *member, bContextDataResult *result)
{
View3D *v3d= CTX_wm_view3d(C);
Scene *scene= CTX_data_scene(C);
@@ -527,29 +536,33 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
if(v3d==NULL) return 0;
- if(ELEM(member, CTX_DATA_SELECTED_OBJECTS, CTX_DATA_SELECTED_BASES)) {
+ if(CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) {
+ int selected_objects= CTX_data_equals(member, "selected_objects");
+
for(base=scene->base.first; base; base=base->next) {
if((base->flag & SELECT) && (base->lay & v3d->lay)) {
if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
- if(member == CTX_DATA_SELECTED_OBJECTS)
- CTX_data_list_add(result, base->object);
+ if(selected_objects)
+ CTX_data_id_list_add(result, &base->object->id);
else
- CTX_data_list_add(result, base);
+ CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
}
}
}
return 1;
}
- else if(ELEM(member, CTX_DATA_SELECTED_EDITABLE_OBJECTS, CTX_DATA_SELECTED_EDITABLE_BASES)) {
+ else if(CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) {
+ int selected_editable_objects= CTX_data_equals(member, "selected_editable_objects");
+
for(base=scene->base.first; base; base=base->next) {
if((base->flag & SELECT) && (base->lay & v3d->lay)) {
if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
if(0==object_is_libdata(base->object)) {
- if(member == CTX_DATA_SELECTED_EDITABLE_OBJECTS)
- CTX_data_list_add(result, base->object);
+ if(selected_editable_objects)
+ CTX_data_id_list_add(result, &base->object->id);
else
- CTX_data_list_add(result, base);
+ CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
}
}
}
@@ -557,38 +570,41 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
return 1;
}
- else if(ELEM(member, CTX_DATA_VISIBLE_OBJECTS, CTX_DATA_VISIBLE_BASES)) {
+ else if(CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) {
+ int visible_objects= CTX_data_equals(member, "visible_objects");
+
for(base=scene->base.first; base; base=base->next) {
if(base->lay & v3d->lay) {
if((base->object->restrictflag & OB_RESTRICT_VIEW)==0) {
- if(member == CTX_DATA_VISIBLE_OBJECTS)
- CTX_data_list_add(result, base->object);
+ if(visible_objects)
+ CTX_data_id_list_add(result, &base->object->id);
else
- CTX_data_list_add(result, base);
+ CTX_data_list_add(result, &scene->id, &RNA_UnknownType, base);
}
}
}
return 1;
}
- else if(member == CTX_DATA_ACTIVE_BASE) {
+ else if(CTX_data_equals(member, "active_base")) {
if(scene->basact && (scene->basact->lay & v3d->lay))
if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0)
- CTX_data_pointer_set(result, scene->basact);
+ CTX_data_pointer_set(result, &scene->id, &RNA_UnknownType, scene->basact);
return 1;
}
- else if(member == CTX_DATA_ACTIVE_OBJECT) {
+ else if(CTX_data_equals(member, "active_object")) {
if(scene->basact && (scene->basact->lay & v3d->lay))
if((scene->basact->object->restrictflag & OB_RESTRICT_VIEW)==0)
- CTX_data_pointer_set(result, scene->basact->object);
+ CTX_data_id_pointer_set(result, &scene->basact->object->id);
return 1;
}
- else if(ELEM(member, CTX_DATA_VISIBLE_BONES, CTX_DATA_EDITABLE_BONES)) {
+ else if(CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
Object *obedit= scene->obedit; // XXX get from context?
bArmature *arm= (obedit) ? obedit->data : NULL;
EditBone *ebone, *flipbone=NULL;
+ int editable_bones= CTX_data_equals(member, "editable_bones");
if (arm && arm->edbo) {
/* Attention: X-Axis Mirroring is also handled here... */
@@ -605,21 +621,21 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
/* if we're filtering for editable too, use the check for that instead, as it has selection check too */
- if (member == CTX_DATA_EDITABLE_BONES) {
+ if (editable_bones) {
/* only selected + editable */
if (EBONE_EDITABLE(ebone)) {
- CTX_data_list_add(result, ebone);
+ CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
- CTX_data_list_add(result, flipbone);
+ CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
}
}
else {
/* only include bones if visible */
- CTX_data_list_add(result, ebone);
+ CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
if ((flipbone) && EBONE_VISIBLE(arm, flipbone)==0)
- CTX_data_list_add(result, flipbone);
+ CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
}
}
}
@@ -627,10 +643,11 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
return 1;
}
}
- else if(ELEM(member, CTX_DATA_SELECTED_BONES, CTX_DATA_SELECTED_EDITABLE_BONES)) {
+ else if(CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) {
Object *obedit= scene->obedit; // XXX get from context?
bArmature *arm= (obedit) ? obedit->data : NULL;
EditBone *ebone, *flipbone=NULL;
+ int selected_editable_bones= CTX_data_equals(member, "selected_editable_bones");
if (arm && arm->edbo) {
/* Attention: X-Axis Mirroring is also handled here... */
@@ -647,21 +664,21 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
flipbone = ED_armature_bone_get_mirrored(arm->edbo, ebone);
/* if we're filtering for editable too, use the check for that instead, as it has selection check too */
- if (member == CTX_DATA_SELECTED_EDITABLE_BONES) {
+ if (selected_editable_bones) {
/* only selected + editable */
if (EBONE_EDITABLE(ebone)) {
- CTX_data_list_add(result, ebone);
+ CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
- CTX_data_list_add(result, flipbone);
+ CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
}
}
else {
/* only include bones if selected */
- CTX_data_list_add(result, ebone);
+ CTX_data_list_add(result, &arm->id, &RNA_UnknownType, ebone);
if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
- CTX_data_list_add(result, flipbone);
+ CTX_data_list_add(result, &arm->id, &RNA_UnknownType, flipbone);
}
}
}
@@ -669,7 +686,7 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
return 1;
}
}
- else if(member == CTX_DATA_VISIBLE_PCHANS) {
+ else if(CTX_data_equals(member, "visible_pchans")) {
Object *obact= OBACT;
bArmature *arm= (obact) ? obact->data : NULL;
bPoseChannel *pchan;
@@ -678,14 +695,14 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
for (pchan= obact->pose->chanbase.first; pchan; pchan= pchan->next) {
/* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
- CTX_data_list_add(result, pchan);
+ CTX_data_list_add(result, &obact->id, &RNA_PoseChannel, pchan);
}
}
return 1;
}
}
- else if(member == CTX_DATA_SELECTED_PCHANS) {
+ else if(CTX_data_equals(member, "selected_pchans")) {
Object *obact= OBACT;
bArmature *arm= (obact) ? obact->data : NULL;
bPoseChannel *pchan;
@@ -695,14 +712,14 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
/* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
if (pchan->bone->flag & (BONE_SELECTED|BONE_ACTIVE))
- CTX_data_list_add(result, pchan);
+ CTX_data_list_add(result, &obact->id, &RNA_PoseChannel, pchan);
}
}
return 1;
}
}
- else if(member == CTX_DATA_ACTIVE_BONE) {
+ else if(CTX_data_equals(member, "active_bone")) {
Object *obedit= scene->obedit; // XXX get from context?
bArmature *arm= (obedit) ? obedit->data : NULL;
EditBone *ebone;
@@ -711,7 +728,7 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
if (EBONE_VISIBLE(arm, ebone)) {
if (ebone->flag & BONE_ACTIVE) {
- CTX_data_pointer_set(result, ebone);
+ CTX_data_pointer_set(result, &arm->id, &RNA_UnknownType, ebone);
return 1;
}
@@ -720,13 +737,13 @@ static int view3d_context(const bContext *C, bContextDataMember member, bContext
}
}
- else if(member == CTX_DATA_ACTIVE_PCHAN) {
+ else if(CTX_data_equals(member, "active_pchan")) {
Object *obact= OBACT;
bPoseChannel *pchan;
pchan= get_active_posechannel(obact);
if (pchan) {
- CTX_data_pointer_set(result, pchan);
+ CTX_data_pointer_set(result, &obact->id, &RNA_PoseChannel, pchan);
return 1;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 6f5860ea4b5..bbcb8b3601d 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -56,6 +56,7 @@
#include "BLI_rand.h"
#include "BKE_action.h"
+#include "BKE_brush.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_customdata.h"
@@ -160,7 +161,7 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d,
if(ob->type==OB_MESH) {
Mesh *me= ob->data;
- EditMesh *em = me->edit_mesh;
+ EditMesh *em = EM_GetEditMesh(me);
EditVert *eve, *evedef=NULL;
EditEdge *eed;
@@ -208,6 +209,8 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d,
tfp->defweightp= &dvert->dw[0].weight;
}
}
+
+ EM_EndEditMesh(me, em);
}
else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
Curve *cu= ob->data;
@@ -362,7 +365,7 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d,
if(ob->type==OB_MESH) {
Mesh *me= ob->data;
- EditMesh *em = me->edit_mesh;
+ EditMesh *em = EM_GetEditMesh(me);
EditVert *eve;
EditEdge *eed;
@@ -387,6 +390,8 @@ static void v3d_editvertex_buts(const bContext *C, uiBlock *block, View3D *v3d,
}
recalc_editnormals(em);
+
+ EM_EndEditMesh(me, em);
}
else if(ob->type==OB_CURVE || ob->type==OB_SURF) {
Curve *cu= ob->data;
@@ -640,7 +645,6 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
BoundBox *bb;
Object *ob= OBACT;
TransformProperties *tfp= v3d->properties_storage;
- VPaint *wpaint= scene->toolsettings->wpaint;
switch(event) {
@@ -846,6 +850,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
BIF_clearTransformOrientation(C);
break;
+#if 0 // XXX
case B_WEIGHT0_0:
wpaint->weight = 0.0f;
break;
@@ -878,6 +883,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event)
case B_OPA1_0:
wpaint->a = 1.0f;
break;
+#endif
case B_CLR_WPAINT:
// if(!multires_level1_test()) {
{
@@ -1003,7 +1009,8 @@ static void weight_paint_buttons(Scene *scene, uiBlock *block)
ob= OBACT;
if(ob==NULL || ob->type!=OB_MESH) return;
-
+
+ /* XXX
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI, B_REDR, "Weight:",10,170,225,19, &wpaint->weight, 0, 1, 10, 0, "Sets the current vertex group's bone deformation strength");
@@ -1032,6 +1039,7 @@ static void weight_paint_buttons(Scene *scene, uiBlock *block)
uiDefButS(block, ROW, B_NOP, "Lighter", 250, 80,60,17, &wpaint->mode, 1.0, 5.0, 0, 0, "Paint over darker areas only");
uiDefButS(block, ROW, B_NOP, "Darker", 250, 62,60,17, &wpaint->mode, 1.0, 6.0, 0, 0, "Paint over lighter areas only");
uiBlockEndAlign(block);
+ */
/* draw options same as below */
uiBlockBeginAlign(block);
@@ -1062,47 +1070,112 @@ static void weight_paint_buttons(Scene *scene, uiBlock *block)
}
}
-static void sculptmode_draw_interface_tools(Scene *scene, uiBlock *block, unsigned short cx, unsigned short cy)
+static void brush_idpoin_handle(bContext *C, ID *id, int event)
{
- Sculpt *s = scene->toolsettings->sculpt;
- Brush *br = s->brush;
-
+ Brush **br = current_brush_source(CTX_data_scene(C));
+
+ if(!br)
+ return;
+
+ switch(event) {
+ case UI_ID_BROWSE:
+ (*br) = (Brush*)id;
+ break;
+ case UI_ID_DELETE:
+ brush_delete(br);
+ break;
+ case UI_ID_RENAME:
+ /* XXX ? */
+ break;
+ case UI_ID_ADD_NEW:
+ if(id) {
+ (*br) = copy_brush((Brush*)id);
+ id->us--;
+ }
+ else
+ (*br) = add_brush("Brush");
+ break;
+ case UI_ID_OPEN:
+ /* XXX not implemented */
+ break;
+ }
+}
+
+static void view3d_panel_brush(const bContext *C, ARegion *ar, short cntrl)
+{
+ uiBlock *block;
+ Brush **brp = current_brush_source(CTX_data_scene(C)), *br;
+ short w = 268, h = 400, cx = 10, cy = h;
+ rctf rect;
+
+ if(!brp)
+ return;
+ br = *brp;
+
+ block= uiBeginBlock(C, ar, "view3d_panel_brush", UI_EMBOSS, UI_HELV);
+ if(uiNewPanel(C, ar, block, "Brush", "View3d", 340, 10, 318, h)==0) return;
+ uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
+
uiBlockBeginAlign(block);
-
- uiDefBut(block,LABEL,B_NOP,"Brush",cx,cy,90,19,NULL,0,0,0,0,"");
- cy-= 20;
-
- uiBlockBeginAlign(block);
- uiDefButC(block,ROW,B_REDR,"Draw",cx,cy,67,19,&br->sculpt_tool,14.0,SCULPT_TOOL_DRAW,0,0,"Draw lines on the model");
- uiDefButC(block,ROW,B_REDR,"Smooth",cx+67,cy,67,19,&br->sculpt_tool,14.0,SCULPT_TOOL_SMOOTH,0,0,"Interactively smooth areas of the model");
- uiDefButC(block,ROW,B_REDR,"Pinch",cx+134,cy,67,19,&br->sculpt_tool,14.0,SCULPT_TOOL_PINCH,0,0,"Interactively pinch areas of the model");
- uiDefButC(block,ROW,B_REDR,"Inflate",cx+201,cy,67,19,&br->sculpt_tool,14,SCULPT_TOOL_INFLATE,0,0,"Push vertices along the direction of their normals");
+ uiDefIDPoinButs(block, CTX_data_main(C), NULL, &br->id, ID_BR, NULL, cx, cy,
+ brush_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE|UI_ID_ALONE);
+ cy-= 25;
+ uiBlockEndAlign(block);
+
+ if(!br)
+ return;
+
+ if(G.f & G_SCULPTMODE) {
+ uiBlockBeginAlign(block);
+ uiDefButC(block,ROW,B_REDR,"Draw",cx,cy,67,19,&br->sculpt_tool,14.0,SCULPT_TOOL_DRAW,0,0,"Draw lines on the model");
+ uiDefButC(block,ROW,B_REDR,"Smooth",cx+67,cy,67,19,&br->sculpt_tool,14.0,SCULPT_TOOL_SMOOTH,0,0,"Interactively smooth areas of the model");
+ uiDefButC(block,ROW,B_REDR,"Pinch",cx+134,cy,67,19,&br->sculpt_tool,14.0,SCULPT_TOOL_PINCH,0,0,"Interactively pinch areas of the model");
+ uiDefButC(block,ROW,B_REDR,"Inflate",cx+201,cy,67,19,&br->sculpt_tool,14,SCULPT_TOOL_INFLATE,0,0,"Push vertices along the direction of their normals");
+ cy-= 20;
+ uiDefButC(block,ROW,B_REDR,"Grab", cx,cy,89,19,&br->sculpt_tool,14,SCULPT_TOOL_GRAB,0,0,"Grabs a group of vertices and moves them with the mouse");
+ uiDefButC(block,ROW,B_REDR,"Layer", cx+89,cy,89,19,&br->sculpt_tool,14, SCULPT_TOOL_LAYER,0,0,"Adds a layer of depth");
+ uiDefButC(block,ROW,B_REDR,"Flatten", cx+178,cy,90,19,&br->sculpt_tool,14, SCULPT_TOOL_FLATTEN,0,0,"Interactively flatten areas of the model");
+ cy-= 25;
+ uiBlockEndAlign(block);
+ }
+
+ uiBlockBeginAlign(block);
+ uiDefButI(block,NUMSLI,B_NOP,"Size: ",cx,cy,w,19,&br->size,1.0,200.0,0,0,"Set brush radius in pixels");
cy-= 20;
- uiDefButC(block,ROW,B_REDR,"Grab", cx,cy,89,19,&br->sculpt_tool,14,SCULPT_TOOL_GRAB,0,0,"Grabs a group of vertices and moves them with the mouse");
- uiDefButC(block,ROW,B_REDR,"Layer", cx+89,cy,89,19,&br->sculpt_tool,14, SCULPT_TOOL_LAYER,0,0,"Adds a layer of depth");
- uiDefButC(block,ROW,B_REDR,"Flatten", cx+178,cy,90,19,&br->sculpt_tool,14, SCULPT_TOOL_FLATTEN,0,0,"Interactively flatten areas of the model");
+ uiDefButF(block,NUMSLI,B_NOP,"Strength: ",cx,cy,w,19,&br->alpha,0,1.0,0,0,"Set brush strength");
cy-= 25;
uiBlockEndAlign(block);
-
+
uiBlockBeginAlign(block);
- uiDefBut(block,LABEL,B_NOP,"Shape",cx,cy,90,19,NULL,0,0,0,0,"");
+
+ uiDefButBitS(block, TOG, BRUSH_AIRBRUSH, B_NOP, "Airbrush", cx,cy,w/3,19, &br->flag,0,0,0,0, "Brush makes changes without waiting for the mouse to move");
+ uiDefButBitS(block, TOG, BRUSH_ANCHORED, B_NOP, "Rake", cx+w/3,cy,w/3,19, &br->flag,0,0,0,0, "");
+ uiDefButBitS(block, TOG, BRUSH_RAKE, B_NOP, "Anchored", cx+w*2.0/3,cy,w/3,19, &br->flag,0,0,0,0, "");
+ cy-= 20;
+ uiDefButBitS(block, TOG, BRUSH_SPACE, B_NOP, "Space", cx,cy,w/3,19, &br->flag,0,0,0,0, "");
+ uiDefButF(block,NUMSLI,B_NOP,"Spacing: ",cx+w/3,cy,w*2.0/3,19,&br->spacing,1.0,500,0,0,"");
cy-= 20;
+ uiBlockEndAlign(block);
+ rect.xmin= cx; rect.xmax= cx + w;
+ rect.ymin= cy - 200; rect.ymax= cy;
uiBlockBeginAlign(block);
+ curvemap_buttons(block, br->curve, (char)0, B_NOP, 0, &rect);
+ uiBlockEndAlign(block);
+
+ uiEndBlock(C, block);
+}
+
+static void sculptmode_draw_interface_tools(Scene *scene, uiBlock *block, unsigned short cx, unsigned short cy)
+{
+ Sculpt *s = scene->toolsettings->sculpt;
+
//XXX if(sd->brush_type != SMOOTH_BRUSH && sd->brush_type != GRAB_BRUSH && sd->brush_type != FLATTEN_BRUSH) {
{
/*uiDefButBitS(block,ROW,B_NOP,"Add",cx,cy,89,19,&br->dir,15.0,1.0,0, 0,"Add depth to model [Shift]");
uiDefButBitS(block,ROW,B_NOP,"Sub",cx+89,cy,89,19,&br->dir,15.0,2.0,0, 0,"Subtract depth from model [Shift]");
*/}
//XXX if(sd->brush_type!=GRAB_BRUSH)
- uiDefButBitS(block, TOG, BRUSH_AIRBRUSH, B_NOP, "Airbrush", cx+178,cy,89,19, &br->flag,0,0,0,0, "Brush makes changes without waiting for the mouse to move");
- cy-= 20;
- uiDefButI(block,NUMSLI,B_NOP,"Size: ",cx,cy,268,19,&br->size,1.0,200.0,0,0,"Set brush radius in pixels");
- cy-= 20;
- //XXX if(sd->brush_type!=GRAB_BRUSH)
- uiDefButF(block,NUMSLI,B_NOP,"Strength: ",cx,cy,268,19,&br->alpha,0,1.0,0,0,"Set brush strength");
- cy-= 25;
- uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefBut( block,LABEL,B_NOP,"Symmetry",cx,cy,90,19,NULL,0,0,0,0,"");
@@ -1199,16 +1272,12 @@ static void view3d_panel_object(const bContext *C, ARegion *ar, short cntrl) //
}
else if(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT)) {
static float hsv[3], old[3]; // used as temp mem for picker
- float *rgb= NULL;
- ToolSettings *settings= scene->toolsettings;
+ Brush **br = current_brush_source(scene);
- if(G.f & G_VERTEXPAINT) rgb= &settings->vpaint->r;
- else if(settings->imapaint.brush) rgb= settings->imapaint.brush->rgb;
-
uiNewPanelTitle(block, "Paint Properties");
- if (rgb)
+ if(br && *br)
/* 'f' is for floating panel */
- uiBlockPickerButtons(block, rgb, hsv, old, hexcol, 'f', B_REDR);
+ uiBlockPickerButtons(block, (*br)->rgb, hsv, old, hexcol, 'f', B_REDR);
}
else if(G.f & G_SCULPTMODE) {
uiNewPanelTitle(block, "Sculpt Properties");
@@ -1492,6 +1561,142 @@ static void view3d_panel_gpencil(const bContext *C, ARegion *ar, short cntrl) //
uiEndBlock(C, block);
}
+static void delete_sketch_armature(bContext *C, void *arg1, void *arg2)
+{
+ BIF_deleteSketch(C);
+}
+
+static void convert_sketch_armature(bContext *C, void *arg1, void *arg2)
+{
+ BIF_convertSketch(C);
+}
+
+static void assign_template_sketch_armature(bContext *C, void *arg1, void *arg2)
+{
+ int index = *(int*)arg1;
+ BIF_setTemplate(C, index);
+}
+static void view3d_panel_bonesketch_spaces(const bContext *C, ARegion *ar, short cntrl)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Scene *scene = CTX_data_scene(C);
+ 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 (obedit && 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= uiBeginBlock(C, ar, "view3d_panel_bonesketch_spaces", UI_EMBOSS, UI_HELV);
+ if(uiNewPanel(C, ar, block, "Bone Sketching", "View3d", 340, 10, 318, height)==0) return;
+ uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL);
+
+ 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, &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, &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, &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, &scene->toolsettings->bone_sketching_convert, 0, 0, 0, 0, subdiv_tooltip[(unsigned char)scene->toolsettings->bone_sketching_convert]);
+
+ switch(scene->toolsettings->bone_sketching_convert)
+ {
+ case SK_CONVERT_CUT_LENGTH:
+ uiDefButF(block, NUM, B_REDR, "Lim:", 70, yco, 140, 19, &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, &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, &scene->toolsettings->skgen_subdivision_number,1, 100, 1, 5, "Number of subdivided bones");
+ yco -= 20;
+ break;
+ case SK_CONVERT_RETARGET:
+ uiDefButC(block, ROW, B_NOP, "No", 70, yco, 40,19, &scene->toolsettings->skgen_retarget_roll, 0, 0, 0, 0, "No special roll treatment");
+ uiDefButC(block, ROW, B_NOP, "View", 110, yco, 50,19, &scene->toolsettings->skgen_retarget_roll, 0, SK_RETARGET_ROLL_VIEW, 0, 0, "Roll bones perpendicular to view");
+ uiDefButC(block, ROW, B_NOP, "Joint", 160, yco, 50,19, &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(C);
+ template_index = BIF_currentTemplate(C);
+
+ but = uiDefButI(block, MENU, B_REDR, BIF_listTemplates(C), 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_NOP, "A:", 10, yco, 66,19, &scene->toolsettings->skgen_retarget_angle_weight, 0, 10, 1, 0, "Angle Weight");
+ uiDefButF(block, NUM, B_NOP, "L:", 76, yco, 67,19, &scene->toolsettings->skgen_retarget_length_weight, 0, 10, 1, 0, "Length Weight");
+ uiDefButF(block, NUM, B_NOP, "D:", 143,yco, 67,19, &scene->toolsettings->skgen_retarget_distance_weight, 0, 10, 1, 0, "Distance Weight");
+ yco -= 20;
+
+ uiDefBut(block, TEX,B_REDR,"S:", 10, yco, 90, 20, scene->toolsettings->skgen_side_string, 0.0, 8.0, 0, 0, "Text to replace &S with");
+ uiDefBut(block, TEX,B_REDR,"N:", 100, yco, 90, 20, scene->toolsettings->skgen_num_string, 0.0, 8.0, 0, 0, "Text to replace &N with");
+ uiDefIconButBitC(block, TOG, SK_RETARGET_AUTONAME, B_NOP, ICON_AUTO,190,yco,20,20, &scene->toolsettings->skgen_retarget_options, 0, 0, 0, 0, "Use Auto Naming");
+ yco -= 20;
+
+ /* auto renaming magic */
+ uiBlockEndAlign(block);
+
+ nb_joints = BIF_nbJointsTemplate(C);
+
+ if (nb_joints == -1)
+ {
+ //XXX
+ //nb_joints = G.totvertsel;
+ }
+
+ bone_name = BIF_nameBoneTemplate(C);
+
+ 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_NOP, "Peel Objects", 10, yco, 200, 20, &scene->snap_flag, 0, 0, 0, 0, "Peel whole objects as one");
+
+ if(yco < 0) uiNewPanelHeight(block, height-yco);
+ }
+}
void view3d_buttons_area_defbuts(const bContext *C, ARegion *ar)
{
@@ -1499,11 +1704,15 @@ void view3d_buttons_area_defbuts(const bContext *C, ARegion *ar)
view3d_panel_object(C, ar, 0);
view3d_panel_properties(C, ar, 0);
view3d_panel_background(C, ar, 0);
+ if(G.f & (G_SCULPTMODE|G_TEXTUREPAINT|G_VERTEXPAINT|G_WEIGHTPAINT))
+ view3d_panel_brush(C, ar, 0);
// XXX view3d_panel_preview(C, ar, 0);
view3d_panel_transform_spaces(C, ar, 0);
if(0)
view3d_panel_gpencil(C, ar, 0);
+ 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..00843a58ba7 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);
+ BDR_drawSketch(C);
+
ED_region_pixelspace(ar);
/* Draw Sculpt Mode brush XXX (removed) */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 78309a40f94..b4b35be3ef3 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -549,6 +549,7 @@ void VIEW3D_OT_viewrotate(wmOperatorType *ot)
/* identifiers */
ot->name= "Rotate view";
+ ot->description = "Rotate the view.";
ot->idname= "VIEW3D_OT_viewrotate";
/* api callbacks */
@@ -630,7 +631,8 @@ void VIEW3D_OT_viewmove(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Rotate view";
+ ot->name= "Move view";
+ ot->description = "Move the view.";
ot->idname= "VIEW3D_OT_viewmove";
/* api callbacks */
@@ -824,11 +826,12 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
-void VIEW3D_OT_viewzoom(wmOperatorType *ot)
+void VIEW3D_OT_zoom(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Zoom view";
- ot->idname= "VIEW3D_OT_viewzoom";
+ ot->description = "Zoom in/out in the view.";
+ ot->idname= "VIEW3D_OT_zoom";
/* api callbacks */
ot->invoke= viewzoom_invoke;
@@ -910,6 +913,7 @@ void VIEW3D_OT_viewhome(wmOperatorType *ot)
{
/* identifiers */
ot->name= "View home";
+ ot->description = "View all objects in scene.";
ot->idname= "VIEW3D_OT_viewhome";
/* api callbacks */
@@ -1048,6 +1052,7 @@ void VIEW3D_OT_viewcenter(wmOperatorType *ot)
/* identifiers */
ot->name= "View center";
+ ot->description = "Move the view to the selection center.";
ot->idname= "VIEW3D_OT_viewcenter";
/* api callbacks */
@@ -1118,6 +1123,7 @@ void VIEW3D_OT_render_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Render Border";
+ ot->description = "Set the boundries of the border render and enables border render .";
ot->idname= "VIEW3D_OT_render_border";
/* api callbacks */
@@ -1286,12 +1292,13 @@ static int view3d_border_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event
return OPERATOR_PASS_THROUGH;
}
-void VIEW3D_OT_border_zoom(wmOperatorType *ot)
+void VIEW3D_OT_zoom_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Border Zoom";
- ot->idname= "VIEW3D_OT_border_zoom";
+ ot->description = "Zoom in the view to the nearest object contained in the border.";
+ ot->idname= "VIEW3D_OT_zoom_border";
/* api callbacks */
ot->invoke= view3d_border_zoom_invoke;
@@ -1458,6 +1465,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot)
{
/* identifiers */
ot->name= "View numpad";
+ ot->description = "Set the view.";
ot->idname= "VIEW3D_OT_viewnumpad";
/* api callbacks */
@@ -1526,6 +1534,7 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot)
{
/* identifiers */
ot->name= "View Orbit";
+ ot->description = "Orbit the view.";
ot->idname= "VIEW3D_OT_view_orbit";
/* api callbacks */
@@ -1575,6 +1584,7 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot)
{
/* identifiers */
ot->name= "View Pan";
+ ot->description = "Pan the view.";
ot->idname= "VIEW3D_OT_view_pan";
/* api callbacks */
@@ -1606,6 +1616,7 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot)
{
/* identifiers */
ot->name= "View persp/ortho";
+ ot->description = "Switch the current view from perspective/orthographic.";
ot->idname= "VIEW3D_OT_view_persportho";
/* api callbacks */
@@ -1704,6 +1715,7 @@ void VIEW3D_OT_clipping(wmOperatorType *ot)
/* identifiers */
ot->name= "Clipping Border";
+ ot->description = "Set the view clipping border.";
ot->idname= "VIEW3D_OT_clipping";
/* api callbacks */
@@ -1757,6 +1769,7 @@ void VIEW3D_OT_drawtype(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Change draw type";
+ ot->description = "Change the draw type of the view.";
ot->idname= "VIEW3D_OT_drawtype";
/* api callbacks */
@@ -1833,6 +1846,7 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
/* identifiers */
ot->name= "Set 3D Cursor";
+ ot->description = "Set the location of the 3D cursor.";
ot->idname= "VIEW3D_OT_cursor3d";
/* api callbacks */
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index a7dd419f672..28db2f45094 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 ************* */
@@ -633,8 +634,8 @@ static void view3d_view_viewnavmenu(bContext *C, uiMenuItem *head, void *arg_unu
uiMenuSeparator(head);
- uiMenuItemFloatO(head, "Zoom in", 0, "VIEW3D_OT_viewzoom", "delta", 1.0f);
- uiMenuItemFloatO(head, "Zoom out", 0, "VIEW3D_OT_viewzoom", "delta", -1.0f);
+ uiMenuItemFloatO(head, "Zoom in", 0, "VIEW3D_OT_zoom", "delta", 1.0f);
+ uiMenuItemFloatO(head, "Zoom out", 0, "VIEW3D_OT_zoom", "delta", -1.0f);
}
static void view3d_view_alignviewmenu(bContext *C, uiMenuItem *head, void *arg_unused)
@@ -684,7 +685,7 @@ static void view3d_viewmenu(bContext *C, uiMenuItem *head, void *arg_unused)
uiMenuContext(head, WM_OP_INVOKE_REGION_WIN);
uiMenuItemO(head, 0, "VIEW3D_OT_clipping");
- uiMenuItemO(head, 0, "VIEW3D_OT_border_zoom");
+ uiMenuItemO(head, 0, "VIEW3D_OT_zoom_border");
uiMenuSeparator(head);
@@ -1034,11 +1035,11 @@ static uiBlock *view3d_select_objectmenu(bContext *C, ARegion *ar, void *arg_unu
uiDefIconTextBlockBut(block, view3d_select_object_linkedmenu, NULL, ICON_RIGHTARROW_THIN, "Linked", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, view3d_select_object_groupedmenu, NULL, ICON_RIGHTARROW_THIN, "Grouped", 0, yco-=20, 120, 19, "");
#endif
- uiDefMenuButO(block, "VIEW3D_OT_borderselect", "Border Select");
+ uiDefMenuButO(block, "VIEW3D_OT_select_border", "Border Select");
uiDefMenuSep(block);
- uiDefMenuButO(block, "OBJECT_OT_de_select_all", "Select/Deselect All");
+ uiDefMenuButO(block, "OBJECT_OT_select_all_toggle", "Select/Deselect All");
uiDefMenuButO(block, "OBJECT_OT_select_invert", "Inverse");
uiDefMenuButO(block, "OBJECT_OT_select_random", "Random");
uiDefMenuButO(block, "OBJECT_OT_select_by_layer", "Select All by Layer");
@@ -1211,13 +1212,13 @@ static void view3d_select_curvemenu(bContext *C, uiMenuItem *head, void *arg_unu
{
Object *obedit= CTX_data_edit_object(C);
- uiMenuItemO(head, 0, "VIEW3D_OT_borderselect");
- uiMenuItemO(head, 0, "VIEW3D_OT_circle_select");
+ uiMenuItemO(head, 0, "VIEW3D_OT_select_border");
+ uiMenuItemO(head, 0, "VIEW3D_OT_select_circle");
uiMenuSeparator(head);
- uiMenuItemO(head, 0, "CURVE_OT_de_select_all");
- uiMenuItemO(head, 0, "CURVE_OT_select_inverse");
+ uiMenuItemO(head, 0, "CURVE_OT_select_all_toggle");
+ uiMenuItemO(head, 0, "CURVE_OT_select_invert");
uiMenuItemO(head, 0, "CURVE_OT_select_random"); // Random...
uiMenuItemO(head, 0, "CURVE_OT_select_every_nth"); // Every Nth..
@@ -3293,14 +3294,14 @@ static void view3d_edit_curve_controlpointsmenu(bContext *C, uiMenuItem *head, v
if(obedit->type == OB_CURVE) {
uiMenuItemEnumO(head, "", 0, "TFM_OT_transform", "mode", TFM_TILT);
- uiMenuItemO(head, 0, "CURVE_OT_clear_tilt");
+ uiMenuItemO(head, 0, "CURVE_OT_tilt_clear");
uiMenuItemO(head, 0, "CURVE_OT_separate");
uiMenuSeparator(head);
- uiMenuItemEnumO(head, "", 0, "CURVE_OT_set_handle_type", "type", 1);
- uiMenuItemEnumO(head, "", 0, "CURVE_OT_set_handle_type", "type", 3);
- uiMenuItemEnumO(head, "", 0, "CURVE_OT_set_handle_type", "type", 2);
+ uiMenuItemEnumO(head, "", 0, "CURVE_OT_handle_type_set", "type", 1);
+ uiMenuItemEnumO(head, "", 0, "CURVE_OT_handle_type_set", "type", 3);
+ uiMenuItemEnumO(head, "", 0, "CURVE_OT_handle_type_set", "type", 2);
uiMenuSeparator(head);
}
@@ -3350,7 +3351,7 @@ static void view3d_edit_curvemenu(bContext *C, uiMenuItem *head, void *arg_unuse
uiMenuItemO(head, 0, "CURVE_OT_duplicate");
uiMenuItemO(head, 0, "CURVE_OT_separate");
uiMenuItemO(head, 0, "CURVE_OT_make_segment");
- uiMenuItemO(head, 0, "CURVE_OT_toggle_cyclic");
+ uiMenuItemO(head, 0, "CURVE_OT_cyclic_toggle");
uiMenuItemO(head, 0, "CURVE_OT_delete"); // Delete...
uiMenuSeparator(head);
@@ -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, "");
@@ -4696,11 +4701,11 @@ static void view3d_select_particlemenu(bContext *C, uiMenuItem *head, void *arg_
{
Scene *scene= CTX_data_scene(C);
- uiMenuItemO(head, 0, "VIEW3D_OT_borderselect");
+ uiMenuItemO(head, 0, "VIEW3D_OT_select_border");
uiMenuSeparator(head);
- uiMenuItemO(head, 0, "PARTICLE_OT_de_select_all");
+ uiMenuItemO(head, 0, "PARTICLE_OT_select_all_toggle");
uiMenuItemO(head, 0, "PARTICLE_OT_select_linked");
if(scene->selectmode & SCE_SELECT_POINT) {
@@ -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;
}
@@ -4880,7 +4886,7 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
int bit, ctrl= win->eventstate->ctrl, shift= win->eventstate->shift;
if(obedit && obedit->type==OB_MESH) {
- em= ((Mesh *)obedit->data)->edit_mesh;
+ em= EM_GetEditMesh((Mesh *)obedit->data);
}
/* watch it: if sa->win does not exist, check that when calling direct drawing routines */
@@ -5111,6 +5117,8 @@ static void do_view3d_header_buttons(bContext *C, void *arg, int event)
}
break;
}
+
+ EM_EndEditMesh(obedit->data, em);
}
static void view3d_header_pulldowns(const bContext *C, uiBlock *block, Object *ob, int *xcoord, int yco)
@@ -5475,7 +5483,7 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
/* selection modus */
if(obedit && (obedit->type == OB_MESH)) {
- EditMesh *em= ((Mesh *)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh *)obedit->data);
uiBlockBeginAlign(block);
uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, xco,yco,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode (Ctrl Tab 1)");
@@ -5491,6 +5499,8 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
}
uiBlockEndAlign(block);
xco+= 20;
+
+ EM_EndEditMesh(obedit->data, em);
}
else if(G.f & G_PARTICLEEDIT) {
uiBlockBeginAlign(block);
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 6e26a9a7ad8..ae77b4293bf 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -62,7 +62,7 @@ void view3d_operatortypes(void);
void view3d_keymap(struct wmWindowManager *wm);
/* view3d_edit.c */
-void VIEW3D_OT_viewzoom(struct wmOperatorType *ot);
+void VIEW3D_OT_zoom(struct wmOperatorType *ot);
void VIEW3D_OT_viewmove(struct wmOperatorType *ot);
void VIEW3D_OT_viewrotate(struct wmOperatorType *ot);
void VIEW3D_OT_viewhome(struct wmOperatorType *ot);
@@ -74,7 +74,7 @@ void VIEW3D_OT_view_orbit(struct wmOperatorType *ot);
void VIEW3D_OT_clipping(struct wmOperatorType *ot);
void VIEW3D_OT_cursor3d(struct wmOperatorType *ot);
void VIEW3D_OT_render_border(struct wmOperatorType *ot);
-void VIEW3D_OT_border_zoom(struct wmOperatorType *ot);
+void VIEW3D_OT_zoom_border(struct wmOperatorType *ot);
void VIEW3D_OT_drawtype(struct wmOperatorType *ot);
void VIEW3D_OT_editmesh_face_toolbox(struct wmOperatorType *ot);
@@ -109,9 +109,9 @@ void view3d_update_depths(struct ARegion *ar, View3D *v3d);
/* view3d_select.c */
void VIEW3D_OT_select(struct wmOperatorType *ot);
void VIEW3D_OT_select_extend(struct wmOperatorType *ot);
-void VIEW3D_OT_circle_select(struct wmOperatorType *ot);
-void VIEW3D_OT_borderselect(struct wmOperatorType *ot);
-void VIEW3D_OT_lasso_select(struct wmOperatorType *ot);
+void VIEW3D_OT_select_circle(struct wmOperatorType *ot);
+void VIEW3D_OT_select_border(struct wmOperatorType *ot);
+void VIEW3D_OT_select_lasso(struct wmOperatorType *ot);
/* view3d_view.c */
void VIEW3D_OT_smoothview(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 7ff6e6b88a8..1cda1b9e4c8 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -65,7 +65,7 @@ void view3d_operatortypes(void)
{
WM_operatortype_append(VIEW3D_OT_viewrotate);
WM_operatortype_append(VIEW3D_OT_viewmove);
- WM_operatortype_append(VIEW3D_OT_viewzoom);
+ WM_operatortype_append(VIEW3D_OT_zoom);
WM_operatortype_append(VIEW3D_OT_viewhome);
WM_operatortype_append(VIEW3D_OT_viewnumpad);
WM_operatortype_append(VIEW3D_OT_view_orbit);
@@ -73,14 +73,14 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_view_persportho);
WM_operatortype_append(VIEW3D_OT_viewcenter);
WM_operatortype_append(VIEW3D_OT_select);
- WM_operatortype_append(VIEW3D_OT_borderselect);
+ WM_operatortype_append(VIEW3D_OT_select_border);
WM_operatortype_append(VIEW3D_OT_clipping);
- WM_operatortype_append(VIEW3D_OT_circle_select);
+ WM_operatortype_append(VIEW3D_OT_select_circle);
WM_operatortype_append(VIEW3D_OT_smoothview);
WM_operatortype_append(VIEW3D_OT_render_border);
- WM_operatortype_append(VIEW3D_OT_border_zoom);
+ WM_operatortype_append(VIEW3D_OT_zoom_border);
WM_operatortype_append(VIEW3D_OT_cursor3d);
- WM_operatortype_append(VIEW3D_OT_lasso_select);
+ WM_operatortype_append(VIEW3D_OT_select_lasso);
WM_operatortype_append(VIEW3D_OT_setcameratoview);
WM_operatortype_append(VIEW3D_OT_drawtype);
WM_operatortype_append(VIEW3D_OT_editmesh_face_toolbox);
@@ -118,24 +118,33 @@ void view3d_keymap(wmWindowManager *wm)
WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PAINT_OT_set_clone_cursor", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "PAINT_OT_clone_cursor_set", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
-
+
+ /* sketch poll checks mode */
+ WM_keymap_add_item(keymap, "SKETCH_OT_gesture", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, 0, 0);
+ km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
+ RNA_boolean_set(km->ptr, "snap", 1);
+ WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0);
+ km = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0);
+ RNA_boolean_set(km->ptr, "snap", 1);
+
WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_viewrotate", MIDDLEMOUSE, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_viewmove", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_verify_item(keymap, "VIEW3D_OT_viewzoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_viewcenter", PADPERIOD, KM_PRESS, 0, 0);
WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0);
- RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewzoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
- RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewzoom", PADMINUS, KM_PRESS, 0, 0)->ptr, "delta", -1);
- RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewzoom", WHEELINMOUSE, KM_PRESS, 0, 0)->ptr, "delta", 1);
- RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewzoom", WHEELOUTMOUSE, KM_PRESS, 0, 0)->ptr, "delta", -1);
+ RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1);
+ RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADMINUS, KM_PRESS, 0, 0)->ptr, "delta", -1);
+ RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", WHEELINMOUSE, KM_PRESS, 0, 0)->ptr, "delta", 1);
+ RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", WHEELOUTMOUSE, KM_PRESS, 0, 0)->ptr, "delta", -1);
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewhome", HOMEKEY, KM_PRESS, 0, 0)->ptr, "center", 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewhome", CKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "center", 1);
@@ -189,16 +198,16 @@ void view3d_keymap(wmWindowManager *wm)
/* selection*/
WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1);
- WM_keymap_add_item(keymap, "VIEW3D_OT_borderselect", BKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_lasso_select", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
- RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_lasso_select", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "type", 1);
- WM_keymap_add_item(keymap, "VIEW3D_OT_circle_select", CKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "type", 1);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_clipping", BKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_border_zoom", BKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "VIEW3D_OT_set_camera_to_view", PAD0, KM_PRESS, KM_ALT|KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT|KM_CTRL, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_snap_menu", SKEY, KM_PRESS, KM_SHIFT, 0);
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index b6098e52a89..d03586da2d5 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -754,10 +754,10 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op)
return OPERATOR_PASS_THROUGH;
}
-void VIEW3D_OT_lasso_select(wmOperatorType *ot)
+void VIEW3D_OT_select_lasso(wmOperatorType *ot)
{
ot->name= "Lasso Select";
- ot->idname= "VIEW3D_OT_lasso_select";
+ ot->idname= "VIEW3D_OT_select_lasso";
ot->invoke= WM_gesture_lasso_invoke;
ot->modal= WM_gesture_lasso_modal;
@@ -1532,11 +1532,11 @@ static EnumPropertyItem prop_select_types[] = {
};
/* ****** Border Select ****** */
-void VIEW3D_OT_borderselect(wmOperatorType *ot)
+void VIEW3D_OT_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Border Select";
- ot->idname= "VIEW3D_OT_borderselect";
+ ot->idname= "VIEW3D_OT_select_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
@@ -1823,10 +1823,10 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void VIEW3D_OT_circle_select(wmOperatorType *ot)
+void VIEW3D_OT_select_circle(wmOperatorType *ot)
{
ot->name= "Circle Select";
- ot->idname= "VIEW3D_OT_circle_select";
+ ot->idname= "VIEW3D_OT_select_circle";
ot->invoke= WM_gesture_circle_invoke;
ot->modal= WM_gesture_circle_modal;
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index b1bd39a66da..2aade74dcca 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -70,6 +70,7 @@
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_view3d.h"
+#include "ED_armature.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -410,7 +411,7 @@ void VIEW3D_OT_setcameratoview(wmOperatorType *ot)
/* identifiers */
ot->name= "Align Camera To View";
- ot->idname= "VIEW3D_OT_set_camera_to_view";
+ ot->idname= "VIEW3D_OT_camera_to_view";
/* api callbacks */
ot->exec= view3d_setcameratoview_exec;
@@ -802,7 +803,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 +1142,11 @@ 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)) {
+ /* if not drawing sketch, draw bones */
+ if(!BDR_drawSketchNames(vc)) {
+ draw_object(scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
+ }
}
else {
Base *base;
@@ -1236,7 +1261,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.c b/source/blender/editors/transform/transform.c
index e7749e6eb3a..091b35c7361 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -163,7 +163,7 @@ static void helpline(TransInfo *t, float *vec)
void setTransformViewMatrices(TransInfo *t)
{
- if(t->spacetype==SPACE_VIEW3D) {
+ if(t->spacetype==SPACE_VIEW3D && t->ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = t->ar->regiondata;
Mat4CpyMat4(t->viewmat, rv3d->viewmat);
@@ -186,7 +186,10 @@ void setTransformViewMatrices(TransInfo *t)
void convertViewVec(TransInfo *t, float *vec, short dx, short dy)
{
if (t->spacetype==SPACE_VIEW3D) {
- window_to_3d_delta(t->ar, vec, dx, dy);
+ if (t->ar->regiontype == RGN_TYPE_WINDOW)
+ {
+ window_to_3d_delta(t->ar, vec, dx, dy);
+ }
}
else if(t->spacetype==SPACE_IMAGE) {
View2D *v2d = t->view;
@@ -764,15 +767,15 @@ void transformEvent(TransInfo *t, wmEvent *event)
}
break;
case OKEY:
- if (t->flag & T_PROP_EDIT && event->keymodifier == KM_SHIFT) {
- t->scene->prop_mode = (t->scene->prop_mode+1)%6;
+ if (t->flag & T_PROP_EDIT && event->shift) {
+ t->prop_mode = (t->prop_mode + 1) % 6;
calculatePropRatio(t);
- t->redraw= 1;
+ t->redraw = 1;
}
break;
case PADPLUSKEY:
- if(event->keymodifier & KM_ALT && t->flag & T_PROP_EDIT) {
- t->propsize*= 1.1f;
+ if(event->alt && t->flag & T_PROP_EDIT) {
+ t->prop_size *= 1.1f;
calculatePropRatio(t);
}
t->redraw= 1;
@@ -783,15 +786,15 @@ void transformEvent(TransInfo *t, wmEvent *event)
transform_autoik_update(t, 1);
}
else if(t->flag & T_PROP_EDIT) {
- t->propsize*= 1.1f;
+ t->prop_size*= 1.1f;
calculatePropRatio(t);
}
else view_editmove(event->type);
t->redraw= 1;
break;
case PADMINUS:
- if(event->keymodifier & KM_ALT && t->flag & T_PROP_EDIT) {
- t->propsize*= 0.90909090f;
+ if(event->alt && t->flag & T_PROP_EDIT) {
+ t->prop_size*= 0.90909090f;
calculatePropRatio(t);
}
t->redraw= 1;
@@ -802,7 +805,7 @@ void transformEvent(TransInfo *t, wmEvent *event)
transform_autoik_update(t, -1);
}
else if (t->flag & T_PROP_EDIT) {
- t->propsize*= 0.90909090f;
+ t->prop_size*= 0.90909090f;
calculatePropRatio(t);
}
else view_editmove(event->type);
@@ -903,7 +906,7 @@ int calculateTransformCenter(bContext *C, wmEvent *event, int centerMode, float
t->mode = TFM_DUMMY;
- initTransInfo(C, t, event); // internal data, mouse, vectors
+ initTransInfo(C, t, NULL, event); // internal data, mouse, vectors
createTransData(C, t); // make TransData structs from selection
@@ -935,29 +938,90 @@ void drawTransform(const struct bContext *C, struct ARegion *ar, void *arg)
{
TransInfo *t = arg;
- drawConstraint(t);
- drawPropCircle(t);
- drawSnapping(t);
+ drawConstraint(C, t);
+ drawPropCircle(C, t);
+ drawSnapping(C, t);
}
void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
{
- short twmode= (t->spacetype==SPACE_VIEW3D)? ((View3D*)t->view)->twmode: V3D_MANIP_GLOBAL;
+ Scene *sce = CTX_data_scene(C);
+ int constraint_axis[3] = {0, 0, 0};
+ int proportional = 0;
- RNA_int_set(op->ptr, "mode", t->mode);
- RNA_int_set(op->ptr, "options", t->options);
- RNA_float_set_array(op->ptr, "values", t->values);
+ if (t->flag & T_AUTOVALUES)
+ {
+ RNA_float_set_array(op->ptr, "value", t->auto_values);
+ }
+ else
+ {
+ RNA_float_set_array(op->ptr, "value", t->values);
+ }
+
+ /* XXX convert stupid flag to enum */
+ switch(t->flag & (T_PROP_EDIT|T_PROP_CONNECTED))
+ {
+ case (T_PROP_EDIT|T_PROP_CONNECTED):
+ proportional = 2;
+ break;
+ case T_PROP_EDIT:
+ proportional = 1;
+ break;
+ default:
+ proportional = 0;
+ }
+
+ if (RNA_struct_find_property(op->ptr, "proportional"))
+ {
+ RNA_enum_set(op->ptr, "proportional", proportional);
+ RNA_enum_set(op->ptr, "proportional_editing_falloff", t->prop_mode);
+ RNA_float_set(op->ptr, "proportional_size", t->prop_size);
+ }
+ if (RNA_struct_find_property(op->ptr, "mirror"))
+ {
+ RNA_boolean_set(op->ptr, "mirror", t->flag & T_MIRROR);
+ }
- RNA_int_set(op->ptr, "constraint_mode", t->con.mode);
- RNA_int_set(op->ptr, "constraint_orientation", twmode);
- RNA_float_set_array(op->ptr, "constraint_matrix", (float*)t->con.mtx);
+ if (RNA_struct_find_property(op->ptr, "constraint_mode"))
+ {
+ RNA_int_set(op->ptr, "constraint_mode", t->con.mode);
+ RNA_int_set(op->ptr, "constraint_orientation", t->current_orientation);
+
+ if (t->con.mode & CON_APPLY)
+ {
+ if (t->con.mode & CON_AXIS0) {
+ constraint_axis[0] = 1;
+ }
+ if (t->con.mode & CON_AXIS1) {
+ constraint_axis[1] = 1;
+ }
+ if (t->con.mode & CON_AXIS2) {
+ constraint_axis[2] = 1;
+ }
+ }
+
+ RNA_boolean_set_array(op->ptr, "constraint_axis", constraint_axis);
+ }
+
+ // XXX If modal, save settings back in scene
+ if (t->flag & T_MODAL)
+ {
+ sce->prop_mode = t->prop_mode;
+ sce->proportional = proportional;
+
+ if(t->spacetype == SPACE_VIEW3D)
+ {
+ View3D *v3d = t->view;
+
+ v3d->twmode = t->current_orientation;
+ }
+ }
}
-void initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
+int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int mode)
{
- int mode = RNA_int_get(op->ptr, "mode");
- int options = RNA_int_get(op->ptr, "options");
+ int options = 0;
/* added initialize, for external calls to set stuff in TransInfo, like undo string */
@@ -967,15 +1031,21 @@ void initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
t->mode = mode;
- initTransInfo(C, t, event); // internal data, mouse, vectors
-
+ if (!initTransInfo(C, t, op, event)) // internal data, mouse, vectors
+ {
+ return 0;
+ }
+
initTransformOrientation(C, t);
if(t->spacetype == SPACE_VIEW3D)
{
- RegionView3D *rv3d = t->ar->regiondata;
//calc_manipulator_stats(curarea);
- Mat3CpyMat4(t->spacemtx, rv3d->twmat);
+ if (t->ar->regiontype == RGN_TYPE_WINDOW)
+ {
+ RegionView3D *rv3d = t->ar->regiondata;
+ Mat3CpyMat4(t->spacemtx, rv3d->twmat);
+ }
Mat3Ortho(t->spacemtx);
t->draw_handle = ED_region_draw_cb_activate(t->ar->type, drawTransform, t, REGION_DRAW_POST);
@@ -989,13 +1059,13 @@ void initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
createTransData(C, t); // make TransData structs from selection
- initSnapping(t); // Initialize snapping data AFTER mode flags
-
if (t->total == 0) {
postTrans(t);
- return;
+ return 0;
}
+ initSnapping(t, op); // Initialize snapping data AFTER mode flags
+
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
/* EVIL2: we gave as argument also texture space context bit... was cleared */
/* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */
@@ -1094,27 +1164,43 @@ void initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
initAlign(t);
break;
}
-
+
/* overwrite initial values if operator supplied a non-null vector */
- if (RNA_property_is_set(op->ptr, "values"))
+ if (RNA_property_is_set(op->ptr, "value"))
{
float values[4];
- RNA_float_get_array(op->ptr, "values", values);
+ RNA_float_get_array(op->ptr, "value", values);
QUATCOPY(t->values, values);
+ QUATCOPY(t->auto_values, values);
+ t->flag |= T_AUTOVALUES;
}
/* Constraint init from operator */
+ if (RNA_struct_find_property(op->ptr, "constraint_axis") && RNA_property_is_set(op->ptr, "constraint_axis"))
{
- t->con.mode = RNA_int_get(op->ptr, "constraint_mode");
-
- if (t->con.mode & CON_APPLY)
+ int constraint_axis[3];
+
+ RNA_boolean_get_array(op->ptr, "constraint_axis", constraint_axis);
+
+ if (constraint_axis[0] || constraint_axis[1] || constraint_axis[2])
{
- RNA_float_get_array(op->ptr, "constraint_matrix", (float*)t->spacemtx);
-
+ t->con.mode |= CON_APPLY;
+
+ if (constraint_axis[0]) {
+ t->con.mode |= CON_AXIS0;
+ }
+ if (constraint_axis[1]) {
+ t->con.mode |= CON_AXIS1;
+ }
+ if (constraint_axis[2]) {
+ t->con.mode |= CON_AXIS2;
+ }
+
setUserConstraint(t, t->con.mode, "%s");
}
-
}
+
+ return 1;
}
void transformApply(bContext *C, TransInfo *t)
@@ -2227,6 +2313,13 @@ int Resize(TransInfo *t, short mval[2])
applySnapping(t, size);
+ if (t->flag & T_AUTOVALUES)
+ {
+ VECCOPY(size, t->auto_values);
+ }
+
+ VECCOPY(t->values, size);
+
SizeToMat3(size, mat);
if (t->con.applySize) {
@@ -2996,8 +3089,6 @@ int Translation(TransInfo *t, short mval[2])
ED_area_headerprint(t->sa, str);
- drawSnapping(t);
-
return 1;
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index ddf10c213af..dfbc22b1e14 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -80,8 +80,9 @@ typedef struct NumInput {
typedef struct TransSnap {
short modePoint;
short modeTarget;
- int mode;
- int status;
+ short mode;
+ short align;
+ short status;
float snapPoint[3];
float snapTarget[3];
float snapNormal[3];
@@ -214,7 +215,7 @@ typedef struct TransInfo {
NDofInput ndof; /* ndof input */
MouseInput mouse; /* mouse input */
char redraw; /* redraw flag */
- float propsize; /* proportional circle radius */
+ float prop_size; /* proportional circle radius */
char proptext[20]; /* proportional falloff text */
float center[3]; /* center of transformation */
int center2d[2]; /* center in screen coordinates */
@@ -245,7 +246,12 @@ typedef struct TransInfo {
/*************** NEW STUFF *********************/
+ short current_orientation;
+
+ short prop_mode;
+
float values[4];
+ float auto_values[4];
void *view;
struct ScrArea *sa;
struct ARegion *ar;
@@ -303,6 +309,13 @@ typedef struct TransInfo {
/* auto-ik is on */
#define T_AUTOIK (1 << 18)
+#define T_MIRROR (1 << 19)
+
+#define T_AUTOVALUES (1 << 20)
+
+ /* to specificy if we save back settings at the end */
+#define T_MODAL (1 << 21)
+
/* TransInfo->modifiers */
#define MOD_CONSTRAINT_SELECT 0x01
#define MOD_PRECISION 0x02
@@ -335,11 +348,13 @@ typedef struct TransInfo {
#define TD_BEZTRIPLE (1 << 12) /* if this is a bez triple, we need to restore the handles, if this is set transdata->misc.hdata needs freeing */
#define TD_NO_LOC (1 << 13) /* when this is set, don't apply translation changes to this element */
#define TD_NOTIMESNAP (1 << 14) /* for Graph Editor autosnap, indicates that point should not undergo autosnapping */
+#define TD_INTVALUES (1 << 15) /* for Graph Editor - curves that can only have int-values need their keyframes tagged with this */
/* transsnap->status */
#define SNAP_ON 1
-#define TARGET_INIT 2
-#define POINT_INIT 4
+#define SNAP_FORCED 2
+#define TARGET_INIT 4
+#define POINT_INIT 8
/* transsnap->modePoint */
#define SNAP_GRID 0
@@ -354,7 +369,7 @@ typedef struct TransInfo {
void TFM_OT_transform(struct wmOperatorType *ot);
-void initTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op, struct wmEvent *event);
+int initTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op, struct wmEvent *event, int mode);
void saveTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op);
void transformEvent(TransInfo *t, struct wmEvent *event);
void transformApply(struct bContext *C, TransInfo *t);
@@ -441,7 +456,7 @@ void initAlign(TransInfo *t);
int Align(TransInfo *t, short mval[2]);
-void drawPropCircle(TransInfo *t);
+void drawPropCircle(const struct bContext *C, TransInfo *t);
/*********************** transform_conversions.c ********** */
struct ListBase;
@@ -475,7 +490,7 @@ void autokeyframe_pose_cb_func(struct Scene *scene, struct View3D *v3d, struct O
/*********************** Constraints *****************************/
-void drawConstraint(TransInfo *t);
+void drawConstraint(const struct bContext *C, TransInfo *t);
void getConstraintMatrix(TransInfo *t);
void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]);
@@ -509,11 +524,11 @@ typedef enum {
void snapGrid(TransInfo *t, float *val);
void snapGridAction(TransInfo *t, float *val, GearsType action);
-void initSnapping(struct TransInfo *t);
+void initSnapping(struct TransInfo *t, struct wmOperator *op);
void applySnapping(TransInfo *t, float *vec);
void resetSnapping(TransInfo *t);
int handleSnapping(TransInfo *t, struct wmEvent *event);
-void drawSnapping(TransInfo *t);
+void drawSnapping(const struct bContext *C, TransInfo *t);
int usingSnappingNormal(TransInfo *t);
int validSnappingNormal(TransInfo *t);
@@ -539,7 +554,7 @@ void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, short mval[2],
/*********************** Generics ********************************/
-void initTransInfo(struct bContext *C, TransInfo *t, struct wmEvent *event);
+int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, struct wmEvent *event);
void postTrans (TransInfo *t);
void resetTransRestrictions(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 26d240be3fc..0064317b57a 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -90,6 +90,28 @@
static void drawObjectConstraint(TransInfo *t);
/* ************************** CONSTRAINTS ************************* */
+void constraintAutoValues(TransInfo *t, float vec[3])
+{
+ int mode = t->con.mode;
+ if (mode & CON_APPLY)
+ {
+ float nval = (t->flag & T_NULL_ONE)?1.0f:0.0f;
+
+ if ((mode & CON_AXIS0) == 0)
+ {
+ vec[0] = nval;
+ }
+ if ((mode & CON_AXIS1) == 0)
+ {
+ vec[1] = nval;
+ }
+ if ((mode & CON_AXIS2) == 0)
+ {
+ vec[2] = nval;
+ }
+ }
+}
+
void constraintNumInput(TransInfo *t, float vec[3])
{
int mode = t->con.mode;
@@ -99,6 +121,8 @@ void constraintNumInput(TransInfo *t, float vec[3])
if (getConstraintSpaceDimension(t) == 2) {
int axis = mode & (CON_AXIS0|CON_AXIS1|CON_AXIS2);
if (axis == (CON_AXIS0|CON_AXIS1)) {
+ vec[0] = vec[0];
+ vec[1] = vec[1];
vec[2] = nval;
}
else if (axis == (CON_AXIS1|CON_AXIS2)) {
@@ -107,12 +131,14 @@ void constraintNumInput(TransInfo *t, float vec[3])
vec[0] = nval;
}
else if (axis == (CON_AXIS0|CON_AXIS2)) {
+ vec[0] = vec[0];
vec[2] = vec[1];
vec[1] = nval;
}
}
else if (getConstraintSpaceDimension(t) == 1) {
if (mode & CON_AXIS0) {
+ vec[0] = vec[0];
vec[1] = nval;
vec[2] = nval;
}
@@ -152,6 +178,13 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) {
applyNumInput(&t->num, vec);
constraintNumInput(t, vec);
}
+
+ /* autovalues is operator param, use that directly but not if snapping is forced */
+ if (t->flag & T_AUTOVALUES && (t->tsnap.status & SNAP_FORCED) == 0)
+ {
+ VECCOPY(vec, t->auto_values);
+ constraintAutoValues(t, vec);
+ }
if (t->con.mode & CON_AXIS0) {
pvec[i++] = vec[0];
@@ -522,9 +555,9 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) {
*/
void setUserConstraint(TransInfo *t, int mode, const char ftext[]) {
char text[40];
- short twmode= (t->spacetype==SPACE_VIEW3D)? ((View3D*)t->view)->twmode: V3D_MANIP_GLOBAL;
+ //short twmode= (t->spacetype==SPACE_VIEW3D)? ((View3D*)t->view)->twmode: V3D_MANIP_GLOBAL;
- switch(twmode) {
+ switch(t->current_orientation) {
case V3D_MANIP_GLOBAL:
{
float mtx[3][3];
@@ -678,7 +711,7 @@ void BIF_setDualAxisConstraint(float vec1[3], float vec2[3], char *text) {
/*----------------- DRAWING CONSTRAINTS -------------------*/
-void drawConstraint(TransInfo *t)
+void drawConstraint(const struct bContext *C, TransInfo *t)
{
TransCon *tc = &(t->con);
@@ -737,17 +770,16 @@ void drawConstraint(TransInfo *t)
}
/* called from drawview.c, as an extra per-window draw option */
-void drawPropCircle(TransInfo *t)
+void drawPropCircle(const struct bContext *C, TransInfo *t)
{
if (t->flag & T_PROP_EDIT) {
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
float tmat[4][4], imat[4][4];
UI_ThemeColor(TH_GRID);
- if(t->spacetype == SPACE_VIEW3D)
+ if(t->spacetype == SPACE_VIEW3D && rv3d != NULL)
{
- RegionView3D *rv3d = t->ar->regiondata;
-
Mat4CpyMat4(tmat, rv3d->viewmat);
Mat4Invert(imat, tmat);
}
@@ -772,7 +804,7 @@ void drawPropCircle(TransInfo *t)
}
set_inverted_drawing(1);
- drawcircball(GL_LINE_LOOP, t->center, t->propsize, imat);
+ drawcircball(GL_LINE_LOOP, t->center, t->prop_size, imat);
set_inverted_drawing(0);
glPopMatrix();
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index b47f4edc7da..12d7bef1bb8 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;
}
@@ -978,7 +978,8 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob)
if (arm->flag & ARM_RESTPOS) {
if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE)==0) {
- BKE_report(CTX_reports(C), RPT_ERROR, "Can't select linked when sync selection is enabled.");
+ // XXX use transform operator reports
+ // BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled.");
return;
}
}
@@ -1016,7 +1017,8 @@ static void createTransPose(bContext *C, TransInfo *t, Object *ob)
}
if(td != (t->data+t->total)) {
- BKE_report(CTX_reports(C), RPT_DEBUG, "Bone selection count error.");
+ // XXX use transform operator reports
+ // BKE_report(op->reports, RPT_DEBUG, "Bone selection count error.");
}
/* initialise initial auto=ik chainlen's? */
@@ -2110,8 +2112,8 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
int count=0, countsel=0, a, totleft;
int propmode = t->flag & T_PROP_EDIT;
int mirror = 0;
-
- if ((t->options & CTX_NO_MIRROR) == 0 && (scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
+
+ if (t->flag & T_MIRROR)
{
mirror = 1;
}
@@ -3047,7 +3049,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
/* Helper function for createTransGraphEditData, which is reponsible for associating
* source data with transform data
*/
-static void bezt_to_transdata (TransData *td, TransData2D *td2d, Object *nob, float *loc, float *cent, short selected, short ishandle)
+static void bezt_to_transdata (TransData *td, TransData2D *td2d, Object *nob, float *loc, float *cent, short selected, short ishandle, short intvals)
{
/* New location from td gets dumped onto the old-location of td2d, which then
* gets copied to the actual data at td2d->loc2d (bezt->vec[n])
@@ -3094,6 +3096,8 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, Object *nob, fl
if (ishandle)
td->flag |= TD_NOTIMESNAP;
+ if (intvals)
+ td->flag |= TD_INTVALUES;
Mat3One(td->mtx);
Mat3One(td->smtx);
@@ -3204,6 +3208,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
for (ale= anim_data.first; ale; ale= ale->next) {
Object *nob= NULL; //ANIM_nla_mapping_get(&ac, ale); // XXX we don't handle NLA mapping here yet
FCurve *fcu= (FCurve *)ale->key_data;
+ short intvals= (fcu->flag & FCURVE_INT_VALUES);
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse (if applicable) */
bezt= fcu->bezt;
@@ -3218,7 +3223,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
if ( (!prevbezt && (bezt->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) ) {
if (bezt->f1 & SELECT) {
hdata = initTransDataCurveHandes(td, bezt);
- bezt_to_transdata(td++, td2d++, nob, bezt->vec[0], bezt->vec[1], 1, 1);
+ bezt_to_transdata(td++, td2d++, nob, bezt->vec[0], bezt->vec[1], 1, 1, intvals);
}
else
h1= 0;
@@ -3227,7 +3232,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
if (bezt->f3 & SELECT) {
if (hdata==NULL)
hdata = initTransDataCurveHandes(td, bezt);
- bezt_to_transdata(td++, td2d++, nob, bezt->vec[2], bezt->vec[1], 1, 1);
+ bezt_to_transdata(td++, td2d++, nob, bezt->vec[2], bezt->vec[1], 1, 1, intvals);
}
else
h2= 0;
@@ -3243,7 +3248,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
hdata = initTransDataCurveHandes(td, bezt);
}
- bezt_to_transdata(td++, td2d++, nob, bezt->vec[1], bezt->vec[1], 1, 0);
+ bezt_to_transdata(td++, td2d++, nob, bezt->vec[1], bezt->vec[1], 1, 0, intvals);
}
/* special hack (must be done after initTransDataCurveHandes(), as that stores handle settings to restore...):
@@ -3489,7 +3494,11 @@ void flushTransGraphData(TransInfo *t)
//else
td2d->loc2d[0]= td2d->loc[0];
- td2d->loc2d[1]= td2d->loc[1];
+ /* if int-values only, truncate to integers */
+ if (td->flag & TD_INTVALUES)
+ td2d->loc2d[1]= (float)((int)td2d->loc[1]);
+ else
+ td2d->loc2d[1]= td2d->loc[1];
}
}
@@ -4049,7 +4058,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;
}
@@ -4375,13 +4384,13 @@ void special_aftertrans_update(TransInfo *t)
Editing *ed= seq_give_editing(t->scene, FALSE);
if (ed && !cancelled) {
ListBase *seqbasep= ed->seqbasep;
- int a;
- TransData *td= t->data;
- TransData2D *td2d= t->data2d;
- TransDataSeq *tdsq= NULL;
Sequence *seq;
-
+#if 0 // TRANSFORM_FIX_ME, Would prefer to use this since the array takes into
+ // account what where transforming (with extend, locked strips etc)
+ // But at the moment t->data is freed in postTrans so for now re-shuffeling selected strips works ok. - Campbell
+ int a;
+ TransData *td= t->data;
/* prevent updating the same seq twice
* if the transdata order is changed this will mess up
@@ -4389,23 +4398,32 @@ void special_aftertrans_update(TransInfo *t)
Sequence *seq_prev= NULL;
/* flush to 2d vector from internally used 3d vector */
- for(a=0; a<t->total; a++, td++, td2d++) {
-
- tdsq= (TransDataSeq *)td->extra;
- seq= tdsq->seq;
-
- if (seq != seq_prev) {
- if(seq->depth==0) {
- if (seq->flag & SEQ_OVERLAP) {
- shuffle_seq(seqbasep, seq);
- }
- }
+ for(a=0; a<t->total; a++, td++) {
+ seq= ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev) && (seq->depth==0) && (seq->flag & SEQ_OVERLAP)) {
+ shuffle_seq(seqbasep, seq);
}
- /* as last: */
seq_prev= seq;
}
+#else // while t->data is not available...
+ int machine, max_machine = 0;
+ /* update in order so we always move bottom strips first */
+ for(seq= seqbasep->first; seq; seq= seq->next) {
+ max_machine = MAX2(max_machine, seq->machine);
+ }
+
+ for (machine = 0; machine <= max_machine; machine++)
+ {
+ for(seq= seqbasep->first; seq; seq= seq->next) {
+ if (seq->machine == machine && seq->depth == 0 && (seq->flag & (SELECT|SEQ_LEFTSEL|SEQ_RIGHTSEL)) != 0 && (seq->flag & SEQ_OVERLAP)) {
+ shuffle_seq(seqbasep, seq);
+ }
+ }
+ }
+#endif
+
for(seq= seqbasep->first; seq; seq= seq->next) {
/* We might want to build a list of effects that need to be updated during transform */
if(seq->type & SEQ_EFFECT) {
@@ -4420,7 +4438,8 @@ void special_aftertrans_update(TransInfo *t)
if (t->customData)
MEM_freeN(t->customData);
-
+ if (t->data)
+ MEM_freeN(t->data); // XXX postTrans usually does this
}
else if (t->spacetype == SPACE_ACTION) {
SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first;
@@ -5017,16 +5036,18 @@ void createTransData(bContext *C, TransInfo *t)
t->flag |= T_POINTS;
}
else {
- View3D *v3d = t->view;
- RegionView3D *rv3d = t->ar->regiondata;
-
t->flag &= ~T_PROP_EDIT; /* no proportional edit in object mode */
createTransObject(C, t);
t->flag |= T_OBJECT;
- if((t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB)
+ if (t->ar->regiontype == RGN_TYPE_WINDOW)
{
- t->flag |= T_CAMERA;
+ View3D *v3d = t->view;
+ RegionView3D *rv3d = t->ar->regiondata;
+ if((t->flag & T_OBJECT) && v3d->camera == OBACT && rv3d->persp==V3D_CAMOB)
+ {
+ t->flag |= T_CAMERA;
+ }
}
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 861681423e9..5b7fa24f2ab 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -52,6 +52,9 @@
#include "DNA_scene_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "RNA_access.h"
//#include "BIF_screen.h"
//#include "BIF_mywindow.h"
@@ -468,7 +471,7 @@ void recalcData(TransInfo *t)
// }
clipMirrorModifier(t, t->obedit);
}
- if((t->options & CTX_NO_MIRROR) == 0 && (scene->toolsettings->editbutflag & B_MESH_X_MIRROR))
+ if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR))
editmesh_apply_to_mirror(t);
DAG_object_flush_update(scene, t->obedit, OB_RECALC_DATA); /* sets recalc flags */
@@ -660,7 +663,7 @@ void resetTransRestrictions(TransInfo *t)
t->flag &= ~T_ALL_RESTRICTIONS;
}
-void initTransInfo (bContext *C, TransInfo *t, wmEvent *event)
+int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
{
Scene *sce = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
@@ -685,16 +688,6 @@ void initTransInfo (bContext *C, TransInfo *t, wmEvent *event)
t->redraw = 1; /* redraw first time */
- t->propsize = 1.0f; /* TRANSFORM_FIX_ME this needs to be saved in scene or something */
-
- /* setting PET flag */
- if ((t->options & CTX_NO_PET) == 0 && (sce->proportional)) {
- t->flag |= T_PROP_EDIT;
-
- if(sce->proportional == 2)
- t->flag |= T_PROP_CONNECTED; // yes i know, has to become define
- }
-
if (event)
{
t->imval[0] = event->x - t->ar->winrct.xmin;
@@ -741,6 +734,20 @@ void initTransInfo (bContext *C, TransInfo *t, wmEvent *event)
if(v3d->flag & V3D_ALIGN) t->flag |= T_V3D_ALIGN;
t->around = v3d->around;
+
+ if (op && RNA_struct_find_property(op->ptr, "constraint_axis") && RNA_property_is_set(op->ptr, "constraint_orientation"))
+ {
+ t->current_orientation = RNA_int_get(op->ptr, "constraint_orientation");
+
+ if (t->current_orientation >= V3D_MANIP_CUSTOM + BIF_countTransformOrientation(C) - 1)
+ {
+ t->current_orientation = V3D_MANIP_GLOBAL;
+ }
+ }
+ else
+ {
+ t->current_orientation = v3d->twmode;
+ }
}
else if(t->spacetype==SPACE_IMAGE || t->spacetype==SPACE_NODE)
{
@@ -756,9 +763,73 @@ void initTransInfo (bContext *C, TransInfo *t, wmEvent *event)
t->around = V3D_CENTER;
}
+ if (op && RNA_struct_find_property(op->ptr, "mirror") && RNA_property_is_set(op->ptr, "mirror"))
+ {
+ if (RNA_boolean_get(op->ptr, "mirror"))
+ {
+ t->flag |= T_MIRROR;
+ }
+ }
+ // Need stuff to take it from edit mesh or whatnot here
+ else
+ {
+ if (t->obedit && t->obedit->type == OB_MESH && sce->toolsettings->editbutflag & B_MESH_X_MIRROR)
+ {
+ t->flag |= T_MIRROR;
+ }
+ }
+
+ /* setting PET flag */
+ if (op && RNA_struct_find_property(op->ptr, "proportional") && RNA_property_is_set(op->ptr, "proportional"))
+ {
+ switch(RNA_enum_get(op->ptr, "proportional"))
+ {
+ case 2: /* XXX connected constant */
+ t->flag |= T_PROP_CONNECTED;
+ case 1: /* XXX prop on constant */
+ t->flag |= T_PROP_EDIT;
+ break;
+ }
+ }
+ else
+ {
+ if ((t->options & CTX_NO_PET) == 0 && (sce->proportional)) {
+ t->flag |= T_PROP_EDIT;
+
+ if(sce->proportional == 2)
+ t->flag |= T_PROP_CONNECTED; // yes i know, has to become define
+ }
+ }
+
+ if (op && RNA_struct_find_property(op->ptr, "proportional_size") && RNA_property_is_set(op->ptr, "proportional_size"))
+ {
+ t->prop_size = RNA_float_get(op->ptr, "proportional_size");
+ }
+ else
+ {
+ t->prop_size = sce->toolsettings->proportional_size;
+ }
+
+ if (op && RNA_struct_find_property(op->ptr, "proportional_editing_falloff") && RNA_property_is_set(op->ptr, "proportional_editing_falloff"))
+ {
+ t->prop_mode = RNA_enum_get(op->ptr, "proportional_editing_falloff");
+ }
+ else
+ {
+ t->prop_mode = sce->prop_mode;
+ }
+
+ /* TRANSFORM_FIX_ME rna restrictions */
+ if (t->prop_size <= 0)
+ {
+ t->prop_size = 1.0f;
+ }
+
setTransformViewMatrices(t);
initNumInput(&t->num);
initNDofInput(&t->ndof);
+
+ return 1;
}
/* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */
@@ -1118,10 +1189,10 @@ void calculatePropRatio(TransInfo *t)
td->factor = 1.0f;
}
else if ((connected &&
- (td->flag & TD_NOTCONNECTED || td->dist > t->propsize))
+ (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size))
||
(connected == 0 &&
- td->rdist > t->propsize)) {
+ td->rdist > t->prop_size)) {
/*
The elements are sorted according to their dist member in the array,
that means we can stop when it finds one element outside of the propsize.
@@ -1133,7 +1204,7 @@ void calculatePropRatio(TransInfo *t)
else {
/* Use rdist for falloff calculations, it is the real distance */
td->flag &= ~TD_NOACTION;
- dist= (t->propsize-td->rdist)/t->propsize;
+ dist= (t->prop_size-td->rdist)/t->prop_size;
/*
* Clamp to positive numbers.
@@ -1143,7 +1214,7 @@ void calculatePropRatio(TransInfo *t)
if (dist < 0.0f)
dist = 0.0f;
- switch(t->scene->prop_mode) {
+ switch(t->prop_mode) {
case PROP_SHARP:
td->factor= dist*dist;
break;
@@ -1171,7 +1242,7 @@ void calculatePropRatio(TransInfo *t)
}
}
}
- switch(t->scene->prop_mode) {
+ switch(t->prop_mode) {
case PROP_SHARP:
strcpy(t->proptext, "(Sharp)");
break;
diff --git a/source/blender/editors/transform/transform_numinput.c b/source/blender/editors/transform/transform_numinput.c
index fc348bab719..34976105db3 100644
--- a/source/blender/editors/transform/transform_numinput.c
+++ b/source/blender/editors/transform/transform_numinput.c
@@ -129,7 +129,6 @@ short hasNumInput(NumInput *n)
void applyNumInput(NumInput *n, float *vec)
{
short i, j;
- float val[3];
if (hasNumInput(n)) {
for (j=0; j<=n->idx_max; j++) {
@@ -142,17 +141,17 @@ void applyNumInput(NumInput *n, float *vec)
if (n->ctrl[i] == 0 && n->flag & NUM_NULL_ONE) {
vec[j] = 1.0f;
}
- else if (val[i] == 0.0f && n->flag & NUM_NO_ZERO) {
+ else if (n->val[i] == 0.0f && n->flag & NUM_NO_ZERO) {
vec[j] = 0.0001f;
}
else {
if (n->inv[i])
{
- vec[j] = 1.0f / val[i];
+ vec[j] = 1.0f / n->val[i];
}
else
{
- vec[j] = val[i];
+ vec[j] = n->val[i];
}
}
}
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 49f0020420a..a45af971d01 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -24,11 +24,13 @@
#include "MEM_guardedalloc.h"
+#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_windowmanager_types.h"
#include "RNA_access.h"
#include "RNA_define.h"
+#include "RNA_enum_types.h"
#include "BLI_arithb.h"
@@ -44,6 +46,64 @@
#include "transform.h"
+typedef struct TransformModeItem
+{
+ char *idname;
+ int mode;
+} TransformModeItem;
+
+static float VecOne[3] = {1, 1, 1};
+
+/* need constants for this */
+EnumPropertyItem proportional_mode_types[] = {
+ {0, "OFF", "Off", ""},
+ {1, "ON", "On", ""},
+ {2, "CONNECTED", "Connected", ""},
+ {0, NULL, NULL, NULL}
+};
+
+EnumPropertyItem snap_mode_types[] = {
+ {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", "Closest", ""},
+ {SCE_SNAP_TARGET_CENTER, "CENTER", "Center", ""},
+ {SCE_SNAP_TARGET_MEDIAN, "MEDIAN", "Median", ""},
+ {SCE_SNAP_TARGET_ACTIVE, "ACTIVE", "Active", ""},
+ {0, NULL, NULL, NULL}
+};
+
+EnumPropertyItem proportional_falloff_types[] = {
+ {PROP_SMOOTH, "SMOOTH", "Smooth", ""},
+ {PROP_SPHERE, "SPHERE", "Sphere", ""},
+ {PROP_ROOT, "ROOT", "Root", ""},
+ {PROP_SHARP, "SHARP", "Sharp", ""},
+ {PROP_LIN, "LINEAR", "Linear", ""},
+ {PROP_CONST, "CONSTANT", "Constant", ""},
+ {PROP_RANDOM, "RANDOM", "Random", ""},
+ {0, NULL, NULL, NULL}
+};
+
+char OP_TRANSLATION[] = "TFM_OT_translation";
+char OP_ROTATION[] = "TFM_OT_rotation";
+char OP_TOSPHERE[] = "TFM_OT_tosphere";
+char OP_RESIZE[] = "TFM_OT_resize";
+char OP_SHEAR[] = "TFM_OT_shear";
+char OP_WARP[] = "TFM_OT_warp";
+char OP_SHRINK_FATTEN[] = "TFM_OT_shrink_fatten";
+char OP_TILT[] = "TFM_OT_tilt";
+
+
+TransformModeItem transform_modes[] =
+{
+ {OP_TRANSLATION, TFM_TRANSLATION},
+ {OP_ROTATION, TFM_ROTATION},
+ {OP_TOSPHERE, TFM_TOSPHERE},
+ {OP_RESIZE, TFM_RESIZE},
+ {OP_SHEAR, TFM_SHEAR},
+ {OP_WARP, TFM_WARP},
+ {OP_SHRINK_FATTEN, TFM_SHRINKFATTEN},
+ {OP_TILT, TFM_TILT},
+ {NULL, 0}
+};
+
static int select_orientation_exec(bContext *C, wmOperator *op)
{
int orientation = RNA_enum_get(op->ptr, "orientation");
@@ -98,17 +158,35 @@ static void transformops_exit(bContext *C, wmOperator *op)
op->customdata = NULL;
}
-static void transformops_data(bContext *C, wmOperator *op, wmEvent *event)
+static int transformops_data(bContext *C, wmOperator *op, wmEvent *event)
{
+ int retval = 1;
if (op->customdata == NULL)
{
TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
-
- initTransform(C, t, op, event);
+ TransformModeItem *tmode;
+ int mode = -1;
+
+ for (tmode = transform_modes; tmode->idname; tmode++)
+ {
+ if (op->type->idname == tmode->idname)
+ {
+ mode = tmode->mode;
+ }
+ }
+
+ if (mode == -1)
+ {
+ mode = RNA_int_get(op->ptr, "mode");
+ }
+
+ retval = initTransform(C, t, op, event, mode);
/* store data */
op->customdata = t;
}
+
+ return retval; /* return 0 on error */
}
static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
@@ -147,7 +225,10 @@ static int transform_exec(bContext *C, wmOperator *op)
{
TransInfo *t;
- transformops_data(C, op, NULL);
+ if (!transformops_data(C, op, NULL))
+ {
+ return OPERATOR_CANCELLED;
+ }
t = op->customdata;
@@ -164,22 +245,242 @@ static int transform_exec(bContext *C, wmOperator *op)
static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
- transformops_data(C, op, event);
+ if (!transformops_data(C, op, event))
+ {
+ return OPERATOR_CANCELLED;
+ }
- if(RNA_property_is_set(op->ptr, "values")) {
+ if(RNA_property_is_set(op->ptr, "value")) {
return transform_exec(C, op);
}
else {
+ TransInfo *t = op->customdata;
+
/* add temp handler */
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
+ t->flag |= T_MODAL; // XXX meh maybe somewhere else
+
return OPERATOR_RUNNING_MODAL;
}
}
+void Properties_Proportional(struct wmOperatorType *ot)
+{
+ RNA_def_enum(ot->srna, "proportional", proportional_mode_types, 0, "Proportional Edition", "");
+ RNA_def_enum(ot->srna, "proportional_editing_falloff", prop_mode_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
+ RNA_def_float(ot->srna, "proportional_size", 1, 0, FLT_MAX, "Proportional Size", "", 0, 100);
+}
+
+void Properties_Snapping(struct wmOperatorType *ot, short align)
+{
+ RNA_def_boolean(ot->srna, "snap", 0, "Snap to Point", "");
+ RNA_def_enum(ot->srna, "snap_mode", snap_mode_types, 0, "Mode", "");
+ RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
+
+ if (align)
+ {
+ RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", "");
+ RNA_def_float_vector(ot->srna, "snap_normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "", -FLT_MAX, FLT_MAX);
+ }
+}
+
+void Properties_Constraints(struct wmOperatorType *ot)
+{
+ RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
+ RNA_def_int(ot->srna, "constraint_orientation", 0, 0, INT_MAX, "Constraint Orientation", "", 0, INT_MAX);
+}
+
+void TFM_OT_translation(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Translation";
+ ot->idname = OP_TRANSLATION;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_areaactive;
+
+ RNA_def_float_vector(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
+
+ Properties_Proportional(ot);
+
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
+
+ Properties_Constraints(ot);
+
+ Properties_Snapping(ot, 1);
+}
+
+void TFM_OT_resize(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Resize";
+ ot->idname = OP_RESIZE;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_areaactive;
+
+ RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
+
+ Properties_Proportional(ot);
+
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
+
+ Properties_Constraints(ot);
+
+ Properties_Snapping(ot, 0);
+}
+
+void TFM_OT_rotation(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Rotation";
+ ot->idname = OP_ROTATION;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_areaactive;
+
+ RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
+
+ Properties_Proportional(ot);
+
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
+
+ Properties_Constraints(ot);
+
+ Properties_Snapping(ot, 0);
+}
+
+void TFM_OT_tilt(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Tilt";
+ ot->idname = OP_TILT;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_editcurve;
+
+ RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
+
+ Properties_Proportional(ot);
+
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
+
+ Properties_Constraints(ot);
+}
+
+void TFM_OT_warp(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Warp";
+ ot->idname = OP_WARP;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_areaactive;
+
+ RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", 0, 1);
+
+ Properties_Proportional(ot);
+
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
+
+ // XXX Shear axis?
+// Properties_Constraints(ot);
+}
+
+void TFM_OT_shear(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Shear";
+ ot->idname = OP_SHEAR;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_areaactive;
+
+ RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
+
+ Properties_Proportional(ot);
+
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
+
+ // XXX Shear axis?
+// Properties_Constraints(ot);
+}
+
+void TFM_OT_shrink_fatten(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Shrink/Fatten";
+ ot->idname = OP_SHRINK_FATTEN;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_editmesh;
+
+ RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
+
+ Properties_Proportional(ot);
+
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
+}
+
+void TFM_OT_tosphere(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "To Sphere";
+ ot->idname = OP_TOSPHERE;
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->invoke = transform_invoke;
+ ot->exec = transform_exec;
+ ot->modal = transform_modal;
+ ot->cancel = transform_cancel;
+ ot->poll = ED_operator_areaactive;
+
+ RNA_def_float_percentage(ot->srna, "value", 0, 0, 1, "Percentage", "", 0, 1);
+
+ Properties_Proportional(ot);
+
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
+}
+
void TFM_OT_transform(struct wmOperatorType *ot)
{
- static const float mtx[3][3] = {{1, 0, 0},{0, 1, 0},{0, 0, 1}};
static EnumPropertyItem transform_mode_types[] = {
{TFM_INIT, "INIT", "Init", ""},
{TFM_DUMMY, "DUMMY", "Dummy", ""},
@@ -191,7 +492,6 @@ void TFM_OT_transform(struct wmOperatorType *ot)
{TFM_WARP, "WARP", "Warp", ""},
{TFM_SHRINKFATTEN, "SHRINKFATTEN", "Shrinkfatten", ""},
{TFM_TILT, "TILT", "Tilt", ""},
- {TFM_LAMP_ENERGY, "LAMP_ENERGY", "Lamp_Energy", ""},
{TFM_TRACKBALL, "TRACKBALL", "Trackball", ""},
{TFM_PUSHPULL, "PUSHPULL", "Pushpull", ""},
{TFM_CREASE, "CREASE", "Crease", ""},
@@ -210,7 +510,7 @@ void TFM_OT_transform(struct wmOperatorType *ot)
{TFM_ALIGN, "ALIGN", "Align", ""},
{0, NULL, NULL, NULL}
};
-
+
/* identifiers */
ot->name = "Transform";
ot->idname = "TFM_OT_transform";
@@ -224,19 +524,28 @@ void TFM_OT_transform(struct wmOperatorType *ot)
ot->poll = ED_operator_areaactive;
RNA_def_enum(ot->srna, "mode", transform_mode_types, 0, "Mode", "");
- RNA_def_int(ot->srna, "options", 0, INT_MIN, INT_MAX, "Options", "", INT_MIN, INT_MAX);
-
- RNA_def_float_vector(ot->srna, "values", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
- RNA_def_int(ot->srna, "constraint_orientation", 0, INT_MIN, INT_MAX, "Constraint Orientation", "", INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "constraint_mode", 0, INT_MIN, INT_MAX, "Constraint Mode", "", INT_MIN, INT_MAX);
+ RNA_def_float_vector(ot->srna, "value", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
+
+ Properties_Proportional(ot);
+ RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Edition", "");
- RNA_def_float_matrix(ot->srna, "constraint_matrix", 9, mtx[0], -FLT_MAX, FLT_MAX, "Constraint Matrix", "", -FLT_MAX, FLT_MAX);
+ RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
+ RNA_def_int(ot->srna, "constraint_orientation", 0, 0, INT_MAX, "Constraint Orientation", "", 0, INT_MAX);
}
void transform_operatortypes(void)
{
WM_operatortype_append(TFM_OT_transform);
+ WM_operatortype_append(TFM_OT_translation);
+ WM_operatortype_append(TFM_OT_rotation);
+ WM_operatortype_append(TFM_OT_tosphere);
+ WM_operatortype_append(TFM_OT_resize);
+ WM_operatortype_append(TFM_OT_shear);
+ WM_operatortype_append(TFM_OT_warp);
+ WM_operatortype_append(TFM_OT_shrink_fatten);
+ WM_operatortype_append(TFM_OT_tilt);
+
WM_operatortype_append(TFM_OT_select_orientation);
}
@@ -246,27 +555,24 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key
switch(spaceid)
{
case SPACE_VIEW3D:
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
+ km = WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0);
- km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
+ km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_S, KM_ANY, 0, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_ROTATION);
+ km = WM_keymap_add_item(keymap, "TFM_OT_rotation", RKEY, KM_PRESS, 0, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_RESIZE);
+ km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", WKEY, KM_PRESS, KM_SHIFT, 0);
- RNA_int_set(km->ptr, "mode", TFM_WARP);
+ km = WM_keymap_add_item(keymap, "TFM_OT_warp", WKEY, KM_PRESS, KM_SHIFT, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
- RNA_int_set(km->ptr, "mode", TFM_TOSPHERE);
+ km = WM_keymap_add_item(keymap, "TFM_OT_tosphere", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
- RNA_int_set(km->ptr, "mode", TFM_SHEAR);
+ km = WM_keymap_add_item(keymap, "TFM_OT_shear", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
+ km = WM_keymap_add_item(keymap, "TFM_OT_shrink_fatten", SKEY, KM_PRESS, KM_ALT, 0);
+
+ km = WM_keymap_add_item(keymap, "TFM_OT_tilt", TKEY, KM_PRESS, 0, 0);
+
km = WM_keymap_add_item(keymap, "TFM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
break;
@@ -287,59 +593,44 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *key
RNA_int_set(km->ptr, "mode", TFM_TIME_SLIDE);
break;
case SPACE_IPO:
- km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
+ km= WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0);
- km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
+ km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_S, KM_ANY, 0, 0);
// XXX the 'mode' identifier here is not quite right
km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_ROTATION);
+ km = WM_keymap_add_item(keymap, "TFM_OT_rotation", RKEY, KM_PRESS, 0, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_RESIZE);
+ km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
break;
case SPACE_NODE:
- km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
+ km= WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0);
- km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_A, KM_ANY, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
- km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
+ km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_A, KM_ANY, 0, 0);
+ km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_S, KM_ANY, 0, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_ROTATION);
+ km = WM_keymap_add_item(keymap, "TFM_OT_rotation", RKEY, KM_PRESS, 0, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_RESIZE);
+ km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
break;
case SPACE_SEQ:
- km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
+ km= WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0);
- km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
+ km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_S, KM_ANY, 0, 0);
km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
break;
case SPACE_IMAGE:
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
+ km = WM_keymap_add_item(keymap, "TFM_OT_translation", GKEY, KM_PRESS, 0, 0);
- km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
+ km= WM_keymap_add_item(keymap, "TFM_OT_translation", EVT_TWEAK_S, KM_ANY, 0, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_ROTATION);
+ km = WM_keymap_add_item(keymap, "TFM_OT_rotation", RKEY, KM_PRESS, 0, 0);
- km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
- RNA_int_set(km->ptr, "mode", TFM_RESIZE);
+ km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
km = WM_keymap_add_item(keymap, "TFM_OT_transform", MKEY, KM_PRESS, 0, 0);
RNA_int_set(km->ptr, "mode", TFM_MIRROR);
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index fd1db9e1984..df785f92166 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -448,15 +448,15 @@ static int count_bone_select(bArmature *arm, ListBase *lb, int do_it)
void initTransformOrientation(bContext *C, TransInfo *t)
{
View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d= CTX_wm_region_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
Object *ob = CTX_data_active_object(C);
Object *obedit = CTX_data_active_object(C);
float normal[3]={0.0, 0.0, 0.0};
float plane[3]={0.0, 0.0, 0.0};
- if(v3d==NULL) return;
+ if(t->spacetype != SPACE_VIEW3D) return;
- switch(v3d->twmode) {
+ switch(t->current_orientation) {
case V3D_MANIP_GLOBAL:
strcpy(t->spacename, "global");
break;
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 447c4b810ab..dc32a46a301 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
@@ -41,9 +43,13 @@
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view3d_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "RNA_access.h"
#include "BLI_arithb.h"
#include "BLI_editVert.h"
+#include "BLI_blenlib.h"
//#include "BDR_drawobject.h"
//
@@ -57,6 +63,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 +72,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"
@@ -82,7 +91,7 @@
/********************* PROTOTYPES ***********************/
-void setSnappingCallback(TransInfo *t);
+void setSnappingCallback(TransInfo *t, short snap_target);
void ApplySnapTranslation(TransInfo *t, float vec[3]);
void ApplySnapRotation(TransInfo *t, float *vec);
@@ -100,12 +109,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 +116,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;
}
@@ -121,7 +124,7 @@ int BIF_snappingSupported(Object *obedit)
return status;
}
-void drawSnapping(TransInfo *t)
+void drawSnapping(const struct bContext *C, TransInfo *t)
{
if ((t->tsnap.status & (SNAP_ON|POINT_INIT|TARGET_INIT)) == (SNAP_ON|POINT_INIT|TARGET_INIT) &&
(t->modifiers & MOD_SNAP_GEARS))
@@ -132,8 +135,8 @@ void drawSnapping(TransInfo *t)
glColor4ub(col[0], col[1], col[2], 128);
if (t->spacetype == SPACE_VIEW3D) {
- View3D *v3d = t->view;
- RegionView3D *rv3d= t->ar->regiondata;
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
float tmat[4][4], imat[4][4];
float size;
@@ -208,7 +211,7 @@ int handleSnapping(TransInfo *t, wmEvent *event)
{
/* toggle snap and reinit */
t->scene->snap_flag ^= SCE_SNAP;
- initSnapping(t);
+ initSnapping(t, NULL);
status = 1;
}
@@ -217,7 +220,13 @@ int handleSnapping(TransInfo *t, wmEvent *event)
void applySnapping(TransInfo *t, float *vec)
{
- if ((t->tsnap.status & SNAP_ON) &&
+ if (t->tsnap.status & SNAP_FORCED)
+ {
+ t->tsnap.targetSnap(t);
+
+ t->tsnap.applySnap(t, vec);
+ }
+ else if ((t->tsnap.status & SNAP_ON) &&
(t->modifiers & MOD_SNAP_GEARS))
{
double current = PIL_check_seconds_timer();
@@ -241,6 +250,8 @@ void applySnapping(TransInfo *t, float *vec)
void resetSnapping(TransInfo *t)
{
t->tsnap.status = 0;
+ t->tsnap.mode = 0;
+ t->tsnap.align = 0;
t->tsnap.modePoint = 0;
t->tsnap.modeTarget = 0;
t->tsnap.last = 0;
@@ -253,14 +264,7 @@ void resetSnapping(TransInfo *t)
int usingSnappingNormal(TransInfo *t)
{
- if (t->scene->snap_flag & SCE_SNAP_ROTATE)
- {
- return 1;
- }
- else
- {
- return 0;
- }
+ return t->tsnap.align;
}
int validSnappingNormal(TransInfo *t)
@@ -276,20 +280,48 @@ int validSnappingNormal(TransInfo *t)
return 0;
}
-void initSnapping(TransInfo *t)
+void initSnapping(TransInfo *t, wmOperator *op)
{
Scene *scene = t->scene;
Object *obedit = t->obedit;
+ int snapping = 0;
+ short snap_mode = t->scene->snap_target;
+
resetSnapping(t);
+ if (op && RNA_struct_find_property(op->ptr, "snap") && RNA_property_is_set(op->ptr, "snap"))
+ {
+ if (RNA_boolean_get(op->ptr, "snap"))
+ {
+ snapping = 1;
+ snap_mode = RNA_enum_get(op->ptr, "snap_mode");
+
+ t->tsnap.status |= SNAP_FORCED|POINT_INIT;
+ RNA_float_get_array(op->ptr, "snap_point", t->tsnap.snapPoint);
+
+ /* snap align only defined in specific cases */
+ if (RNA_struct_find_property(op->ptr, "snap_align"))
+ {
+ t->tsnap.align = RNA_boolean_get(op->ptr, "snap_align");
+ RNA_float_get_array(op->ptr, "snap_normal", t->tsnap.snapNormal);
+ Normalize(t->tsnap.snapNormal);
+ }
+ }
+ }
+ else
+ {
+ snapping = ((scene->snap_flag & SCE_SNAP) == SCE_SNAP);
+ t->tsnap.align = ((t->scene->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
+ }
+
if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && // Only 3D view or UV
(t->flag & T_CAMERA) == 0) { // Not with camera selected
- setSnappingCallback(t);
+ setSnappingCallback(t, snap_mode);
/* 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
+ (snapping) && // Only if the snap flag is on
+ (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;
@@ -305,7 +337,7 @@ void initSnapping(TransInfo *t)
}
/* Object mode */
else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
- (scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on
+ (snapping) && // Only if the snap flag is on
(obedit == NULL) ) // Object Mode
{
t->tsnap.status |= SNAP_ON;
@@ -325,12 +357,11 @@ void initSnapping(TransInfo *t)
}
}
-void setSnappingCallback(TransInfo *t)
+void setSnappingCallback(TransInfo *t, short snap_target)
{
- Scene *scene = t->scene;
t->tsnap.calcSnap = CalcSnapGeometry;
- switch(scene->snap_target)
+ switch(snap_target)
{
case SCE_SNAP_TARGET_CLOSEST:
t->tsnap.modeTarget = SNAP_CLOSEST;
@@ -362,7 +393,7 @@ void setSnappingCallback(TransInfo *t)
t->tsnap.distance = RotationBetween;
// Can't do TARGET_CENTER with rotation, use TARGET_MEDIAN instead
- if (scene->snap_target == SCE_SNAP_TARGET_CENTER) {
+ if (snap_target == SCE_SNAP_TARGET_CENTER) {
t->tsnap.modeTarget = SNAP_MEDIAN;
t->tsnap.targetSnap = TargetSnapMedian;
}
@@ -372,7 +403,7 @@ void setSnappingCallback(TransInfo *t)
t->tsnap.distance = ResizeBetween;
// Can't do TARGET_CENTER with resize, use TARGET_MEDIAN instead
- if (scene->snap_target == SCE_SNAP_TARGET_CENTER) {
+ if (snap_target == SCE_SNAP_TARGET_CENTER) {
t->tsnap.modeTarget = SNAP_MEDIAN;
t->tsnap.targetSnap = TargetSnapMedian;
}
@@ -503,85 +534,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];
- found = snapObjects(t, &dist, vec, no, t->tsnap.mode);
- if (found == 1)
+ depth_peels.first = depth_peels.last = NULL;
+
+ peelObjectsTransForm(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;
+// }
+
+
+ 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 = snapObjectsTransform(t, t->mval, &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,7 +865,252 @@ void TargetSnapClosest(TransInfo *t)
}
/*================================================================*/
-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 snapFace(ARegion *ar, 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(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(ARegion *ar, 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(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(ARegion *ar, 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(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(short snap_mode, ARegion *ar, 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 (snap_mode)
+ {
+ case SCE_SNAP_MODE_VERTEX:
+ retval |= snapVertex(ar, eBone->head, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+ retval |= snapVertex(ar, 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(ar, 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 (snap_mode)
+ {
+ case SCE_SNAP_MODE_VERTEX:
+ retval |= snapVertex(ar, head_vec, NULL, mval, ray_start, ray_start_local, ray_normal_local, obmat, NULL, loc, NULL, dist, depth);
+ retval |= snapVertex(ar, 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(ar, 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(short snap_mode, ARegion *ar, 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;
int totvert = dm->getNumVerts(dm);
@@ -791,7 +1144,7 @@ int snapDerivedMesh(TransInfo *t, Object *ob, DerivedMesh *dm, EditMesh *em, flo
if (test == 1) {
- switch (t->scene->snap_mode)
+ switch (snap_mode)
{
case SCE_SNAP_MODE_FACE:
{
@@ -810,8 +1163,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 +1195,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(ar, 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(ar, 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 +1267,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(ar, v->co, v->no, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth);
}
}
@@ -1080,79 +1327,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(ar, 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,41 +1344,273 @@ 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) {
- Scene *scene = t->scene;
- View3D *v3d = t->view;
+int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, 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;
+
+ if (ob->type == OB_MESH) {
+ EditMesh *em;
+ DerivedMesh *dm;
+
+ if (editobject)
+ {
+ em = ((Mesh *)ob->data)->edit_mesh;
+ dm = editmesh_get_derived_cage(scene, ob, em, CD_MASK_BAREMESH);
+ }
+ else
+ {
+ em = NULL;
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+ }
+
+ retval = snapDerivedMesh(scene->snap_mode, ar, ob, dm, em, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
+
+ dm->release(dm);
+ }
+ else if (ob->type == OB_ARMATURE)
+ {
+ retval = snapArmature(scene->snap_mode, ar, ob, ob->data, obmat, ray_start, ray_normal, mval, loc, no, dist, depth);
+ }
+
+ return retval;
+}
+
+int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, short mval[2], int *dist, float *loc, float *no, SnapMode mode) {
Base *base;
float depth = FLT_MAX;
int retval = 0;
float ray_start[3], ray_normal[3];
- viewray(t->ar, v3d, t->mval, ray_start, ray_normal);
+ viewray(ar, v3d, mval, ray_start, ray_normal);
- if (mode == SNAP_ALL && t->obedit)
+ if (mode == SNAP_ALL && obedit)
{
- DerivedMesh *dm;
- Object *ob = t->obedit;
- EditMesh *em = ((Mesh *)t->obedit->data)->edit_mesh;
+ Object *ob = obedit;
- dm = editmesh_get_derived_cage(t->scene, t->obedit, em, CD_MASK_BAREMESH);
+ retval |= snapObject(scene, ar, ob, 1, ob->obmat, ray_start, ray_normal, 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(scene, ob);
+
+ for(dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next)
+ {
+ Object *ob = dupli_ob->ob;
+
+ retval |= snapObject(scene, ar, ob, 0, dupli_ob->mat, ray_start, ray_normal, mval, loc, no, dist, &depth);
+ }
+
+ free_object_duplilist(lb);
+ }
+
+ retval |= snapObject(scene, ar, ob, 0, ob->obmat, ray_start, ray_normal, mval, loc, no, dist, &depth);
+ }
+ }
+
+ return retval;
+}
+
+int snapObjectsTransform(TransInfo *t, short mval[2], int *dist, float *loc, float *no, SnapMode mode)
+{
+ return snapObjects(t->scene, t->view, t->ar, t->obedit, mval, dist, loc, no, mode);
+}
+
+int snapObjectsContext(bContext *C, short mval[2], int *dist, float *loc, float *no, SnapMode mode)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ View3D *v3d = sa->spacedata.first;
+
+ return snapObjects(CTX_data_scene(C), v3d, CTX_wm_region(C), CTX_data_edit_object(C), mval, dist, loc, no, mode);
+}
+
+/******************** 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(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(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, short mval[2])
+{
+ Base *base;
+ int retval = 0;
+ float ray_start[3], ray_normal[3];
+ viewray(ar, v3d, 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)
{
DupliObject *dupli_ob;
- ListBase *lb = object_duplilist(t->scene, ob);
+ ListBase *lb = object_duplilist(scene, ob);
for(dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next)
{
@@ -1211,21 +1618,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(ob, dm, dupli_ob->mat, ray_start, ray_normal, mval, depth_peels);
retval = retval || val;
@@ -1237,11 +1632,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 != obedit)
+ {
+ dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+
+ val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels);
+ }
+ else
+ {
+ em = ((Mesh *)ob->data)->edit_mesh;
+ dm = editmesh_get_derived_cage(scene, obedit, em, CD_MASK_BAREMESH);
+
+ val = peelDerivedMesh(ob, dm, ob->obmat, ray_start, ray_normal, mval, depth_peels);
+ }
+
retval = retval || val;
dm->release(dm);
@@ -1249,9 +1657,25 @@ int snapObjects(TransInfo *t, int *dist, float *loc, float *no, int mode) {
}
}
+ BLI_sortlist(depth_peels, cmpPeel);
+ removeDoublesPeel(depth_peels);
+
return retval;
}
+int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, short mval[2])
+{
+ return peelObjects(t->scene, t->view, t->ar, t->obedit, depth_peels, mval);
+}
+
+int peelObjectsContext(bContext *C, ListBase *depth_peels, short mval[2])
+{
+ ScrArea *sa = CTX_wm_area(C);
+ View3D *v3d = sa->spacedata.first;
+
+ return peelObjects(CTX_data_scene(C), v3d, CTX_wm_region(C), CTX_data_edit_object(C), depth_peels, mval);
+}
+
/*================================================================*/
static void applyGrid(TransInfo *t, float *val, int max_index, float fac[3], GearsType action);
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 9686d4d6094..4b2f23e823b 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -120,7 +120,7 @@ static void draw_uvs_shadow(SpaceImage *sima, Object *obedit)
EditFace *efa;
TFace *tf;
- em= ((Mesh*)obedit->data)->edit_mesh;
+ em= EM_GetEditMesh((Mesh*)obedit->data);
/* draws the grey mesh when painting */
glColor3ub(112, 112, 112);
@@ -135,6 +135,8 @@ static void draw_uvs_shadow(SpaceImage *sima, Object *obedit)
if(efa->v4) glVertex2fv(tf->uv[3]);
glEnd();
}
+
+ EM_EndEditMesh(obedit->data, em);
}
static int draw_uvs_dm_shadow(DerivedMesh *dm)
@@ -373,6 +375,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)
{
@@ -387,7 +428,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
int drawfaces, interpedges, lastsel, sel;
Image *ima= sima->image;
- em= me->edit_mesh;
+ em= EM_GetEditMesh(me);
activetf= EM_get_active_mtface(em, &efa_act, NULL, 0); /* will be set to NULL if hidden */
settings= scene->toolsettings;
@@ -397,6 +438,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 +621,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) {
@@ -781,6 +826,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
}
glPointSize(1.0);
+ EM_EndEditMesh(obedit->data, em);
}
void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit)
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 60cfbfd0f39..17b2aff1b21 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -75,10 +75,17 @@
int ED_uvedit_test(Object *obedit)
{
+ EditMesh *em;
+ int ret;
+
if(obedit->type != OB_MESH)
return 0;
- return EM_texFaceCheck(((Mesh*)obedit->data)->edit_mesh);
+ em = EM_GetEditMesh(obedit->data);
+ ret = EM_texFaceCheck(em);
+ EM_EndEditMesh(obedit->data, em);
+
+ return ret;
}
/************************* assign image ************************/
@@ -98,9 +105,11 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre
if(!obedit || (obedit->type != OB_MESH))
return;
- em= ((Mesh*)obedit->data)->edit_mesh;
- if(!em || !em->faces.first)
+ em= EM_GetEditMesh(((Mesh*)obedit->data));
+ if(!em || !em->faces.first) {
+ EM_EndEditMesh(obedit->data, em);
return;
+ }
/* ensure we have a uv layer */
if(!CustomData_has_layer(&em->fdata, CD_MTFACE)) {
@@ -135,6 +144,8 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre
/* and update depdency graph */
if(update)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+
+ EM_EndEditMesh(obedit->data, em);
}
/* dotile - 1, set the tile flag (from the space image)
@@ -153,7 +164,7 @@ void ED_uvedit_set_tile(bContext *C, Scene *scene, Object *obedit, Image *ima, i
if(ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE)
return;
- em= ((Mesh*)obedit->data)->edit_mesh;
+ em= EM_GetEditMesh((Mesh*)obedit->data);
for(efa= em->faces.first; efa; efa= efa->next) {
tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
@@ -173,6 +184,7 @@ void ED_uvedit_set_tile(bContext *C, Scene *scene, Object *obedit, Image *ima, i
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
}
/*********************** space conversion *********************/
@@ -356,7 +368,7 @@ void uv_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy)
int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float *min, float *max)
{
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
int sel;
@@ -373,13 +385,14 @@ int ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float *min, float
if(efa->v4 && (uvedit_uv_selected(scene, efa, tf, 3))) { DO_MINMAX2(tf->uv[3], min, max); sel = 1; }
}
}
-
+
+ EM_EndEditMesh(obedit->data, em);
return sel;
}
int uvedit_center(Scene *scene, Image *ima, Object *obedit, float *cent, int mode)
{
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
float min[2], max[2];
@@ -407,10 +420,12 @@ int uvedit_center(Scene *scene, Image *ima, Object *obedit, float *cent, int mod
if(change) {
cent[0]= (min[0]+max[0])/2.0;
cent[1]= (min[1]+max[1])/2.0;
-
+
+ EM_EndEditMesh(obedit->data, em);
return 1;
}
+ EM_EndEditMesh(obedit->data, em);
return 0;
}
@@ -569,7 +584,7 @@ static void find_nearest_uv_vert(Scene *scene, Image *ima, EditMesh *em, float c
int ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, float co[2], float uv[2])
{
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
float mindist, dist;
@@ -599,6 +614,7 @@ int ED_uvedit_nearest_uv(Scene *scene, Object *obedit, Image *ima, float co[2],
}
}
+ EM_EndEditMesh(obedit->data, em);
return found;
}
@@ -978,7 +994,7 @@ static void weld_align_uv(bContext *C, int tool)
scene= CTX_data_scene(C);
obedit= CTX_data_edit_object(C);
- em= ((Mesh*)obedit->data)->edit_mesh;
+ em= EM_GetEditMesh((Mesh*)obedit->data);
ima= CTX_data_edit_image(C);
INIT_MINMAX2(min, max);
@@ -1038,6 +1054,8 @@ static void weld_align_uv(bContext *C, int tool)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
}
static int align_exec(bContext *C, wmOperator *op)
@@ -1111,7 +1129,7 @@ static int stitch_exec(bContext *C, wmOperator *op)
sima= (SpaceImage*)CTX_wm_space_data(C);
scene= CTX_data_scene(C);
obedit= CTX_data_edit_object(C);
- em= ((Mesh*)obedit->data)->edit_mesh;
+ em= EM_GetEditMesh((Mesh*)obedit->data);
ima= CTX_data_edit_image(C);
if(RNA_boolean_get(op->ptr, "use_limit")) {
@@ -1126,8 +1144,10 @@ static int stitch_exec(bContext *C, wmOperator *op)
EM_init_index_arrays(em, 0, 0, 1);
vmap= EM_make_uv_vert_map(em, 1, 0, limit);
- if(vmap == NULL)
+ if(vmap == NULL) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
for(a=0, eve= em->verts.first; eve; a++, eve= eve->next) {
vlist= EM_get_uv_map_vert(vmap, a);
@@ -1256,6 +1276,7 @@ static int stitch_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -1288,7 +1309,7 @@ static int select_inverse_exec(bContext *C, wmOperator *op)
scene= CTX_data_scene(C);
obedit= CTX_data_edit_object(C);
- em= ((Mesh*)obedit->data)->edit_mesh;
+ em= EM_GetEditMesh((Mesh*)obedit->data);
ima= CTX_data_edit_image(C);
if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
@@ -1309,6 +1330,7 @@ static int select_inverse_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -1338,7 +1360,7 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
scene= CTX_data_scene(C);
obedit= CTX_data_edit_object(C);
- em= ((Mesh*)obedit->data)->edit_mesh;
+ em= EM_GetEditMesh((Mesh*)obedit->data);
ima= CTX_data_edit_image(C);
if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
@@ -1376,14 +1398,15 @@ static int de_select_all_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
-void UV_OT_de_select_all(wmOperatorType *ot)
+void UV_OT_select_all_toggle(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select or Deselect All";
- ot->idname= "UV_OT_de_select_all";
+ ot->idname= "UV_OT_select_all_toggle";
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
@@ -1422,7 +1445,7 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Image *ima= CTX_data_edit_image(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
NearestHit hit;
@@ -1456,14 +1479,18 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
if(loop) {
/* find edge */
find_nearest_uv_edge(scene, ima, em, co, &hit);
- if(hit.efa == NULL)
+ if(hit.efa == NULL) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
}
else if(selectmode == UV_SELECT_VERTEX) {
/* find vertex */
find_nearest_uv_vert(scene, ima, em, co, penalty, &hit);
- if(hit.efa == NULL)
+ if(hit.efa == NULL) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
/* mark 1 vertex as being hit */
for(i=0; i<4; i++)
@@ -1475,8 +1502,10 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
else if(selectmode == UV_SELECT_EDGE) {
/* find edge */
find_nearest_uv_edge(scene, ima, em, co, &hit);
- if(hit.efa == NULL)
+ if(hit.efa == NULL) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
/* mark 2 edge vertices as being hit */
for(i=0; i<4; i++)
@@ -1492,8 +1521,10 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
else if(selectmode == UV_SELECT_FACE) {
/* find face */
find_nearest_uv_face(scene, ima, em, co, &hit);
- if(hit.efa == NULL)
+ if(hit.efa == NULL) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
/* make active */
EM_set_actFace(em, hit.efa);
@@ -1512,11 +1543,15 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
else if(selectmode == UV_SELECT_ISLAND) {
find_nearest_uv_vert(scene, ima, em, co, NULL, &hit);
- if(hit.efa==NULL)
+ if(hit.efa==NULL) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
}
- else
+ else {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
/* do selection */
if(loop) {
@@ -1666,7 +1701,8 @@ static int mouse_select(bContext *C, float co[2], int extend, int loop)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_PASS_THROUGH|OPERATOR_FINISHED;
}
@@ -1718,7 +1754,7 @@ void UV_OT_select(wmOperatorType *ot)
/* ******************** loop select operator **************** */
-static int loop_select_exec(bContext *C, wmOperator *op)
+static int select_loop_exec(bContext *C, wmOperator *op)
{
float co[2];
int extend, loop;
@@ -1730,7 +1766,7 @@ static int loop_select_exec(bContext *C, wmOperator *op)
return mouse_select(C, co, extend, loop);
}
-static int loop_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_loop_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
ARegion *ar= CTX_wm_region(C);
float co[2];
@@ -1742,19 +1778,19 @@ static int loop_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
UI_view2d_region_to_view(&ar->v2d, x, y, &co[0], &co[1]);
RNA_float_set_array(op->ptr, "location", co);
- return loop_select_exec(C, op);
+ return select_loop_exec(C, op);
}
-void UV_OT_loop_select(wmOperatorType *ot)
+void UV_OT_select_loop(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Loop Select";
- ot->idname= "UV_OT_loop_select";
+ ot->idname= "UV_OT_select_loop";
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* api callbacks */
- ot->exec= loop_select_exec;
- ot->invoke= loop_select_invoke;
+ ot->exec= select_loop_exec;
+ ot->invoke= select_loop_invoke;
ot->poll= ED_operator_uvedit;
/* properties */
@@ -1772,12 +1808,13 @@ static int select_linked_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Image *ima= CTX_data_edit_image(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
float limit[2];
int extend;
if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled.");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -1788,6 +1825,7 @@ static int select_linked_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -1814,12 +1852,13 @@ static int unlink_selection_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Image *ima= CTX_data_edit_image(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
BKE_report(op->reports, RPT_ERROR, "Can't unlink selection when sync selection is enabled.");
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
@@ -1841,6 +1880,7 @@ static int unlink_selection_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -1873,7 +1913,7 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
* This only needs to be done when the Mesh is not used for
* selection (so for sticky modes, vertex or location based). */
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
int nverts, i;
@@ -1928,8 +1968,10 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
/*for(a=0, eve= em->verts.first; eve; a++, eve= eve->next)
eve->tmp.l = a; */
- if(vmap == NULL)
+ if(vmap == NULL) {
+ EM_EndEditMesh(obedit->data, em);
return;
+ }
for(efa_index=0, efa= em->faces.first; efa; efa_index++, efa= efa->next) {
if(efa->tmp.l) {
@@ -1989,6 +2031,7 @@ static void uv_faces_do_sticky(bContext *C, SpaceImage *sima, Scene *scene, Obje
}
}
}
+ EM_EndEditMesh(obedit->data, em);
}
static int border_select_exec(bContext *C, wmOperator *op)
@@ -1998,7 +2041,7 @@ static int border_select_exec(bContext *C, wmOperator *op)
Object *obedit= CTX_data_edit_object(C);
Image *ima= CTX_data_edit_image(C);
ARegion *ar= CTX_wm_region(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tface;
rcti rect;
@@ -2110,18 +2153,20 @@ static int border_select_exec(bContext *C, wmOperator *op)
}
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
-
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
-void UV_OT_border_select(wmOperatorType *ot)
+void UV_OT_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Border Select";
- ot->idname= "UV_OT_border_select";
+ ot->idname= "UV_OT_select_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
@@ -2166,7 +2211,7 @@ int circle_select_exec(bContext *C, wmOperator *op)
SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
ARegion *ar= CTX_wm_region(C);
EditFace *efa;
MTFace *tface;
@@ -2204,6 +2249,7 @@ int circle_select_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -2301,7 +2347,7 @@ void UV_OT_snap_cursor(wmOperatorType *ot)
static int snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, View2D *v2d)
{
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tface;
short change= 0;
@@ -2319,12 +2365,13 @@ static int snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, View2D *
}
}
+ EM_EndEditMesh(obedit->data, em);
return change;
}
static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obedit)
{
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
EditVert *eve;
MTFace *tface;
@@ -2399,6 +2446,7 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
if(!change) {
MEM_freeN(coords);
MEM_freeN(usercount);
+ EM_EndEditMesh(obedit->data, em);
return change;
}
@@ -2445,12 +2493,13 @@ static int snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obe
MEM_freeN(coords);
MEM_freeN(usercount);
+ EM_EndEditMesh(obedit->data, em);
return change;
}
static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
{
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
Image *ima= sima->image;
EditFace *efa;
MTFace *tface;
@@ -2475,6 +2524,7 @@ static int snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit)
}
}
+ EM_EndEditMesh(obedit->data, em);
return change;
}
@@ -2536,7 +2586,7 @@ static int pin_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Image *ima= CTX_data_edit_image(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tface;
int clear= RNA_boolean_get(op->ptr, "clear");
@@ -2564,6 +2614,7 @@ static int pin_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -2589,7 +2640,7 @@ static int select_pinned_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
Image *ima= CTX_data_edit_image(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tface;
@@ -2608,6 +2659,7 @@ static int select_pinned_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -2630,7 +2682,7 @@ static int hide_exec(bContext *C, wmOperator *op)
SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
int swap= RNA_boolean_get(op->ptr, "unselected");
@@ -2638,6 +2690,8 @@ static int hide_exec(bContext *C, wmOperator *op)
if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
EM_hide_mesh(em, swap);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -2745,6 +2799,7 @@ static int hide_exec(bContext *C, wmOperator *op)
EM_validate_selections(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -2770,7 +2825,7 @@ static int reveal_exec(bContext *C, wmOperator *op)
SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
@@ -2778,6 +2833,8 @@ static int reveal_exec(bContext *C, wmOperator *op)
if(scene->toolsettings->uv_flag & UV_SYNC_SELECTION) {
EM_reveal_mesh(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -2873,6 +2930,7 @@ static int reveal_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -2918,11 +2976,11 @@ static int set_2d_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
return set_2d_cursor_exec(C, op);
}
-void UV_OT_set_2d_cursor(wmOperatorType *ot)
+void UV_OT_cursor_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set 3D Cursor";
- ot->idname= "UV_OT_set_2d_cursor";
+ ot->idname= "UV_OT_cursor_set";
/* api callbacks */
ot->exec= set_2d_cursor_exec;
@@ -2983,11 +3041,11 @@ static int set_tile_invoke(bContext *C, wmOperator *op, wmEvent *event)
return set_tile_exec(C, op);
}
-void UV_OT_set_tile(wmOperatorType *ot)
+void UV_OT_tile_set(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Tile";
- ot->idname= "UV_OT_set_tile";
+ ot->idname= "UV_OT_tile_set";
/* api callbacks */
ot->exec= set_tile_exec;
@@ -3005,14 +3063,14 @@ void UV_OT_set_tile(wmOperatorType *ot)
void ED_operatortypes_uvedit(void)
{
- WM_operatortype_append(UV_OT_de_select_all);
+ WM_operatortype_append(UV_OT_select_all_toggle);
WM_operatortype_append(UV_OT_select_invert);
WM_operatortype_append(UV_OT_select);
- WM_operatortype_append(UV_OT_loop_select);
+ WM_operatortype_append(UV_OT_select_loop);
WM_operatortype_append(UV_OT_select_linked);
WM_operatortype_append(UV_OT_unlink_selection);
WM_operatortype_append(UV_OT_select_pinned);
- WM_operatortype_append(UV_OT_border_select);
+ WM_operatortype_append(UV_OT_select_border);
WM_operatortype_append(UV_OT_circle_select);
WM_operatortype_append(UV_OT_snap_cursor);
@@ -3038,8 +3096,8 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_reveal);
WM_operatortype_append(UV_OT_hide);
- WM_operatortype_append(UV_OT_set_2d_cursor);
- WM_operatortype_append(UV_OT_set_tile);
+ WM_operatortype_append(UV_OT_cursor_set);
+ WM_operatortype_append(UV_OT_tile_set);
}
void ED_keymap_uvedit(wmWindowManager *wm)
@@ -3049,18 +3107,18 @@ void ED_keymap_uvedit(wmWindowManager *wm)
/* pick selection */
WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1);
- WM_keymap_add_item(keymap, "UV_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0)->ptr, "extend", 1);
+ WM_keymap_add_item(keymap, "UV_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_loop", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0)->ptr, "extend", 1);
/* border/circle selection */
- WM_keymap_add_item(keymap, "UV_OT_border_select", BKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_border_select", BKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "pinned", 1);
+ WM_keymap_add_item(keymap, "UV_OT_select_border", BKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "UV_OT_select_border", BKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "pinned", 1);
WM_keymap_add_item(keymap, "UV_OT_circle_select", CKEY, KM_PRESS, 0, 0);
/* selection manipulation */
WM_keymap_add_item(keymap, "UV_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "UV_OT_unlink_selection", LKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "UV_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "UV_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "UV_OT_select_invert", IKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "UV_OT_select_pinned", PKEY, KM_PRESS, KM_SHIFT, 0);
@@ -3081,8 +3139,8 @@ void ED_keymap_uvedit(wmWindowManager *wm)
WM_keymap_add_item(keymap, "UV_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0);
/* cursor */
- WM_keymap_add_item(keymap, "UV_OT_set_2d_cursor", ACTIONMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "UV_OT_set_tile", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "UV_OT_tile_set", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
transform_keymap_for_space(wm, keymap, SPACE_IMAGE);
}
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index d34c0b916ec..e8a0de28658 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -72,18 +72,22 @@
static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
{
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
- if(ED_uvedit_test(obedit))
+ if(ED_uvedit_test(obedit)) {
+ EM_EndEditMesh(obedit->data, em);
return 1;
+ }
if(em && em->faces.first)
EM_add_data_layer(em, &em->fdata, CD_MTFACE);
- if(!ED_uvedit_test(obedit))
+ if(!ED_uvedit_test(obedit)) {
+ EM_EndEditMesh(obedit->data, em);
return 0;
+ }
// XXX this image is not in context in 3d view .. only
// way to get would be to find the first image window?
@@ -95,6 +99,7 @@ static int ED_uvedit_ensure_uvs(bContext *C, Scene *scene, Object *obedit)
uvedit_face_select(scene, efa, tf);
}
+ EM_EndEditMesh(obedit->data, em);
return 1;
}
@@ -218,7 +223,7 @@ static void minimize_stretch_init(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
MinStretch *ms;
int fill_holes= RNA_boolean_get(op->ptr, "fill_holes");
@@ -400,7 +405,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
ParamHandle *handle;
handle = construct_param_handle(scene, em, 1, 0, 1, 1);
@@ -411,6 +416,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -432,7 +438,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
ParamHandle *handle;
handle= construct_param_handle(scene, em, 1, 0, 1, 1);
@@ -443,6 +449,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -464,15 +471,19 @@ static ParamHandle *liveHandle = NULL;
void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
{
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
short abf = scene->toolsettings->unwrapper == 1;
short fillholes = scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES;
- if(!ED_uvedit_test(obedit)) return;
+ if(!ED_uvedit_test(obedit)) {
+ EM_EndEditMesh(obedit->data, em);
+ return;
+ }
liveHandle = construct_param_handle(scene, em, 0, fillholes, 1, 1);
param_lscm_begin(liveHandle, PARAM_TRUE, abf);
+ EM_EndEditMesh(obedit->data, em);
}
void ED_uvedit_live_unwrap_re_solve(void)
@@ -595,7 +606,7 @@ static void uv_map_transform(bContext *C, wmOperator *op, float center[3], float
/* context checks are messy here, making it work in both 3d view and uv editor */
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
View3D *v3d= CTX_wm_view3d(C);
RegionView3D *rv3d= CTX_wm_region_view3d(C);
/* common operator properties */
@@ -621,6 +632,8 @@ static void uv_map_transform(bContext *C, wmOperator *op, float center[3], float
Mat4One(rotmat);
else
uv_map_rotation_matrix(rotmat, rv3d, obedit, upangledeg, sideangledeg, radius);
+
+ EM_EndEditMesh(obedit->data, em);
}
static void uv_transform_properties(wmOperatorType *ot, int radius)
@@ -773,15 +786,17 @@ static int unwrap_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
ParamHandle *handle;
int method = RNA_enum_get(op->ptr, "method");
int fill_holes = RNA_boolean_get(op->ptr, "fill_holes");
int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
/* add uvs if they don't exist yet */
- if(!ED_uvedit_ensure_uvs(C, scene, obedit))
+ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
handle= construct_param_handle(scene, em, 0, fill_holes, 0, correct_aspect);
@@ -798,6 +813,7 @@ static int unwrap_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -882,15 +898,17 @@ static int from_view_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
ARegion *ar= CTX_wm_region(C);
EditFace *efa;
MTFace *tf;
float rotmat[4][4];
/* add uvs if they don't exist yet */
- if(!ED_uvedit_ensure_uvs(C, scene, obedit))
+ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
if(RNA_boolean_get(op->ptr, "orthographic")) {
uv_map_rotation_matrix(rotmat, ar->regiondata, obedit, 90.0f, 0.0f, 1.0f);
@@ -928,6 +946,7 @@ static int from_view_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -963,13 +982,15 @@ static int reset_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
/* add uvs if they don't exist yet */
- if(!ED_uvedit_ensure_uvs(C, scene, obedit))
+ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->f & SELECT) {
@@ -992,6 +1013,7 @@ static int reset_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -1047,14 +1069,16 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
float center[3], rotmat[4][4];
/* add uvs if they don't exist yet */
- if(!ED_uvedit_ensure_uvs(C, scene, obedit))
+ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
uv_map_transform(C, op, center, rotmat);
@@ -1077,6 +1101,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -1116,14 +1141,16 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
float center[3], rotmat[4][4];
/* add uvs if they don't exist yet */
- if(!ED_uvedit_ensure_uvs(C, scene, obedit))
+ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
uv_map_transform(C, op, center, rotmat);
@@ -1146,6 +1173,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
@@ -1171,15 +1199,17 @@ static int cube_project_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
Object *obedit= CTX_data_edit_object(C);
- EditMesh *em= ((Mesh*)obedit->data)->edit_mesh;
+ EditMesh *em= EM_GetEditMesh((Mesh*)obedit->data);
EditFace *efa;
MTFace *tf;
float no[3], cube_size, *loc, dx, dy;
int cox, coy;
/* add uvs if they don't exist yet */
- if(!ED_uvedit_ensure_uvs(C, scene, obedit))
+ if(!ED_uvedit_ensure_uvs(C, scene, obedit)) {
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_CANCELLED;
+ }
loc= obedit->obmat[3];
cube_size= RNA_float_get(op->ptr, "cube_size");
@@ -1230,6 +1260,7 @@ static int cube_project_exec(bContext *C, wmOperator *op)
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, obedit);
+ EM_EndEditMesh(obedit->data, em);
return OPERATOR_FINISHED;
}
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/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index eadd7affe6a..3cc155af1ad 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -97,7 +97,7 @@ typedef struct ImBuf {
unsigned int encodedsize; /**< Size of data written to encodedbuffer */
unsigned int encodedbuffersize; /**< Size of encodedbuffer */
- float *rect_float; /**< floating point Rect equivilant */
+ float *rect_float; /**< floating point Rect equivalent */
int channels; /**< amount of channels in rect_float (0 = 4 channel default) */
float dither; /**< random dither value, for conversion from float -> byte rect */
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/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 3e618a483e3..e723609f3ae 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -861,7 +861,6 @@ static const char *exr_rgba_channelname(InputFile *file, const char *chan)
for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i)
{
- const Channel &channel = i.channel();
const char *str= i.name();
int len= strlen(str);
if(len) {
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_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 3ce656faf92..9112a714857 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -69,21 +69,43 @@ typedef struct FMod_Generator {
/* generator based on PyExpression */
char expression[256]; /* python expression to use as generator */
- /* simple polynomial generator (y = C[0]*(x^(n)) + C[1]*(x^(n-1)) + ... C[n]) */
- float *poly_coefficients; /* array of the coefficients for the polynomial (poly_order + 1 items long) */
- unsigned int poly_order; /* order of the polynomial (i.e. 1 for linear, 2 for quadratic) */
+ /* general generator information */
+ float *coefficients; /* coefficients array */
+ unsigned int arraysize; /* size of the coefficients array */
+
+ unsigned short poly_order; /* order of polynomial generated (i.e. 1 for linear, 2 for quadratic) */
+ short func_type; /* builtin math function eFMod_Generator_Functions */
+
+ int pad;
/* settings */
short flag; /* settings */
- short mode; /* which 'generator' to use */
+ short mode; /* which 'generator' to use eFMod_Generator_Modes */
} FMod_Generator;
/* generator modes */
enum {
FCM_GENERATOR_POLYNOMIAL = 0,
+ FCM_GENERATOR_POLYNOMIAL_FACTORISED,
+ FCM_GENERATOR_FUNCTION,
FCM_GENERATOR_EXPRESSION,
} eFMod_Generator_Modes;
+/* generator flags */
+enum {
+ /* generator works in conjunction with other modifiers (i.e. doesn't replace those before it) */
+ FCM_GENERATOR_ADDITIVE = (1<<0),
+} eFMod_Generator_Flags;
+
+/* 'function' generator types */
+enum {
+ FCM_GENERATOR_FN_SIN = 0,
+ FCM_GENERATOR_FN_COS,
+ FCM_GENERATOR_FN_TAN,
+ FCM_GENERATOR_FN_SQRT,
+ FCM_GENERATOR_FN_LN,
+} eFMod_Generator_Functions;
+
/* envelope modifier - envelope data */
typedef struct FCM_EnvelopeData {
@@ -215,7 +237,7 @@ typedef struct FCurve {
/* motion data */
BezTriple *bezt; /* user-editable keyframes (array) */
FPoint *fpt; /* 'baked/imported' motion samples (array) */
- int totvert; /* total number of points which define the curve (i.e. size of arrays in FPoints) */
+ unsigned int totvert; /* total number of points which define the curve (i.e. size of arrays in FPoints) */
/* value cache + settings */
float curval; /* value stored from last time curve was evaluated */
@@ -444,7 +466,6 @@ enum {
* be generic (using various placeholder template tags that will be
* replaced with appropriate information from the context).
*/
-// TODO: how should templates work exactly? For now, we only implement the specific KeyingSets...
typedef struct KS_Path {
struct KS_Path *next, *prev;
@@ -452,6 +473,10 @@ typedef struct KS_Path {
ID *id; /* ID block that keyframes are for */
char group[64]; /* name of the group to add to */
+ /* relative paths only */
+ int idtype; /* ID-type that path can be used on */
+ int templates; /* Templates that will be encountered in the path (as set of bitflags) */
+
/* all paths */
char *rna_path; /* dynamically (or statically in the case of predefined sets) path */
int array_index; /* index that path affects */
@@ -476,6 +501,20 @@ enum {
KSP_GROUP_KSNAME,
} eKSP_Grouping;
+/* KS_Path->templates (Template Flags)
+ *
+ * Templates in paths are used to substitute information from the
+ * active context into relavent places in the path strings. This
+ * enum here defines the flags which define which templates are
+ * required by a path before it can be used
+ */
+enum {
+ KSP_TEMPLATE_OBJECT = (1<<0), /* #obj - selected object */
+ KSP_TEMPLATE_PCHAN = (1<<1), /* #pch - selected posechannel */
+ KSP_TEMPLATE_CONSTRAINT = (1<<2), /* #con - active only */
+ KSP_TEMPLATE_NODE = (1<<3), /* #nod - selected node */
+} eKSP_TemplateTypes;
+
/* ---------------- */
/* KeyingSet definition (ks)
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_oops_types.h b/source/blender/makesdna/DNA_outliner_types.h
index 0a6b1a45b11..b19db15d73b 100644
--- a/source/blender/makesdna/DNA_oops_types.h
+++ b/source/blender/makesdna/DNA_outliner_types.h
@@ -1,6 +1,4 @@
/**
- * blenlib/DNA_oops_types.h (mar-2001 nzc)
- *
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -28,11 +26,8 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef DNA_OOPS_TYPES_H
-#define DNA_OOPS_TYPES_H
-
-#define OOPSX 5.0
-#define OOPSY 1.8
+#ifndef DNA_OUTLINER_TYPES_H
+#define DNA_OUTLINER_TYPES_H
#include "DNA_listBase.h"
@@ -48,30 +43,6 @@ typedef struct TreeStore {
TreeStoreElem *data;
} TreeStore;
-typedef struct Oops {
- struct Oops *next, *prev;
- short type, flag, dt, hide;
- float x, y; /* left - bottom */
- float dx, dy; /* shuffle */
- struct ID *id;
- ListBase link;
-} Oops;
-
-#
-#
-typedef struct OopsLink {
- struct OopsLink *next, *prev;
- short type, flag;
- struct ID **idfrom;
- Oops *to, *from; /* from is for temp */
- float xof, yof;
- char name[12];
-} OopsLink;
-
-/* oops->flag (1==SELECT) */
-#define OOPS_DOSELECT 2
-#define OOPS_REFER 4
-
/* TreeStoreElem->flag */
#define TSE_CLOSED 1
#define TSE_SELECTED 2
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 047fcd3b94e..d5828f7e3a3 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -401,10 +401,9 @@ typedef struct Sculpt
} Sculpt;
typedef struct VPaint {
- float r, g, b, a; /* paint color */
- float weight; /* weight paint */
- float size; /* of brush */
- float gamma, mul;
+ struct Brush *brush;
+
+ float gamma, mul; /* should become part of struct Brush? */
short mode, flag;
int tot; /* allocation size of prev buffers */
unsigned int *vpaint_prev; /* previous mesh colors */
@@ -469,6 +468,9 @@ typedef struct ToolSettings {
/* Particle Editing */
struct ParticleEditSettings particle;
+ /* Transform Proportional Area of Effect */
+ float proportional_size;
+
/* Select Group Threshold */
float select_thresh;
@@ -500,12 +502,21 @@ typedef struct ToolSettings {
char skgen_postpro_passes;
char skgen_subdivisions[3];
char skgen_multi_level;
- char skgen_optimisation_method;
-
- char tpad[6];
+ 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 {
@@ -773,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
@@ -782,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 */
@@ -931,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_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index d90527040dd..4ab9aa55b42 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -38,7 +38,9 @@ struct SpaceType;
struct SpaceLink;
struct ARegion;
struct ARegionType;
+struct PanelType;
struct Scene;
+struct uiLayout;
struct wmTimer;
typedef struct bScreen {
@@ -88,6 +90,9 @@ typedef struct ScrEdge {
typedef struct Panel { /* the part from uiBlock that needs saved in file */
struct Panel *next, *prev;
+ struct PanelType *type; /* runtime */
+ struct uiLayout *layout; /* runtime for drawing */
+
char panelname[64], tabname[64]; /* defined as UI_MAX_NAME_STR */
char drawname[64]; /* panelname is identifier for restoring location */
short ofsx, ofsy, sizex, sizey;
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 8cca610b698..8a26a216e79 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -33,7 +33,7 @@
#include "DNA_listBase.h"
#include "DNA_vec_types.h"
-#include "DNA_oops_types.h" /* for TreeStoreElem */
+#include "DNA_outliner_types.h" /* for TreeStoreElem */
#include "DNA_image_types.h" /* ImageUser */
/* Hum ... Not really nice... but needed for spacebuts. */
#include "DNA_view2d_types.h"
@@ -52,6 +52,7 @@ struct FileList;
struct bGPdata;
struct bDopeSheet;
struct FileSelectParams;
+struct FileLayout;
struct bScreen;
struct Scene;
struct wmOperator;
@@ -179,16 +180,7 @@ typedef struct SpaceFile {
struct wmTimer *loadimage_timer;
- /* view settings - XXX - move into own struct */
- short prv_w;
- short prv_h;
- short tile_w;
- short tile_h;
- short tile_border_x;
- short tile_border_y;
- short prv_border_x;
- short prv_border_y;
-
+ struct FileLayout *layout;
} SpaceFile;
@@ -202,10 +194,6 @@ typedef struct SpaceOops {
View2D v2d; /* depricated, copied to region */
- ListBase oops;
- short pin, visiflag, flag, rt;
- void *lockpoin;
-
ListBase tree;
struct TreeStore *treestore;
@@ -214,12 +202,7 @@ typedef struct SpaceOops {
struct TreeStoreElem search_tse;
int search_flags, do_;
- short type, outlinevis, storeflag;
- short deps_flags;
-
- /* RNA */
- char *rnapath;
-
+ short flag, outlinevis, storeflag, pad;
} SpaceOops;
typedef struct SpaceImage {
@@ -278,14 +261,12 @@ typedef struct SpaceText {
int top, viewlines;
short flags, menunr;
- int font_id;
int lheight;
int left;
int showlinenrs;
int tabnumber;
- int pad;
int showsyntax;
int overwrite;
float pix_per_line;
@@ -590,6 +571,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)
@@ -618,35 +600,12 @@ enum {
/* stext->findstr/replacestr */
#define ST_MAX_FIND_STR 256
-/* SpaceOops->type */
-#define SO_OOPS 0
-#define SO_OUTLINER 1
-#define SO_DEPSGRAPH 2
-
/* SpaceOops->flag */
#define SO_TESTBLOCKS 1
#define SO_NEWSELECTED 2
#define SO_HIDE_RESTRICTCOLS 4
#define SO_HIDE_KEYINGSETINFO 8
-/* SpaceOops->visiflag */
-#define OOPS_SCE 1
-#define OOPS_OB 2
-#define OOPS_ME 4
-#define OOPS_CU 8
-#define OOPS_MB 16
-#define OOPS_LT 32
-#define OOPS_LA 64
-#define OOPS_MA 128
-#define OOPS_TE 256
-#define OOPS_IP 512
-#define OOPS_LAY 1024
-#define OOPS_LI 2048
-#define OOPS_IM 4096
-#define OOPS_AR 8192
-#define OOPS_GR 16384
-#define OOPS_CA 32768
-
/* SpaceOops->outlinevis */
#define SO_ALL_SCENES 0
#define SO_CUR_SCENE 1
@@ -747,7 +706,7 @@ enum {
SPACE_EMPTY,
SPACE_VIEW3D,
SPACE_IPO,
- SPACE_OOPS,
+ SPACE_OUTLINER,
SPACE_BUTS,
SPACE_FILE,
SPACE_IMAGE,
diff --git a/source/blender/makesdna/intern/SConscript b/source/blender/makesdna/intern/SConscript
index 6c8f48da251..eae75a1658b 100644
--- a/source/blender/makesdna/intern/SConscript
+++ b/source/blender/makesdna/intern/SConscript
@@ -2,10 +2,13 @@
import sys
import os
+def normpath(path):
+ return os.path.abspath(os.path.normpath(path))
+
Import ('env')
cflags = ''
defines = []
-root_build_dir=env['BF_BUILDDIR']
+root_build_dir=normpath(env['BF_BUILDDIR'])
source_files = ['makesdna.c']
header_files = env.Glob('../*.h')
@@ -31,14 +34,15 @@ if not USE_WINE:
if sys.platform != 'cygwin':
makesdna_tool.Append (CCFLAGS = cflags)
makesdna_tool.Append (CPPDEFINES = defines)
-targetdir = root_build_dir+'/lib'
+targetdir = normpath(root_build_dir+'/lib')
+
if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
targetdir = '#'+targetdir
makesdna_tool.Append (LIBPATH = targetdir)
if env['BF_PROFILE']:
makesdna_tool.Append (LINKFLAGS = env['BF_PROFILE_LINKFLAGS'])
-targetdir = root_build_dir + '/makesdna'
+targetdir = normpath(root_build_dir + '/makesdna')
if not (root_build_dir[0]==os.sep or root_build_dir[1]==':'):
targetdir = '#' + targetdir
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 17547c4eb1d..bf2f0f3900e 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -111,7 +111,7 @@ char *includefiles[] = {
"DNA_fileglobal_types.h",
"DNA_sequence_types.h",
"DNA_effect_types.h",
- "DNA_oops_types.h",
+ "DNA_outliner_types.h",
"DNA_property_types.h",
"DNA_sensor_types.h",
"DNA_controller_types.h",
@@ -1135,7 +1135,7 @@ int main(int argc, char ** argv)
#include "DNA_fileglobal_types.h"
#include "DNA_sequence_types.h"
#include "DNA_effect_types.h"
-#include "DNA_oops_types.h"
+#include "DNA_outliner_types.h"
#include "DNA_property_types.h"
#include "DNA_sensor_types.h"
#include "DNA_controller_types.h"
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 8bc8c58f425..e2d3f85f550 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -25,8 +25,13 @@
#ifndef RNA_ACCESS
#define RNA_ACCESS
+#include "DNA_listBase.h"
#include "RNA_types.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct bContext;
struct ID;
struct Main;
@@ -68,6 +73,7 @@ extern StructRNA RNA_ColorRamp;
extern StructRNA RNA_ColorRampElement;
extern StructRNA RNA_ColorSequence;
extern StructRNA RNA_Constraint;
+extern StructRNA RNA_Context;
extern StructRNA RNA_ControlFluidSettings;
extern StructRNA RNA_Controller;
extern StructRNA RNA_Curve;
@@ -303,6 +309,7 @@ PropertyRNA *RNA_struct_name_property(PointerRNA *ptr);
PropertyRNA *RNA_struct_iterator_property(PointerRNA *ptr);
int RNA_struct_is_ID(PointerRNA *ptr);
+int RNA_struct_is_a(PointerRNA *ptr, StructRNA *srna);
PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier);
const struct ListBase *RNA_struct_defined_properties(StructRNA *srna);
@@ -327,6 +334,7 @@ void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin
void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *softmin, float *softmax, float *step, float *precision);
int RNA_property_string_maxlength(PointerRNA *ptr, PropertyRNA *prop);
+StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **item, int *totitem);
int RNA_property_enum_value(PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value);
@@ -403,6 +411,8 @@ char *RNA_path_back(const char *path);
int RNA_path_resolve(PointerRNA *ptr, const char *path,
PointerRNA *r_ptr, PropertyRNA **r_prop);
+char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop);
+
#if 0
/* Dependency
*
@@ -475,7 +485,9 @@ int RNA_property_is_set(PointerRNA *ptr, const char *name);
/* python compatible string representation of this property, (must be freed!) */
char *RNA_property_as_string(PointerRNA *ptr, PropertyRNA *prop);
-#endif /* RNA_ACCESS */
-
+#ifdef __cplusplus
+}
+#endif
+#endif /* RNA_ACCESS */
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index d80a4e4573e..94a2c51c660 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -33,6 +33,10 @@
#include "DNA_listBase.h"
#include "RNA_types.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Blender RNA */
BlenderRNA *RNA_create(void);
@@ -49,6 +53,7 @@ void RNA_def_struct_name_property(StructRNA *srna, PropertyRNA *prop);
void RNA_def_struct_nested(BlenderRNA *brna, StructRNA *srna, const char *structname);
void RNA_def_struct_flag(StructRNA *srna, int flag);
void RNA_def_struct_refine_func(StructRNA *srna, const char *refine);
+void RNA_def_struct_path_func(StructRNA *srna, const char *path);
void RNA_def_struct_identifier(StructRNA *srna, const char *identifier);
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description);
void RNA_struct_free(BlenderRNA *brna, StructRNA *srna);
@@ -115,6 +120,7 @@ void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, co
void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname);
void RNA_def_property_flag(PropertyRNA *prop, int flag);
+void RNA_def_property_clear_flag(PropertyRNA *prop, int flag);
void RNA_def_property_array(PropertyRNA *prop, int arraylength);
void RNA_def_property_range(PropertyRNA *prop, double min, double max);
@@ -146,6 +152,9 @@ void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const cha
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set);
void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring);
-#endif /* RNA_DEFINE_H */
+#ifdef __cplusplus
+}
+#endif
+#endif /* RNA_DEFINE_H */
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
new file mode 100644
index 00000000000..9cb49fcaf60
--- /dev/null
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -0,0 +1,37 @@
+/**
+ * $Id$
+ *
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation (2008).
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef RNA_ENUM_TYPES
+#define RNA_ENUM_TYPES
+
+#include "RNA_types.h"
+
+/* Types */
+
+extern EnumPropertyItem prop_mode_items[];
+
+#endif /* RNA_ENUM_TYPES */
+
+
+
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 03c6fc1a335..c3dcf4040ea 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -25,9 +25,14 @@
#ifndef RNA_TYPES
#define RNA_TYPES
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct PropertyRNA;
struct StructRNA;
struct BlenderRNA;
+struct IDProperty;
/* Pointer
*
@@ -38,7 +43,6 @@ struct BlenderRNA;
typedef struct PointerRNA {
struct {
- struct StructRNA *type;
void *data;
} id;
@@ -75,28 +79,13 @@ typedef enum PropertyFlag {
/* editable means the property is editable in the user
* interface, properties are editable by default except
* for pointers and collections. */
- PROP_NOT_EDITABLE = 1,
+ PROP_EDITABLE = 1,
/* animateable means the property can be driven by some
* other input, be it animation curves, expressions, ..
* properties are animateable by default except for pointers
* and collections */
- PROP_NOT_ANIMATEABLE = 2,
-
-#if 0
- /* for pointers and collections, means that the struct
- * depends on the data pointed to for evaluation, such
- * that a change in the data pointed to will affect the
- * evaluated result of this struct. */
- PROP_EVALUATE_DEPENDENCY = 8,
- PROP_INVERSE_EVALUATE_DEPENDENCY = 16,
-
- /* for pointers and collections, means that the struct
- * requires the data pointed to for rendering in the,
- * be it the render engine or viewport */
- PROP_RENDER_DEPENDENCY = 32,
- PROP_INVERSE_RENDER_DEPENDENCY = 64,
-#endif
+ PROP_ANIMATEABLE = 2,
/* internal flags */
PROP_BUILTIN = 128,
@@ -118,6 +107,11 @@ typedef struct CollectionPropertyIterator {
PointerRNA ptr;
} CollectionPropertyIterator;
+typedef struct CollectionPointerLink {
+ struct CollectionPointerLink *next, *prev;
+ PointerRNA ptr;
+} CollectionPointerLink;
+
/* Iterator Utility */
typedef struct EnumPropertyItem {
@@ -148,6 +142,10 @@ typedef struct StructRNA StructRNA;
typedef struct BlenderRNA BlenderRNA;
+#ifdef __cplusplus
+}
+#endif
+
#endif /* RNA_TYPES */
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 15be45ae59b..934e009eebc 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -34,6 +34,7 @@ SET(DEFSRC
rna_cloth.c
rna_color.c
rna_constraint.c
+ rna_context.c
rna_controller.c
rna_curve.c
rna_fluidsim.c
@@ -97,7 +98,7 @@ ADD_CUSTOM_COMMAND(
)
# Build bf_rna
-SET(SRC rna_access.c rna_dependency.c ${GENSRC})
+SET(SRC rna_access.c ${GENSRC})
BLENDERLIB(bf_rna "${SRC}" "${INC}")
MESSAGE(STATUS "Configuring makesrna")
diff --git a/source/blender/makesrna/intern/Makefile b/source/blender/makesrna/intern/Makefile
index aad4acdbf38..070f6f264bd 100644
--- a/source/blender/makesrna/intern/Makefile
+++ b/source/blender/makesrna/intern/Makefile
@@ -26,7 +26,7 @@ LIBNAME = rna
DIR = $(OCGDIR)/blender/makesrna
ALLRNA = $(wildcard rna_*.c)
-DEFRNA = $(filter-out %rna_define.c, $(filter-out %rna_dependency.c, $(filter-out %rna_access.c, $(ALLRNA))))
+DEFRNA = $(filter-out %rna_define.c, $(filter-out %rna_access.c, $(ALLRNA)))
GENSRCS = $(patsubst rna_%.c, rna_%_gen.c, $(DEFRNA))
GENTARGET = $(patsubst %.c, $(DIR)/$(DEBUG_DIR)%.c, $(GENSRCS))
@@ -34,10 +34,14 @@ GENTARGET = $(patsubst %.c, $(DIR)/$(DEBUG_DIR)%.c, $(GENSRCS))
MAKESRCS = $(DEFRNA) makesrna.c rna_define.c
MAKEOBJS = $(patsubst %.c, $(DIR)/$(DEBUG_DIR)%.o, $(MAKESRCS))
-CSRCS = $(GENSRCS) rna_access.c rna_dependency.c
+CSRCS = $(GENSRCS) rna_access.c
include nan_compile.mk
+ifdef NAN_DEPEND
+-include $(MAKESRCS:%.c=$(DIR)/$(DEBUG_DIR)%.d)
+endif
+
CFLAGS += $(LEVEL_1_C_WARNINGS)
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index ac05eab14d1..7bd52114792 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -2,19 +2,19 @@
import sys
import os
-ap = os.path.abspath
+def normpath(path):
+ return os.path.abspath(os.path.normpath(path))
Import ('env')
cflags = '-Wall'
defines = []
-root_build_dir=ap(env['BF_BUILDDIR'])
+root_build_dir=normpath(env['BF_BUILDDIR'])
source_files = env.Glob('*.c')
# making rna_access.c part of both makesrna and blender seems to
# give conflict, how to solve?
source_files.remove('rna_access.c')
-source_files.remove('rna_dependency.c')
generated_files = source_files[:]
generated_files.remove('rna_define.c')
@@ -76,20 +76,20 @@ rna_dict = rna.Dictionary()
rna.Depends (generated_files, makesrna)
# this seems bad, how to retrieve it from scons?
-build_dir = ap(root_build_dir + '/source/blender/makesrna/intern') + "/"
+build_dir = root_build_dir + '/source/blender/makesrna/intern/'
if env['OURPLATFORM'] != 'linuxcross':
- rna.Command (generated_files, '', ap(root_build_dir+os.sep+"makesrna ") + " \"" + build_dir + "\"")
+ rna.Command (generated_files, '', root_build_dir+os.sep+"makesrna " + build_dir)
else:
- rna.Command (generated_files, '', ap(root_build_dir+os.sep+"makesrna.exe") + " \"" + build_dir + "\"")
+ rna.Command (generated_files, '', root_build_dir+os.sep+"makesrna.exe " + build_dir)
if USE_WINE:
- rna.Command (generated_files, '', ap('wine ' + root_build_dir+os.sep+"makesrna.exe") + " \"" + build_dir + "\"")
+ rna.Command (generated_files, '', 'wine ' + root_build_dir+os.sep+"makesrna.exe " + build_dir)
else:
- rna.Command (generated_files, '', ap(root_build_dir+os.sep+"makesrna.exe") + " \"" + build_dir + "\"")
+ rna.Command (generated_files, '', root_build_dir+os.sep+"makesrna.exe " + build_dir)
-obj = ['intern/rna_access.c', 'intern/rna_dependency.c']
+obj = ['intern/rna_access.c']
for generated_file in generated_files:
obj += ['intern/' + generated_file]
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 4b7b5babc2e..0d124a121d5 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -261,9 +261,9 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr
PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
rna_print_data_get(f, dp);
if(dp->dnapointerlevel == 0)
- fprintf(f, " return rna_pointer_inherit_refine(ptr, &RNA_%s, &data->%s);\n", (char*)pprop->structtype, dp->dnaname);
+ fprintf(f, " return rna_pointer_inherit_refine(ptr, &RNA_%s, &data->%s);\n", (char*)pprop->type, dp->dnaname);
else
- fprintf(f, " return rna_pointer_inherit_refine(ptr, &RNA_%s, data->%s);\n", (char*)pprop->structtype, dp->dnaname);
+ fprintf(f, " return rna_pointer_inherit_refine(ptr, &RNA_%s, data->%s);\n", (char*)pprop->type, dp->dnaname);
}
fprintf(f, "}\n\n");
break;
@@ -277,7 +277,7 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr
if(strcmp(manualfunc, "rna_iterator_listbase_get") == 0 ||
strcmp(manualfunc, "rna_iterator_array_get") == 0 ||
strcmp(manualfunc, "rna_iterator_array_dereference_get") == 0)
- fprintf(f, " return rna_pointer_inherit_refine(&iter->parent, &RNA_%s, %s(iter));\n", (cprop->structtype)? (char*)cprop->structtype: "UnknownType", manualfunc);
+ fprintf(f, " return rna_pointer_inherit_refine(&iter->parent, &RNA_%s, %s(iter));\n", (cprop->type)? (char*)cprop->type: "UnknownType", manualfunc);
else
fprintf(f, " return %s(iter);\n", manualfunc);
}
@@ -290,7 +290,7 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr
fprintf(f, "{\n");
if(manualfunc) {
- fprintf(f, " return %s(ptr, values);\n", manualfunc);
+ fprintf(f, " %s(ptr, values);\n", manualfunc);
}
else {
rna_print_data_get(f, dp);
@@ -384,12 +384,14 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr
char *func;
int i;
- if(prop->flag & (PROP_IDPROPERTY|PROP_NOT_EDITABLE))
+ if(!(prop->flag & PROP_EDITABLE))
+ return NULL;
+ if(prop->flag & PROP_IDPROPERTY)
return NULL;
if(!manualfunc) {
if(!dp->dnastructname || !dp->dnaname) {
- if(!(prop->flag & PROP_NOT_EDITABLE)) {
+ if(prop->flag & PROP_EDITABLE) {
fprintf(stderr, "rna_def_property_set_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
DefRNA.error= 1;
}
@@ -732,8 +734,8 @@ static void rna_def_property_funcs(FILE *f, PropertyDefRNA *dp)
pprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (char*)pprop->get);
pprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (char*)pprop->set);
- if(!pprop->structtype && !pprop->get) {
- fprintf(stderr, "rna_def_property_funcs: %s.%s, pointer must have either type function or fixed type.\n", srna->identifier, prop->identifier);
+ if(!pprop->type) {
+ fprintf(stderr, "rna_def_property_funcs: %s.%s, pointer must have a struct type.\n", srna->identifier, prop->identifier);
DefRNA.error= 1;
}
break;
@@ -764,8 +766,8 @@ static void rna_def_property_funcs(FILE *f, PropertyDefRNA *dp)
DefRNA.error= 1;
}
}
- if(!cprop->structtype && !cprop->get) {
- fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have either type function or fixed type.\n", srna->identifier, prop->identifier);
+ if(!cprop->type) {
+ fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a struct type.\n", srna->identifier, prop->identifier);
DefRNA.error= 1;
}
break;
@@ -861,6 +863,154 @@ static void rna_def_property_funcs_header(FILE *f, PropertyDefRNA *dp)
fprintf(f, "\n");
}
+static void rna_def_property_funcs_header_cpp(FILE *f, PropertyDefRNA *dp)
+{
+ PropertyRNA *prop;
+ StructRNA *srna;
+
+ srna= dp->srna;
+ prop= dp->prop;
+
+ if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN))
+ return;
+
+ if(prop->name && prop->description && strcmp(prop->description, "") != 0)
+ fprintf(f, "\t/* %s: %s */\n", prop->name, prop->description);
+ else if(prop->name)
+ fprintf(f, "\t/* %s */\n", prop->name);
+ else
+ fprintf(f, "\t/* */\n");
+
+ switch(prop->type) {
+ case PROP_BOOLEAN: {
+ if(!prop->arraylength)
+ fprintf(f, "\tbool %s(void);", prop->identifier);
+ else
+ fprintf(f, "\tArray<int, %d> %s(void);", prop->arraylength, prop->identifier);
+ break;
+ }
+ case PROP_INT: {
+ if(!prop->arraylength)
+ fprintf(f, "\tint %s(void);", prop->identifier);
+ else
+ fprintf(f, "\tArray<int, %d> %s(void);", prop->arraylength, prop->identifier);
+ break;
+ }
+ case PROP_FLOAT: {
+ if(!prop->arraylength)
+ fprintf(f, "\tfloat %s(void);", prop->identifier);
+ else
+ fprintf(f, "\tArray<float, %d> %s(void);", prop->arraylength, prop->identifier);
+ break;
+ }
+ case PROP_ENUM: {
+ EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
+ int i;
+
+ if(eprop->item) {
+ fprintf(f, "\tenum %s_enum {\n", prop->identifier);
+
+ for(i=0; i<eprop->totitem; i++)
+ fprintf(f, "\t\t%s_%s = %d,\n", prop->identifier, eprop->item[i].identifier, eprop->item[i].value);
+
+ fprintf(f, "\t};\n");
+ }
+
+ fprintf(f, "\t%s_enum %s(void);", prop->identifier, prop->identifier);
+ break;
+ }
+ case PROP_STRING: {
+ fprintf(f, "\tstd::string %s(void);", prop->identifier);
+ break;
+ }
+ case PROP_POINTER: {
+ PointerPropertyRNA *pprop= (PointerPropertyRNA*)dp->prop;
+
+ if(pprop->type)
+ fprintf(f, "\t%s %s(void);", (char*)pprop->type, prop->identifier);
+ else
+ fprintf(f, "\t%s %s(void);", "UnknownType", prop->identifier);
+ break;
+ }
+ case PROP_COLLECTION: {
+ CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)dp->prop;
+
+ if(cprop->type)
+ fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", (char*)cprop->type, srna->identifier, prop->identifier);
+ else
+ fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, prop->identifier);
+ break;
+ }
+ }
+
+ fprintf(f, "\n");
+}
+
+static void rna_def_property_funcs_impl_cpp(FILE *f, PropertyDefRNA *dp)
+{
+ PropertyRNA *prop;
+ StructRNA *srna;
+
+ srna= dp->srna;
+ prop= dp->prop;
+
+ if(prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN))
+ return;
+
+ switch(prop->type) {
+ case PROP_BOOLEAN: {
+ if(!prop->arraylength)
+ fprintf(f, "\tBOOLEAN_PROPERTY(%s, %s)", srna->identifier, prop->identifier);
+ else
+ fprintf(f, "\tBOOLEAN_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->arraylength, prop->identifier);
+ break;
+ }
+ case PROP_INT: {
+ if(!prop->arraylength)
+ fprintf(f, "\tINT_PROPERTY(%s, %s)", srna->identifier, prop->identifier);
+ else
+ fprintf(f, "\tINT_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->arraylength, prop->identifier);
+ break;
+ }
+ case PROP_FLOAT: {
+ if(!prop->arraylength)
+ fprintf(f, "\tFLOAT_PROPERTY(%s, %s)", srna->identifier, prop->identifier);
+ else
+ fprintf(f, "\tFLOAT_ARRAY_PROPERTY(%s, %d, %s)", srna->identifier, prop->arraylength, prop->identifier);
+ break;
+ }
+ case PROP_ENUM: {
+ fprintf(f, "\tENUM_PROPERTY(%s_enum, %s, %s)", prop->identifier, srna->identifier, prop->identifier);
+
+ break;
+ }
+ case PROP_STRING: {
+ fprintf(f, "\tSTRING_PROPERTY(%s, %s)", srna->identifier, prop->identifier);
+ break;
+ }
+ case PROP_POINTER: {
+ PointerPropertyRNA *pprop= (PointerPropertyRNA*)dp->prop;
+
+ if(pprop->type)
+ fprintf(f, "\tPOINTER_PROPERTY(%s, %s, %s)", (char*)pprop->type, srna->identifier, prop->identifier);
+ else
+ fprintf(f, "\tPOINTER_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, prop->identifier);
+ break;
+ }
+ case PROP_COLLECTION: {
+ /*CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)dp->prop;
+
+ if(cprop->type)
+ fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", (char*)cprop->type, srna->identifier, prop->identifier);
+ else
+ fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s)", "UnknownType", srna->identifier, prop->identifier);*/
+ break;
+ }
+ }
+
+ fprintf(f, "\n");
+}
+
static const char *rna_find_type(const char *type)
{
StructDefRNA *ds;
@@ -890,14 +1040,14 @@ static void rna_auto_types()
if(dp->prop->type == PROP_POINTER) {
PointerPropertyRNA *pprop= (PointerPropertyRNA*)dp->prop;
- if(!pprop->structtype && !pprop->get)
- pprop->structtype= (StructRNA*)rna_find_type(dp->dnatype);
+ if(!pprop->type && !pprop->get)
+ pprop->type= (StructRNA*)rna_find_type(dp->dnatype);
}
else if(dp->prop->type== PROP_COLLECTION) {
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)dp->prop;
- if(!cprop->structtype && !cprop->get && strcmp(dp->dnatype, "ListBase")==0)
- cprop->structtype= (StructRNA*)rna_find_type(dp->dnatype);
+ if(!cprop->type && !cprop->get && strcmp(dp->dnatype, "ListBase")==0)
+ cprop->type= (StructRNA*)rna_find_type(dp->dnatype);
}
}
}
@@ -1022,7 +1172,7 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
switch(prop->type) {
case PROP_ENUM: {
EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
- int i;
+ int i, defaultfound= 0;
if(eprop->item) {
fprintf(f, "static EnumPropertyItem rna_%s_%s_items[%d] = {", srna->identifier, prop->identifier, eprop->totitem);
@@ -1034,9 +1184,17 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
rna_print_c_string(f, eprop->item[i].description); fprintf(f, "}");
if(i != eprop->totitem-1)
fprintf(f, ", ");
+
+ if(eprop->defaultvalue == eprop->item[i].value)
+ defaultfound= 1;
}
fprintf(f, "};\n\n");
+
+ if(!defaultfound) {
+ fprintf(stderr, "rna_generate_structs: %s.%s, enum default is not in items.\n", srna->identifier, prop->identifier);
+ DefRNA.error= 1;
+ }
}
else {
fprintf(stderr, "rna_generate_structs: %s.%s, enum must have items defined.\n", srna->identifier, prop->identifier);
@@ -1171,14 +1329,14 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
case PROP_POINTER: {
PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
fprintf(f, "\t%s, %s, ", rna_function_string(pprop->get), rna_function_string(pprop->set));
- if(pprop->structtype) fprintf(f, "&RNA_%s\n", (char*)pprop->structtype);
+ if(pprop->type) fprintf(f, "&RNA_%s\n", (char*)pprop->type);
else fprintf(f, "NULL\n");
break;
}
case PROP_COLLECTION: {
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, ", rna_function_string(cprop->begin), rna_function_string(cprop->next), rna_function_string(cprop->end), rna_function_string(cprop->get), rna_function_string(cprop->length), rna_function_string(cprop->lookupint), rna_function_string(cprop->lookupstring));
- if(cprop->structtype) fprintf(f, "&RNA_%s\n", (char*)cprop->structtype);
+ if(cprop->type) fprintf(f, "&RNA_%s\n", (char*)cprop->type);
else fprintf(f, "NULL\n");
break;
}
@@ -1193,7 +1351,9 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
else fprintf(f, "\tNULL, ");
if(srna->prev) fprintf(f, "&RNA_%s,\n", srna->prev->identifier);
else fprintf(f, "NULL,\n");
-
+
+ fprintf(f, "\tNULL,\n"); /* PyType - Cant initialize here */
+
fprintf(f, "\t");
rna_print_c_string(f, srna->identifier);
fprintf(f, ", %d, ", srna->flag);
@@ -1225,6 +1385,7 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
else fprintf(f, "\tNULL,\n");
fprintf(f, "\t%s,\n", rna_function_string(srna->refine));
+ fprintf(f, "\t%s,\n", rna_function_string(srna->path));
prop= srna->properties.first;
if(prop) fprintf(f, "\t{(PropertyRNA*)&rna_%s_%s, ", srna->identifier, prop->identifier);
@@ -1245,6 +1406,7 @@ typedef struct RNAProcessItem {
} RNAProcessItem;
RNAProcessItem PROCESS_ITEMS[]= {
+ {"rna_rna.c", RNA_def_rna},
{"rna_ID.c", RNA_def_ID},
{"rna_texture.c", RNA_def_texture},
{"rna_action.c", RNA_def_action},
@@ -1256,6 +1418,7 @@ RNAProcessItem PROCESS_ITEMS[]= {
{"rna_cloth.c", RNA_def_cloth},
{"rna_color.c", RNA_def_color},
{"rna_constraint.c", RNA_def_constraint},
+ {"rna_context.c", RNA_def_context},
{"rna_controller.c", RNA_def_controller},
{"rna_curve.c", RNA_def_curve},
{"rna_fluidsim.c", RNA_def_fluidsim},
@@ -1277,7 +1440,6 @@ RNAProcessItem PROCESS_ITEMS[]= {
{"rna_pose.c", RNA_def_pose},
{"rna_property.c", RNA_def_gameproperty},
{"rna_radio.c", RNA_def_radio},
- {"rna_rna.c", RNA_def_rna},
{"rna_scene.c", RNA_def_scene},
{"rna_screen.c", RNA_def_screen},
{"rna_scriptlink.c", RNA_def_scriptlink},
@@ -1357,6 +1519,8 @@ static void rna_generate_header(BlenderRNA *brna, FILE *f)
fprintf(f, "#include \"RNA_types.h\"\n\n");
+ fprintf(f, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n");
+
fprintf(f, "#define FOREACH_BEGIN(property, sptr, itemptr) \\\n");
fprintf(f, " { \\\n");
fprintf(f, " CollectionPropertyIterator rna_macro_iter; \\\n");
@@ -1383,7 +1547,172 @@ static void rna_generate_header(BlenderRNA *brna, FILE *f)
rna_def_property_funcs_header(f, dp);
}
- fprintf(f, "#endif /* __RNA_BLENDER_H__ */\n");
+ fprintf(f, "#ifdef __cplusplus\n}\n#endif\n\n");
+
+ fprintf(f, "#endif /* __RNA_BLENDER_H__ */\n\n");
+}
+
+static const char *cpp_classes = ""
+"\n"
+"#include <string>\n"
+"\n"
+"namespace RNA {\n"
+"\n"
+"#define BOOLEAN_PROPERTY(sname, identifier) \\\n"
+" bool sname::identifier(void) { return (bool)sname##_##identifier##_get(&ptr); }\n"
+"\n"
+"#define BOOLEAN_ARRAY_PROPERTY(sname, size, identifier) \\\n"
+" Array<int,size> sname::identifier(void) \\\n"
+" { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n"
+"\n"
+"#define INT_PROPERTY(sname, identifier) \\\n"
+" int sname::identifier(void) { return sname##_##identifier##_get(&ptr); }\n"
+"\n"
+"#define INT_ARRAY_PROPERTY(sname, size, identifier) \\\n"
+" Array<int,size> sname::identifier(void) \\\n"
+" { Array<int, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n"
+"\n"
+"#define FLOAT_PROPERTY(sname, identifier) \\\n"
+" float sname::identifier(void) { return sname##_##identifier##_get(&ptr); }\n"
+"\n"
+"#define FLOAT_ARRAY_PROPERTY(sname, size, identifier) \\\n"
+" Array<float,size> sname::identifier(void) \\\n"
+" { Array<float, size> ar; sname##_##identifier##_get(&ptr, ar.data); return ar; }\n"
+"\n"
+"#define ENUM_PROPERTY(type, sname, identifier) \\\n"
+" sname::type sname::identifier(void) { return (type)sname##_##identifier##_get(&ptr); }\n"
+"\n"
+"#define STRING_PROPERTY(sname, identifier) \\\n"
+" std::string sname::identifier(void) { \\\n"
+" int len= sname##_##identifier##_length(&ptr); \\\n"
+" std::string str; str.resize(len); \\\n"
+" sname##_##identifier##_get(&ptr, &str[0]); return str; } \\\n"
+"\n"
+"#define POINTER_PROPERTY(type, sname, identifier) \\\n"
+" type sname::identifier(void) { return type(sname##_##identifier##_get(&ptr)); }\n"
+"\n"
+"#define COLLECTION_PROPERTY(type, sname, identifier) \\\n"
+" typedef CollectionIterator<type, sname##_##identifier##_begin, \\\n"
+" sname##_##identifier##_next, sname##_##identifier##_end> identifier##_iterator; \\\n"
+" Collection<sname, type, sname##_##identifier##_begin, \\\n"
+" sname##_##identifier##_next, sname##_##identifier##_end> identifier;\n"
+"\n"
+"class Pointer {\n"
+"public:\n"
+" Pointer(const PointerRNA& p) : ptr(p) { }\n"
+" operator const PointerRNA&() { return ptr; }\n"
+" bool is_a(StructRNA *type) { return RNA_struct_is_a(&ptr, type); }\n"
+" operator void*() { return ptr.data; }\n"
+" operator bool() { return ptr.data != NULL; }\n"
+"\n"
+" PointerRNA ptr;\n"
+"};\n"
+"\n"
+"\n"
+"template<typename T, int Tsize>\n"
+"class Array {\n"
+"public:\n"
+" T data[Tsize];\n"
+" operator T*() { return data; }\n"
+"};\n"
+"\n"
+"typedef void (*TBeginFunc)(CollectionPropertyIterator *iter, PointerRNA *ptr);\n"
+"typedef void (*TNextFunc)(CollectionPropertyIterator *iter);\n"
+"typedef void (*TEndFunc)(CollectionPropertyIterator *iter);\n"
+"\n"
+"template<typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n"
+"class CollectionIterator {\n"
+"public:\n"
+" CollectionIterator() : t(iter.ptr), init(false) { iter.valid= false; }\n"
+" ~CollectionIterator(void) { if(init) Tend(&iter); };\n"
+" const CollectionIterator<T, Tbegin, Tnext, Tend>& operator=(const CollectionIterator<T, Tbegin, Tnext, Tend>& copy)\n"
+" { if(init) Tend(&iter); iter= copy.iter; if(iter.internal) iter.internal= MEM_dupallocN(iter.internal); t= copy.t; init= copy.init; return *this; }\n"
+"\n"
+" operator bool(void)\n"
+" { return iter.valid != 0; }\n"
+" const CollectionIterator<T, Tbegin, Tnext, Tend>& operator++() { Tnext(&iter); t = T(iter.ptr); return *this; }\n"
+" T& operator*(void) { return t; }\n"
+" T* operator->(void) { return &t; }\n"
+" bool operator==(const CollectionIterator<T, Tbegin, Tnext, Tend>& other) { return iter.valid == other.iter.valid; }\n"
+" bool operator!=(const CollectionIterator<T, Tbegin, Tnext, Tend>& other) { return iter.valid != other.iter.valid; }\n"
+"\n"
+" void begin(const Pointer& ptr)\n"
+" { if(init) Tend(&iter); Tbegin(&iter, (PointerRNA*)&ptr.ptr); t = T(iter.ptr); init = true; }\n"
+"\n"
+"private:\n"
+" CollectionPropertyIterator iter;\n"
+" T t;\n"
+" bool init;\n"
+"};\n"
+"\n"
+"template<typename Tp, typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n"
+"class Collection {\n"
+"public:\n"
+" Collection(const PointerRNA& p) : ptr(p) {}\n"
+"\n"
+" CollectionIterator<T, Tbegin, Tnext, Tend> begin()\n"
+" { CollectionIterator<T, Tbegin, Tnext, Tend> iter; iter.begin(ptr); return iter; }\n"
+" CollectionIterator<T, Tbegin, Tnext, Tend> end()\n"
+" { return CollectionIterator<T, Tbegin, Tnext, Tend>(); } /* test */ \n"
+"\n"
+"private:\n"
+" PointerRNA ptr;\n"
+"};\n"
+"\n";
+
+static void rna_generate_header_cpp(BlenderRNA *brna, FILE *f)
+{
+ StructDefRNA *ds;
+ PropertyDefRNA *dp;
+ StructRNA *srna;
+
+ fprintf(f, "\n#ifndef __RNA_BLENDER_CPP_H__\n");
+ fprintf(f, "#define __RNA_BLENDER_CPP_H__\n\n");
+
+ fprintf(f, "/* Automatically generated classes for the Data API.\n"
+ " Do not edit manually, changes will be overwritten. */\n\n");
+
+ fprintf(f, "#include \"RNA_blender.h\"\n");
+ fprintf(f, "#include \"RNA_types.h\"\n");
+
+ fprintf(f, cpp_classes);
+
+ fprintf(f, "/**************** Declarations ****************/\n\n");
+
+ for(ds=DefRNA.structs.first; ds; ds=ds->next)
+ fprintf(f, "class %s;\n", ds->srna->identifier);
+ fprintf(f, "\n");
+
+ for(ds=DefRNA.structs.first; ds; ds=ds->next) {
+ srna= ds->srna;
+
+ fprintf(f, "/**************** %s ****************/\n\n", srna->name);
+
+ fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base)? srna->base->identifier: "Pointer");
+ fprintf(f, "public:\n");
+ fprintf(f, "\t%s(const PointerRNA& ptr) :\n\t\t%s(ptr)", srna->identifier, (srna->base)? srna->base->identifier: "Pointer");
+ for(dp=ds->properties.first; dp; dp=dp->next)
+ if(!(dp->prop->flag & (PROP_IDPROPERTY|PROP_BUILTIN)))
+ if(dp->prop->type == PROP_COLLECTION)
+ fprintf(f, ",\n\t\t%s(ptr)", dp->prop->identifier);
+ fprintf(f, "\n\t\t{}\n\n");
+
+ for(dp=ds->properties.first; dp; dp=dp->next)
+ rna_def_property_funcs_header_cpp(f, dp);
+ fprintf(f, "};\n\n");
+ }
+
+
+ fprintf(f, "/**************** Implementation ****************/\n");
+
+ for(ds=DefRNA.structs.first; ds; ds=ds->next) {
+ for(dp=ds->properties.first; dp; dp=dp->next)
+ rna_def_property_funcs_impl_cpp(f, dp);
+
+ fprintf(f, "\n");
+ }
+
+ fprintf(f, "}\n\n#endif /* __RNA_BLENDER_CPP_H__ */\n\n");
}
static void make_bad_file(char *file)
@@ -1415,10 +1744,34 @@ static int rna_preprocess(char *outfile)
}
rna_auto_types();
- rna_sort(brna);
+
+
+ /* create RNA_blender_cpp.h */
+ strcpy(deffile, outfile);
+ strcat(deffile, "RNA_blender_cpp.h");
status= (DefRNA.error != 0);
+ if(status) {
+ make_bad_file(deffile);
+ }
+ else {
+ file = fopen(deffile, "w");
+
+ if(!file) {
+ printf ("Unable to open file: %s\n", deffile);
+ status = 1;
+ }
+ else {
+ rna_generate_header_cpp(brna, file);
+ fclose(file);
+
+ status= (DefRNA.error != 0);
+ }
+ }
+
+ rna_sort(brna);
+
/* create rna_gen_*.c files */
for(i=0; PROCESS_ITEMS[i].filename; i++) {
strcpy(deffile, outfile);
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 97c87c6a962..5955f16f916 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -33,6 +33,7 @@
#ifdef RNA_RUNTIME
#include "BKE_idprop.h"
+#include "BKE_library.h"
/* name functions that ignore the first two ID characters */
void rna_ID_name_get(PointerRNA *ptr, char *value)
@@ -51,6 +52,7 @@ void rna_ID_name_set(PointerRNA *ptr, const char *value)
{
ID *id= (ID*)ptr->data;
BLI_strncpy(id->name+2, value, sizeof(id->name)-2);
+ test_idbutton(id->name+2);
}
StructRNA *rna_ID_refine(PointerRNA *ptr)
@@ -144,7 +146,8 @@ static void rna_def_ID_properties(BlenderRNA *brna)
/* IDP_GROUP */
prop= RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_EXPORT|PROP_NOT_EDITABLE|PROP_IDPROPERTY);
+ RNA_def_property_flag(prop, PROP_EXPORT|PROP_IDPROPERTY);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "IDPropertyGroup");
prop= RNA_def_property(srna, "collection", PROP_COLLECTION, PROP_NONE);
@@ -171,7 +174,6 @@ static void rna_def_ID(BlenderRNA *brna)
RNA_def_struct_refine_func(srna, "rna_ID_refine");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* must be unique */
RNA_def_property_ui_text(prop, "Name", "Unique datablock ID name.");
RNA_def_property_string_funcs(prop, "rna_ID_name_get", "rna_ID_name_length", "rna_ID_name_set");
RNA_def_property_string_maxlength(prop, sizeof(((ID*)NULL)->name)-2);
@@ -179,7 +181,7 @@ static void rna_def_ID(BlenderRNA *brna)
prop= RNA_def_property(srna, "users", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "us");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Users", "Number of times this datablock is referenced.");
prop= RNA_def_property(srna, "fake_user", PROP_BOOLEAN, PROP_NONE);
@@ -189,7 +191,7 @@ static void rna_def_ID(BlenderRNA *brna)
prop= RNA_def_property(srna, "library", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "lib");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Library", "Library file the datablock is linked from.");
}
@@ -203,7 +205,7 @@ static void rna_def_library(BlenderRNA *brna)
prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "name");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Filename", "Path to the library .blend file.");
}
void RNA_def_ID(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index b19faee38b9..3fcc2d18487 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -55,7 +55,6 @@ void RNA_exit()
void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr)
{
- r_ptr->id.type= NULL;
r_ptr->id.data= NULL;
r_ptr->type= &RNA_Main;
r_ptr->data= main;
@@ -72,7 +71,6 @@ void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
idtype= rna_ID_refine(&tmp);
}
- r_ptr->id.type= idtype;
r_ptr->id.data= id;
r_ptr->type= idtype;
r_ptr->data= id;
@@ -89,7 +87,6 @@ void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
idtype= rna_ID_refine(&tmp);
}
- r_ptr->id.type= idtype;
r_ptr->id.data= id;
r_ptr->type= type;
r_ptr->data= data;
@@ -99,22 +96,37 @@ static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerR
{
if(type && type->flag & STRUCT_ID) {
ptr->id.data= ptr->data;
- ptr->id.type= type;
}
else {
ptr->id.data= parent->id.data;
- ptr->id.type= parent->id.type;
}
}
void RNA_blender_rna_pointer_create(PointerRNA *r_ptr)
{
- r_ptr->id.type= NULL;
r_ptr->id.data= NULL;
r_ptr->type= &RNA_BlenderRNA;
r_ptr->data= &BLENDER_RNA;
}
+PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
+{
+ PointerRNA result;
+
+ if(data) {
+ result.data= data;
+ result.type= type;
+ rna_pointer_inherit_id(type, ptr, &result);
+
+ if(type->refine)
+ result.type= type->refine(&result);
+ }
+ else
+ memset(&result, 0, sizeof(result));
+
+ return result;
+}
+
/* ID Properties */
IDProperty *rna_idproperties_get(PointerRNA *ptr, int create)
@@ -283,6 +295,18 @@ int RNA_struct_is_ID(PointerRNA *ptr)
return (ptr->type->flag & STRUCT_ID) != 0;
}
+int RNA_struct_is_a(PointerRNA *ptr, StructRNA *srna)
+{
+ StructRNA *type;
+
+ /* ptr->type is always maximally refined */
+ for(type=ptr->type; type; type=type->base)
+ if(type == srna)
+ return 1;
+
+ return 0;
+}
+
PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
{
CollectionPropertyIterator iter;
@@ -294,7 +318,7 @@ PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
prop= NULL;
for(; iter.valid; RNA_property_collection_next(&iter), i++) {
- if(strcmp(identifier, RNA_property_identifier(&iter.ptr, iter.ptr.data)) == 0) {
+ if(strcmp(identifier, RNA_property_identifier(ptr, iter.ptr.data)) == 0) {
prop= iter.ptr.data;
break;
}
@@ -431,6 +455,19 @@ int RNA_property_string_maxlength(PointerRNA *ptr, PropertyRNA *prop)
return sprop->maxlength;
}
+StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
+{
+ PointerPropertyRNA *pprop;
+
+ rna_idproperty_check(&prop, ptr);
+ pprop= (PointerPropertyRNA*)prop;
+
+ if(pprop->type)
+ return pprop->type;
+
+ return &RNA_UnknownType;
+}
+
void RNA_property_enum_items(PointerRNA *ptr, PropertyRNA *prop, const EnumPropertyItem **item, int *totitem)
{
EnumPropertyRNA *eprop;
@@ -508,7 +545,7 @@ int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
else
flag= prop->flag;
- return !(flag & PROP_NOT_EDITABLE);
+ return (flag & PROP_EDITABLE);
}
int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
@@ -517,7 +554,7 @@ int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
rna_idproperty_check(&prop, ptr);
- if(prop->flag & PROP_NOT_ANIMATEABLE)
+ if(!(prop->flag & PROP_ANIMATEABLE))
return 0;
if(prop->editable)
@@ -525,7 +562,7 @@ int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
else
flag= prop->flag;
- return !(flag & PROP_NOT_EDITABLE);
+ return (flag & PROP_EDITABLE);
}
int RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop)
@@ -569,7 +606,7 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
IDP_Int(idprop)= value;
else if(bprop->set)
bprop->set(ptr, value);
- else if(!(prop->flag & PROP_NOT_EDITABLE)) {
+ else if(prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val;
IDProperty *group;
@@ -586,8 +623,14 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *val
BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
IDProperty *idprop;
- if((idprop=rna_idproperty_check(&prop, ptr)))
- memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
+ if((idprop=rna_idproperty_check(&prop, ptr))) {
+ if(prop->arraylength == 0)
+ values[0]= RNA_property_boolean_get(ptr, prop);
+ else
+ memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
+ }
+ else if(prop->arraylength == 0)
+ values[0]= RNA_property_boolean_get(ptr, prop);
else if(bprop->getarray)
bprop->getarray(ptr, values);
else if(bprop->defaultarray)
@@ -609,11 +652,17 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in
BooleanPropertyRNA *bprop= (BooleanPropertyRNA*)prop;
IDProperty *idprop;
- if((idprop=rna_idproperty_check(&prop, ptr)))
- memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
+ if((idprop=rna_idproperty_check(&prop, ptr))) {
+ if(prop->arraylength == 0)
+ IDP_Int(idprop)= values[0];
+ else
+ memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
+ }
+ else if(prop->arraylength == 0)
+ RNA_property_boolean_set(ptr, prop, values[0]);
else if(bprop->setarray)
bprop->setarray(ptr, values);
- else if(!(prop->flag & PROP_NOT_EDITABLE)) {
+ else if(prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val;
IDProperty *group;
@@ -660,7 +709,7 @@ void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
IDP_Int(idprop)= value;
else if(iprop->set)
iprop->set(ptr, value);
- else if(!(prop->flag & PROP_NOT_EDITABLE)) {
+ else if(prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val;
IDProperty *group;
@@ -677,8 +726,14 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
IDProperty *idprop;
- if((idprop=rna_idproperty_check(&prop, ptr)))
- memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
+ if((idprop=rna_idproperty_check(&prop, ptr))) {
+ if(prop->arraylength == 0)
+ values[0]= RNA_property_int_get(ptr, prop);
+ else
+ memcpy(values, IDP_Array(idprop), sizeof(int)*idprop->len);
+ }
+ else if(prop->arraylength == 0)
+ values[0]= RNA_property_int_get(ptr, prop);
else if(iprop->getarray)
iprop->getarray(ptr, values);
else if(iprop->defaultarray)
@@ -700,11 +755,17 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v
IntPropertyRNA *iprop= (IntPropertyRNA*)prop;
IDProperty *idprop;
- if((idprop=rna_idproperty_check(&prop, ptr)))
- memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);
+ if((idprop=rna_idproperty_check(&prop, ptr))) {
+ if(prop->arraylength == 0)
+ IDP_Int(idprop)= values[0];
+ else
+ memcpy(IDP_Array(idprop), values, sizeof(int)*idprop->len);\
+ }
+ else if(prop->arraylength == 0)
+ RNA_property_int_set(ptr, prop, values[0]);
else if(iprop->setarray)
iprop->setarray(ptr, values);
- else if(!(prop->flag & PROP_NOT_EDITABLE)) {
+ else if(prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val;
IDProperty *group;
@@ -760,7 +821,7 @@ void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
else if(fprop->set) {
fprop->set(ptr, value);
}
- else if(!(prop->flag & PROP_NOT_EDITABLE)) {
+ else if(prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val;
IDProperty *group;
@@ -779,7 +840,9 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val
int i;
if((idprop=rna_idproperty_check(&prop, ptr))) {
- if(idprop->subtype == IDP_FLOAT) {
+ if(prop->arraylength == 0)
+ values[0]= RNA_property_float_get(ptr, prop);
+ else if(idprop->subtype == IDP_FLOAT) {
memcpy(values, IDP_Array(idprop), sizeof(float)*idprop->len);
}
else {
@@ -787,13 +850,14 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val
values[i]= (float)(((double*)IDP_Array(idprop))[i]);
}
}
+ else if(prop->arraylength == 0)
+ values[0]= RNA_property_float_get(ptr, prop);
else if(fprop->getarray)
fprop->getarray(ptr, values);
else if(fprop->defaultarray)
memcpy(values, fprop->defaultarray, sizeof(float)*prop->arraylength);
else
memset(values, 0, sizeof(float)*prop->arraylength);
-
}
float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
@@ -811,7 +875,9 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa
int i;
if((idprop=rna_idproperty_check(&prop, ptr))) {
- if(idprop->subtype == IDP_FLOAT) {
+ if(prop->arraylength == 0)
+ IDP_Double(idprop)= values[0];
+ else if(idprop->subtype == IDP_FLOAT) {
memcpy(IDP_Array(idprop), values, sizeof(float)*idprop->len);
}
else {
@@ -819,10 +885,12 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa
((double*)IDP_Array(idprop))[i]= values[i];
}
}
+ else if(prop->arraylength == 0)
+ RNA_property_float_set(ptr, prop, values[0]);
else if(fprop->setarray) {
fprop->setarray(ptr, values);
}
- else if(!(prop->flag & PROP_NOT_EDITABLE)) {
+ else if(prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val;
IDProperty *group;
@@ -899,7 +967,7 @@ void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *val
IDP_AssignString(idprop, (char*)value);
else if(sprop->set)
sprop->set(ptr, value);
- else if(!(prop->flag & PROP_NOT_EDITABLE)) {
+ else if(prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val;
IDProperty *group;
@@ -935,7 +1003,7 @@ void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
else if(eprop->set) {
eprop->set(ptr, value);
}
- else if(!(prop->flag & PROP_NOT_EDITABLE)) {
+ else if(prop->flag & PROP_EDITABLE) {
IDPropertyTemplate val;
IDProperty *group;
@@ -956,7 +1024,7 @@ PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
pprop= (PointerPropertyRNA*)prop;
/* for groups, data is idprop itself */
- return rna_pointer_inherit_refine(ptr, pprop->structtype, idprop);
+ return rna_pointer_inherit_refine(ptr, pprop->type, idprop);
}
else if(pprop->get) {
return pprop->get(ptr);
@@ -1002,8 +1070,8 @@ static void rna_property_collection_get_idp(CollectionPropertyIterator *iter)
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)iter->prop;
iter->ptr.data= rna_iterator_array_get(iter);
- iter->ptr.type= cprop->structtype;
- rna_pointer_inherit_id(cprop->structtype, &iter->parent, &iter->ptr);
+ iter->ptr.type= cprop->type;
+ rna_pointer_inherit_id(cprop->type, &iter->parent, &iter->ptr);
}
void RNA_property_collection_begin(PointerRNA *ptr, PropertyRNA *prop, CollectionPropertyIterator *iter)
@@ -1118,7 +1186,7 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
r_ptr->data= IDP_GetIndexArray(idprop, idprop->len-1);
- r_ptr->type= cprop->structtype;
+ r_ptr->type= cprop->type;
rna_pointer_inherit_id(NULL, ptr, r_ptr);
}
else
@@ -1309,26 +1377,6 @@ void rna_iterator_array_end(CollectionPropertyIterator *iter)
MEM_freeN(iter->internal);
}
-/* Pointer Handling */
-
-PointerRNA rna_pointer_inherit_refine(PointerRNA *ptr, StructRNA *type, void *data)
-{
- PointerRNA result;
-
- if(data) {
- result.data= data;
- result.type= type;
- rna_pointer_inherit_id(type, ptr, &result);
-
- if(type->refine)
- result.type= type->refine(&result);
- }
- else
- memset(&result, 0, sizeof(result));
-
- return result;
-}
-
/* RNA Path - Experiment */
static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int bracket)
@@ -1414,7 +1462,7 @@ int RNA_path_resolve(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, Prope
prop= NULL;
for(; iter.valid; RNA_property_collection_next(&iter)) {
- if(strcmp(token, RNA_property_identifier(&iter.ptr, iter.ptr.data)) == 0) {
+ if(strcmp(token, RNA_property_identifier(&curptr, iter.ptr.data)) == 0) {
prop= iter.ptr.data;
break;
}
@@ -1574,6 +1622,33 @@ char *RNA_path_back(const char *path)
return result;
}
+char *RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
+{
+ char *ptrpath=NULL, *path;
+ const char *propname;
+
+ if(!ptr->id.data || !ptr->data || !prop)
+ return NULL;
+
+ if(!RNA_struct_is_ID(ptr)) {
+ if(ptr->type->path)
+ ptrpath= ptr->type->path(ptr);
+ else
+ return NULL;
+ }
+
+ propname= RNA_property_identifier(ptr, prop);
+
+ if(ptrpath) {
+ path= BLI_sprintfN("%s.%s", ptrpath, propname);
+ MEM_freeN(ptrpath);
+ }
+ else
+ path= BLI_strdup(propname);
+
+ return path;
+}
+
/* Quick name based property access */
int RNA_boolean_get(PointerRNA *ptr, const char *name)
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index ba5423f0408..6cb38ed9cdc 100755..100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -139,7 +139,7 @@ void rna_def_channeldriver(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Driver Object", "Object that controls this Driver.");
prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Driver_RnaPath_get", "rna_Driver_RnaPath_length", "rna_Driver_RnaPath_set");
RNA_def_property_ui_text(prop, "Driver RNA Path", "RNA Path (from Driver Object) to property used as Driver.");
@@ -174,12 +174,12 @@ void rna_def_fcurve(BlenderRNA *brna)
/* Pointers */
prop= RNA_def_property(srna, "driver", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // xxx?
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // xxx?
RNA_def_property_ui_text(prop, "Driver", "Channel Driver (only set for Driver F-Curves)");
/* Path + Array Index */
prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_FCurve_RnaPath_get", "rna_FCurve_RnaPath_length", "rna_FCurve_RnaPath_set");
RNA_def_property_ui_text(prop, "RNA Path", "RNA Path to property affected by F-Curve.");
@@ -236,9 +236,9 @@ void rna_def_action_group(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", AGRP_SELECTED);
RNA_def_property_ui_text(prop, "Selected", "Action Group is selected.");
- prop= RNA_def_property(srna, "protected", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "locked", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", AGRP_PROTECTED);
- RNA_def_property_ui_text(prop, "Protected", "Action Group is protected.");
+ RNA_def_property_ui_text(prop, "Locked", "Action Group is locked.");
prop= RNA_def_property(srna, "expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", AGRP_EXPANDED);
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index 4ed4fe1d72e..531ae1e2790 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -71,7 +71,7 @@ void RNA_def_actuator(BlenderRNA *brna)
/* type is not editable, would need to do proper data free/alloc */
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, actuator_type_items);
RNA_def_property_ui_text(prop, "Type", "");
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 95091741db4..160c0294f7f 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -106,7 +106,7 @@ void rna_def_keyingset_path(BlenderRNA *brna)
/* Path + Array Index */
prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_ksPath_RnaPath_get", "rna_ksPath_RnaPath_length", "rna_ksPath_RnaPath_set");
RNA_def_property_ui_text(prop, "RNA Path", "RNA Path to property setting.");
@@ -140,14 +140,14 @@ void rna_def_keyingset(BlenderRNA *brna)
/* Flags */
prop= RNA_def_property(srna, "builtin", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYINGSET_BUILTIN);
RNA_def_property_ui_text(prop, "Built-In", "Keying Set is a built-in to Blender.");
/* TODO: for now, this is editable, but do we really want this to happen? */
prop= RNA_def_property(srna, "absolute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", KEYINGSET_ABSOLUTE);
- RNA_def_property_ui_text(prop, "Absolute", "Keying Set defines specifc paths/settings to be keyframed (i.e. is not reliant on context info)");
+ RNA_def_property_ui_text(prop, "Absolute", "Keying Set defines specific paths/settings to be keyframed (i.e. is not reliant on context info)");
/* Keyframing Flags */
prop= RNA_def_property(srna, "insertkey_needed", PROP_BOOLEAN, PROP_NONE);
@@ -169,7 +169,7 @@ void rna_def_animdata_common(StructRNA *srna)
prop= RNA_def_property(srna, "animation_data", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "adt");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Animation Data", "Animation data for this datablock.");
}
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 5c5457ceb84..a76dc2f0972 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -126,7 +126,7 @@ static void rna_def_bone(BlenderRNA *brna)
/* strings */
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* must be unique */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* must be unique */
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_struct_name_property(srna, prop);
@@ -190,7 +190,7 @@ static void rna_def_bone(BlenderRNA *brna)
prop= RNA_def_property(srna, "cyclic_offset", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BONE_NO_CYCLICOFFSET);
- RNA_def_property_ui_text(prop, "Cyclic Offset", "When bone doesn't have a parent, it recieves cyclic offset effects.");
+ RNA_def_property_ui_text(prop, "Cyclic Offset", "When bone doesn't have a parent, it receives cyclic offset effects.");
prop= RNA_def_property(srna, "editmode_locked", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BONE_EDITMODE_LOCKED);
@@ -244,7 +244,7 @@ static void rna_def_bone(BlenderRNA *brna)
prop= RNA_def_property(srna, "roll", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 2.0f);
- RNA_def_property_ui_text(prop, "Bone Roll", "In Edit Mode, the 'roll' (i.e. rotation around the bone vector, equivilant to local Y-axis rotation).");
+ RNA_def_property_ui_text(prop, "Bone Roll", "In Edit Mode, the 'roll' (i.e. rotation around the bone vector, equivalent to local Y-axis rotation).");
}
void rna_def_armature(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index d21c79fbe52..9f5b3ba3af7 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -198,7 +198,7 @@ void rna_def_brush(BlenderRNA *brna)
/* clone tool */
prop= RNA_def_property(srna, "clone_image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "clone.image");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Clone Image", "Image for clone tool.");
prop= RNA_def_property(srna, "clone_opacity", PROP_FLOAT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index bfcdf8ce13d..94537eecba9 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -188,7 +188,7 @@ static void rna_def_cloth_sim_settings(BlenderRNA *brna)
prop= RNA_def_property(srna, "air_damping", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "Cvi");
RNA_def_property_range(prop, 0.0f, 10.0f);
- RNA_def_property_ui_text(prop, "Air Damping", "Air has normaly some thickness which slows falling things down.");
+ RNA_def_property_ui_text(prop, "Air Damping", "Air has normally some thickness which slows falling things down.");
prop= RNA_def_property(srna, "pin_cloth", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", CLOTH_SIMSETTINGS_FLAG_GOAL);
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 1009859798d..dcd5a494e5d 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -133,13 +133,13 @@ static void rna_def_curvemappoint(BlenderRNA *brna)
prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_float_sdna(prop, NULL, "x");
RNA_def_property_array(prop, 2);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Location", "X/Y coordinates of the curve point.");
prop= RNA_def_property(srna, "handle_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, prop_handle_type_items);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Handle Type", "Curve interpolation at this point: bezier or vector.");
prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
@@ -165,7 +165,7 @@ static void rna_def_curvemap(BlenderRNA *brna)
prop= RNA_def_property(srna, "extend", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, prop_extend_items);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Extend", "Extrapolate the curve or extend it horizontally.");
prop= RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
@@ -218,12 +218,12 @@ static void rna_def_curvemapping(BlenderRNA *brna)
prop= RNA_def_property(srna, "black_level", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "black");
- RNA_def_property_ui_text(prop, "Black Level", "For RGB curves, the colour that black is mapped to");
+ RNA_def_property_ui_text(prop, "Black Level", "For RGB curves, the color that black is mapped to");
RNA_def_property_float_funcs(prop, NULL, "rna_CurveMapping_black_level_set", NULL);
prop= RNA_def_property(srna, "white_level", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "white");
- RNA_def_property_ui_text(prop, "White Level", "For RGB curves, the colour that white is mapped to");
+ RNA_def_property_ui_text(prop, "White Level", "For RGB curves, the color that white is mapped to");
RNA_def_property_float_funcs(prop, NULL, "rna_CurveMapping_white_level_set", NULL);
}
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 7cb57053272..774f2f9c0ef 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -187,7 +187,7 @@ static void rna_def_constraint_python(BlenderRNA *brna)
prop= RNA_def_property(srna, "script_error", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PYCON_SCRIPTERROR);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Script Error", "The linked Python script has thrown an error.");
}
@@ -727,17 +727,17 @@ static void rna_def_constraint_rigid_body_joint(BlenderRNA *brna)
prop= RNA_def_property(srna, "axis_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "axX");
RNA_def_property_range(prop, -360.0, 360.f);
- RNA_def_property_ui_text(prop, "Axis X", "Rotate pivot on X axis in degress.");
+ RNA_def_property_ui_text(prop, "Axis X", "Rotate pivot on X axis in degrees.");
prop= RNA_def_property(srna, "axis_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "axY");
RNA_def_property_range(prop, -360.0, 360.f);
- RNA_def_property_ui_text(prop, "Axis Y", "Rotate pivot on Y axis in degress.");
+ RNA_def_property_ui_text(prop, "Axis Y", "Rotate pivot on Y axis in degrees.");
prop= RNA_def_property(srna, "axis_z", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "axZ");
RNA_def_property_range(prop, -360.0, 360.f);
- RNA_def_property_ui_text(prop, "Axis Z", "Rotate pivot on Z axis in degress.");
+ RNA_def_property_ui_text(prop, "Axis Z", "Rotate pivot on Z axis in degrees.");
/* XXX not sure how to wrap the two 6 element arrays for the generic joint */
//float minLimit[6];
@@ -1187,7 +1187,7 @@ void RNA_def_constraint(BlenderRNA *brna)
/* enums */
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Type", "");
@@ -1200,7 +1200,7 @@ void RNA_def_constraint(BlenderRNA *brna)
// XXX this is really an internal flag, but it may be useful for some tools to be able to access this...
prop= RNA_def_property(srna, "disabled", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CONSTRAINT_DISABLE);
RNA_def_property_ui_text(prop, "Disabled", "Constraint has invalid settings and will not be evaluated.");
diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c
new file mode 100644
index 00000000000..d3089917649
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_context.c
@@ -0,0 +1,150 @@
+/**
+ * $Id$
+ *
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation (2009).
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+
+#include "DNA_ID.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_types.h"
+
+#ifdef RNA_RUNTIME
+
+#include "BKE_context.h"
+
+static PointerRNA rna_Context_manager_get(PointerRNA *ptr)
+{
+ bContext *C= (bContext*)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Region, CTX_wm_manager(C));
+}
+
+/*static PointerRNA rna_Context_window_get(PointerRNA *ptr)
+{
+ bContext *C= (bContext*)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Region, CTX_wm_window(C));
+}*/
+
+static PointerRNA rna_Context_screen_get(PointerRNA *ptr)
+{
+ bContext *C= (bContext*)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Region, CTX_wm_screen(C));
+}
+
+static PointerRNA rna_Context_area_get(PointerRNA *ptr)
+{
+ bContext *C= (bContext*)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Region, CTX_wm_area(C));
+}
+
+static PointerRNA rna_Context_space_data_get(PointerRNA *ptr)
+{
+ bContext *C= (bContext*)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Region, CTX_wm_space_data(C));
+}
+
+static PointerRNA rna_Context_region_get(PointerRNA *ptr)
+{
+ bContext *C= (bContext*)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Region, CTX_wm_region(C));
+}
+
+/*static PointerRNA rna_Context_region_data_get(PointerRNA *ptr)
+{
+ bContext *C= (bContext*)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Region, CTX_wm_region_data(C));
+}*/
+
+static PointerRNA rna_Context_main_get(PointerRNA *ptr)
+{
+ bContext *C= (bContext*)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Main, CTX_data_main(C));
+}
+
+static PointerRNA rna_Context_scene_get(PointerRNA *ptr)
+{
+ bContext *C= (bContext*)ptr->data;
+ return rna_pointer_inherit_refine(ptr, &RNA_Scene, CTX_data_scene(C));
+}
+
+#else
+
+void RNA_def_context(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "Context", NULL);
+ RNA_def_struct_ui_text(srna, "Context", "Current windowmanager and data context.");
+
+ /* WM */
+ prop= RNA_def_property(srna, "manager", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "WindowManager");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_manager_get", NULL);
+
+ /* prop= RNA_def_property(srna, "window", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "Window");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_window_get", NULL); */
+
+ prop= RNA_def_property(srna, "screen", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "Screen");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_screen_get", NULL);
+
+ prop= RNA_def_property(srna, "area", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "Area");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_area_get", NULL);
+
+ prop= RNA_def_property(srna, "space_data", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "Space");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_space_data_get", NULL);
+
+ prop= RNA_def_property(srna, "region", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "Region");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_region_get", NULL);
+
+ /*prop= RNA_def_property(srna, "region_data", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "RegionData");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_region_data_get", NULL);*/
+
+ /* Data */
+ prop= RNA_def_property(srna, "main", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "Main");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_main_get", NULL);
+
+ prop= RNA_def_property(srna, "scene", PROP_POINTER, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_struct_type(prop, "Scene");
+ RNA_def_property_pointer_funcs(prop, "rna_Context_scene_get", NULL);
+}
+
+#endif
+
diff --git a/source/blender/makesrna/intern/rna_controller.c b/source/blender/makesrna/intern/rna_controller.c
index c08233b9584..1c2e5ecee02 100644
--- a/source/blender/makesrna/intern/rna_controller.c
+++ b/source/blender/makesrna/intern/rna_controller.c
@@ -88,7 +88,7 @@ void RNA_def_controller(BlenderRNA *brna)
/* type is not editable, would need to do proper data free/alloc */
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, controller_type_items);
RNA_def_property_ui_text(prop, "Type", "");
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 4a422cecbd7..dd1c620fe45 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * Contributor(s): Blender Foundation (2008), Juho Vepsäläinen
+ * Contributor(s): Blender Foundation (2008), Juho Veps�l�inen
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -30,6 +30,7 @@
#include "rna_internal.h"
#include "DNA_curve_types.h"
+#include "DNA_material_types.h"
#ifdef RNA_RUNTIME
@@ -90,7 +91,26 @@ static void rna_BezTriple_ctrlpoint_set(PointerRNA *ptr, const float *values)
static int rna_Curve_texspace_editable(PointerRNA *ptr)
{
Curve *cu= (Curve*)ptr->data;
- return (cu->texflag & CU_AUTOSPACE)? PROP_NOT_EDITABLE: 0;
+ return (cu->texflag & CU_AUTOSPACE)? 0: PROP_EDITABLE;
+}
+
+static void rna_Curve_material_index_range(PointerRNA *ptr, int *min, int *max)
+{
+ Curve *cu= (Curve*)ptr->id.data;
+ *min= 0;
+ *max= cu->totcol-1;
+}
+
+static int rna_Nurb_length(PointerRNA *ptr)
+{
+ Nurb *nu= (Nurb*)ptr->data;
+ return nu->pntsv>0 ? nu->pntsu*nu->pntsv : nu->pntsu;
+}
+
+static void rna_BPoint_array_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+{
+ Nurb *nu= (Nurb*)ptr->data;
+ rna_iterator_array_begin(iter, (void*)nu->bp, sizeof(BPoint*), nu->pntsv>0 ? nu->pntsu*nu->pntsv : nu->pntsu, NULL);
}
#else
@@ -132,7 +152,7 @@ static void rna_def_bpoint(BlenderRNA *brna)
prop= RNA_def_property(srna, "bevel_radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "radius");
/*RNA_def_property_range(prop, 0.0f, 1.0f);*/
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Bevel Radius", "Radius for bevelling");
}
@@ -187,7 +207,7 @@ static void rna_def_beztriple(BlenderRNA *brna)
prop= RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "ipo");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, prop_mode_interpolation_items);
RNA_def_property_ui_text(prop, "Interpolation", "(For F-Curves Only) Interpolation to use for segment of curve starting from current BezTriple.");
@@ -220,7 +240,7 @@ static void rna_def_beztriple(BlenderRNA *brna)
prop= RNA_def_property(srna, "bevel_radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "radius");
/*RNA_def_property_range(prop, 0.0f, 1.0f);*/
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Bevel Radius", "Radius for bevelling");
}
@@ -451,7 +471,12 @@ void rna_def_curve(BlenderRNA *brna)
prop= RNA_def_property(srna, "shape_keys", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "key");
RNA_def_property_ui_text(prop, "Shape Keys", "");
-
+
+ prop= RNA_def_property(srna, "curves", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "nurb", NULL);
+ RNA_def_property_struct_type(prop, "Nurb");
+ RNA_def_property_ui_text(prop, "Curves", "Collection of curves in this curve data object.");
+
rna_def_path(brna, srna);
rna_def_nurbs(brna, srna);
rna_def_font(brna, srna);
@@ -524,6 +549,126 @@ void rna_def_curve(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Retopo", "Turn on the re-topology tool.");
}
+
+void rna_def_curve_nurb(BlenderRNA *brna)
+{
+ static EnumPropertyItem spline_interpolation_items[] = {
+ {BEZT_IPO_CONST, "LINEAR", "Linear", ""},
+ {BEZT_IPO_LIN, "CARDINAL", "Cardinal", ""},
+ {BEZT_IPO_BEZ, "BSPLINE", "BSpline", ""},
+ {BEZT_IPO_BEZ, "EASE", "Ease", ""},
+ {0, NULL, NULL, NULL}};
+
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "Nurb", NULL);
+ RNA_def_struct_ui_text(srna, "Nurb", "Element of a curve, either Nurb, Bezier or Polyline or a character with text objects.");
+
+ prop= RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "bp", NULL);
+ RNA_def_property_struct_type(prop, "CurvePoint");
+ RNA_def_property_collection_funcs(prop, "rna_BPoint_array_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", "rna_Nurb_length", 0, 0);
+ RNA_def_property_ui_text(prop, "Points", "Collection of points for Poly and Nurbs curves.");
+
+ prop= RNA_def_property(srna, "bezier_points", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_struct_type(prop, "BezierCurvePoint");
+ RNA_def_property_collection_sdna(prop, NULL, "bezt", "pntsu");
+ RNA_def_property_ui_text(prop, "Bezier Points", "Collection of points bezier curves only.");
+
+
+ prop= RNA_def_property(srna, "tilt_interpolation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "tilt_interp");
+ RNA_def_property_enum_items(prop, spline_interpolation_items);
+ RNA_def_property_ui_text(prop, "Tilt Interpolation", "The type of tilt interpolation for 3D, Bezier curves.");
+
+ prop= RNA_def_property(srna, "radius_interpolation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "radius_interp");
+ RNA_def_property_enum_items(prop, spline_interpolation_items);
+ RNA_def_property_ui_text(prop, "Radius Interpolation", "The type of radius interpolation for Bezier curves.");
+
+
+ prop= RNA_def_property(srna, "point_count_u", PROP_INT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* editing this needs knot recalc*/
+ RNA_def_property_int_sdna(prop, NULL, "pntsu");
+ RNA_def_property_ui_text(prop, "Points U", "Total number points for the curve or surface in the U direction");
+
+ prop= RNA_def_property(srna, "point_count_v", PROP_INT, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* editing this needs knot recalc*/
+ RNA_def_property_int_sdna(prop, NULL, "pntsv");
+ RNA_def_property_ui_text(prop, "Points V", "Total number points for the surface on the V direction");
+
+
+ prop= RNA_def_property(srna, "order_u", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "orderu");
+ RNA_def_property_range(prop, 2, 6);
+ RNA_def_property_ui_text(prop, "Order U", "Nurbs order in the U direction (For curves and surfaces), Higher values let points influence a greater area");
+
+ prop= RNA_def_property(srna, "order_v", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "orderv");
+ RNA_def_property_range(prop, 2, 6);
+ RNA_def_property_ui_text(prop, "Order V", "Nurbs order in the V direction (For surfaces only), Higher values let points influence a greater area");
+
+
+ prop= RNA_def_property(srna, "resolution_u", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "resolu");
+ RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_ui_text(prop, "Resolution U", "Curve or Surface subdivisions per segment");
+
+ prop= RNA_def_property(srna, "resolution_v", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "resolv");
+ RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_ui_text(prop, "Resolution V", "Surface subdivisions per segment");
+
+ prop= RNA_def_property(srna, "cyclic_u", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flagu", CU_CYCLIC);
+ RNA_def_property_ui_text(prop, "Cyclic U", "Make this curve or surface a closed loop in the U direction.");
+
+ prop= RNA_def_property(srna, "cyclic_v", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flagv", CU_CYCLIC);
+ RNA_def_property_ui_text(prop, "Cyclic V", "Make this surface a closed loop in the V direction.");
+
+
+ /* Note, endpoint and bezier flags should never be on at the same time! */
+ prop= RNA_def_property(srna, "endpoint_u", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flagu", 2);
+ RNA_def_property_ui_text(prop, "Endpoint U", "Make this nurbs curve or surface meet the endpoints in the U direction (Cyclic U must be disabled).");
+
+ prop= RNA_def_property(srna, "endpoint_v", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flagv", 2);
+ RNA_def_property_ui_text(prop, "Endpoint V", "Make this nurbs surface meet the endpoints in the V direction (Cyclic V must be disabled).");
+
+ prop= RNA_def_property(srna, "bezier_u", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flagu", 4);
+ RNA_def_property_ui_text(prop, "Bezier U", "Make this nurbs curve or surface act like a bezier spline in the U direction (Order U must be 3 or 4, Cyclic U must be disabled).");
+
+ prop= RNA_def_property(srna, "bezier_v", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flagv", 4);
+ RNA_def_property_ui_text(prop, "Bezier V", "Make this nurbs surface act like a bezier spline in the V direction (Order V must be 3 or 4, Cyclic V must be disabled).");
+
+
+ prop= RNA_def_property(srna, "smooth", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_SMOOTH);
+ RNA_def_property_ui_text(prop, "Smooth", "Smooth the normals of the surface or beveled curve.");
+
+ prop= RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "hide", 1);
+ RNA_def_property_ui_text(prop, "Hide", "Hide this curve in editmode.");
+
+ prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "mat_nr");
+ RNA_def_property_ui_text(prop, "Material Index", "");
+ RNA_def_property_range(prop, 0, MAXMAT-1);
+ RNA_def_property_int_funcs(prop, NULL, NULL, "rna_Curve_material_index_range");
+
+ prop= RNA_def_property(srna, "character_index", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "charidx");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* editing this needs knot recalc*/
+ RNA_def_property_ui_text(prop, "Character Index", "the location of this character in the text data (only for text curves)");
+}
+
+
+
void RNA_def_curve(BlenderRNA *brna)
{
rna_def_curve(brna);
@@ -531,6 +676,7 @@ void RNA_def_curve(BlenderRNA *brna)
rna_def_charinfo(brna);
rna_def_bpoint(brna);
rna_def_beztriple(brna);
+ rna_def_curve_nurb(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 48c93955784..15486efc9d0 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -113,6 +113,7 @@ static int rna_member_cmp(const char *name, const char *oname)
while(1) {
if(name[a]=='[' && oname[a]==0) return 1;
+ if(name[a]=='[' && oname[a]=='[') return 1;
if(name[a]==0) break;
if(name[a] != oname[a]) return 0;
a++;
@@ -145,7 +146,11 @@ static int rna_find_sdna_member(SDNA *sdna, const char *structname, const char *
if(cmp == 1) {
smember->type= sdna->types[sp[0]];
smember->name= dnaname;
- smember->arraylength= DNA_elem_array_size(smember->name, strlen(smember->name));
+
+ if(strstr(membername, "["))
+ smember->arraylength= 0;
+ else
+ smember->arraylength= DNA_elem_array_size(smember->name, strlen(smember->name));
smember->pointerlevel= 0;
for(b=0; dnaname[b] == '*'; b++)
@@ -403,12 +408,11 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
cprop->begin= rna_builtin_properties_begin;
cprop->next= rna_builtin_properties_next;
cprop->get= rna_builtin_properties_get;
- cprop->structtype= &RNA_Property;
+ cprop->type= &RNA_Property;
#endif
}
prop= RNA_def_property(srna, "rna_type", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "RNA", "RNA type definition.");
if(DefRNA.preprocess) {
@@ -419,7 +423,7 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
#ifdef RNA_RUNTIME
PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
pprop->get= rna_builtin_type_get;
- pprop->structtype= &RNA_Struct;
+ pprop->type= &RNA_Struct;
#endif
}
}
@@ -515,6 +519,16 @@ void RNA_def_struct_refine_func(StructRNA *srna, const char *refine)
if(refine) srna->refine= (StructRefineFunc)refine;
}
+void RNA_def_struct_path_func(StructRNA *srna, const char *path)
+{
+ if(!DefRNA.preprocess) {
+ fprintf(stderr, "RNA_def_struct_path_func: only during preprocessing.\n");
+ return;
+ }
+
+ if(path) srna->path= (StructPathFunc)path;
+}
+
void RNA_def_struct_identifier(StructRNA *srna, const char *identifier)
{
if(DefRNA.preprocess) {
@@ -625,8 +639,8 @@ PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type,
prop->name= identifier;
prop->description= "";
- if(type == PROP_COLLECTION || type == PROP_POINTER)
- prop->flag= PROP_NOT_EDITABLE|PROP_NOT_ANIMATEABLE;
+ if(type != PROP_COLLECTION && type != PROP_POINTER)
+ prop->flag= PROP_EDITABLE|PROP_ANIMATEABLE;
if(DefRNA.preprocess) {
switch(type) {
@@ -680,20 +694,12 @@ PropertyRNA *RNA_def_property(StructRNA *srna, const char *identifier, int type,
void RNA_def_property_flag(PropertyRNA *prop, int flag)
{
-#if 0
- StructRNA *srna;
-#endif
-
prop->flag |= flag;
+}
-#if 0
- if(prop->type != PROP_POINTER && prop->type != PROP_COLLECTION) {
- if(flag & (PROP_EVALUATE_DEPENDENCY|PROP_INVERSE_EVALUATE_DEPENDENCY|PROP_RENDER_DEPENDENCY|PROP_INVERSE_RENDER_DEPENDENCY)) {
- fprintf(stderr, "RNA_def_property_flag: %s.%s, only pointer and collection types can create dependencies.\n", ds->srna->identifier, prop->identifier);
- DefRNA.error= 1;
- }
- }
-#endif
+void RNA_def_property_clear_flag(PropertyRNA *prop, int flag)
+{
+ prop->flag &= ~flag;
}
void RNA_def_property_array(PropertyRNA *prop, int arraylength)
@@ -798,12 +804,12 @@ void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
switch(prop->type) {
case PROP_POINTER: {
PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
- pprop->structtype = (StructRNA*)type;
+ pprop->type = (StructRNA*)type;
break;
}
case PROP_COLLECTION: {
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
- cprop->structtype = (StructRNA*)type;
+ cprop->type = (StructRNA*)type;
break;
}
default:
@@ -825,12 +831,12 @@ void RNA_def_property_struct_runtime(PropertyRNA *prop, StructRNA *type)
switch(prop->type) {
case PROP_POINTER: {
PointerPropertyRNA *pprop= (PointerPropertyRNA*)prop;
- pprop->structtype = type;
+ pprop->type = type;
break;
}
case PROP_COLLECTION: {
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
- cprop->structtype = type;
+ cprop->type = type;
break;
}
default:
@@ -843,16 +849,23 @@ void RNA_def_property_struct_runtime(PropertyRNA *prop, StructRNA *type)
void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
{
StructRNA *srna= DefRNA.laststruct;
- int i;
+ int i, defaultfound= 0;
switch(prop->type) {
case PROP_ENUM: {
EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
eprop->item= item;
eprop->totitem= 0;
- for(i=0; item[i].identifier; i++)
+ for(i=0; item[i].identifier; i++) {
eprop->totitem++;
+ if(item[i].value == eprop->defaultvalue)
+ defaultfound= 1;
+ }
+
+ if(!defaultfound)
+ eprop->defaultvalue= item[0].value;
+
break;
}
default:
@@ -1001,11 +1014,28 @@ void RNA_def_property_string_default(PropertyRNA *prop, const char *value)
void RNA_def_property_enum_default(PropertyRNA *prop, int value)
{
StructRNA *srna= DefRNA.laststruct;
+ int i, defaultfound= 0;
switch(prop->type) {
case PROP_ENUM: {
EnumPropertyRNA *eprop= (EnumPropertyRNA*)prop;
eprop->defaultvalue= value;
+
+ for(i=0; i<eprop->totitem; i++) {
+ if(eprop->item[i].value == eprop->defaultvalue)
+ defaultfound= 1;
+ }
+
+ if(!defaultfound && eprop->totitem) {
+ if(value == 0) {
+ eprop->defaultvalue= eprop->item[0].value;
+ }
+ else {
+ fprintf(stderr, "RNA_def_property_enum_default: %s.%s, default is not in items.\n", srna->identifier, prop->identifier);
+ DefRNA.error= 1;
+ }
+ }
+
break;
}
default:
@@ -1118,7 +1148,7 @@ void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const
iprop->softmax= 10000;
}
- if(prop->subtype == PROP_UNSIGNED)
+ if(prop->subtype == PROP_UNSIGNED || prop->subtype == PROP_PERCENTAGE)
iprop->hardmin= iprop->softmin= 0;
}
}
diff --git a/source/blender/makesrna/intern/rna_dependency.c b/source/blender/makesrna/intern/rna_dependency.c
deleted file mode 100644
index d867d2f7768..00000000000
--- a/source/blender/makesrna/intern/rna_dependency.c
+++ /dev/null
@@ -1,92 +0,0 @@
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "DNA_scene_types.h"
-
-#include "RNA_access.h"
-#include "RNA_types.h"
-
-#if 0
-typedef struct RNAGenDeps {
- void *udata;
- PropDependencyCallback cb;
-} RNAGenDeps;
-
-static void rna_generate_deps(RNAGenDeps *gen, PointerRNA *ptr, PointerRNA *idptr)
-{
- PropertyRNA *prop;
- PointerRNA pptr;
- CollectionPropertyIterator iter;
-
- /* traverse recursively into ID struct properties, other
- * pointers we potentially add as dependencies */
-
- for(prop=ptr->type->properties.first; prop; prop=prop->next) {
- if(prop->type == PROP_POINTER) {
- RNA_property_pointer_get(ptr, prop, &pptr);
-
- if(pptr.data && pptr.type) {
- if(idptr && (pptr.type->flag & STRUCT_ID)) {
- if(prop->flag & PROP_EVALUATE_DEPENDENCY)
- gen->cb(gen->udata, ptr, &pptr);
- else if(prop->flag & PROP_INVERSE_EVALUATE_DEPENDENCY)
- gen->cb(gen->udata, ptr, &pptr);
- }
- else
- rna_generate_deps(gen, &pptr, (idptr)? idptr: &pptr);
- }
- }
- else if(prop->type == PROP_COLLECTION) {
- RNA_property_collection_begin(ptr, prop, &iter);
-
- while(iter.valid) {
- RNA_property_collection_get(&pptr, prop, &iter);
-
- if(pptr.data && pptr.type) {
- if(idptr && (pptr.type->flag & STRUCT_ID)) {
- if(prop->flag & PROP_EVALUATE_DEPENDENCY)
- gen->cb(gen->udata, ptr, &pptr);
- else if(prop->flag & PROP_INVERSE_EVALUATE_DEPENDENCY)
- gen->cb(gen->udata, ptr, &pptr);
- }
- else
- rna_generate_deps(gen, &pptr, (idptr)? idptr: &pptr);
- }
-
- RNA_property_collection_next(prop, &iter);
- }
-
- RNA_property_collection_end(prop, &iter);
- }
- }
-}
-
-void RNA_generate_dependencies(PointerRNA *ptr, void *udata, PropDependencyCallback cb)
-{
- RNAGenDeps gen;
-
- gen.udata= udata;
- gen.cb= cb;
-
- rna_generate_deps(&gen, ptr, NULL);
-}
-
-void RNA_test_dependencies_cb(void *udata, PointerRNA *from, PointerRNA *to)
-{
- PropertyRNA *prop;
- char name[256], nameto[256];
-
- prop= from->type? from->type->nameproperty: NULL;
- if(prop) RNA_property_string_get(prop, from, name);
- else strcpy(name, "unknown");
-
- prop= from->type? from->type->nameproperty: NULL;
- if(prop) RNA_property_string_get(prop, to, nameto);
- else strcpy(nameto, "unknown");
-
- printf("%s (%s) -> %s (%s)\n", name, from->type->identifier, nameto, to->type->identifier);
-}
-#endif
-
diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c
index 89431604006..a8a471062f8 100644
--- a/source/blender/makesrna/intern/rna_fluidsim.c
+++ b/source/blender/makesrna/intern/rna_fluidsim.c
@@ -174,7 +174,7 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
prop= RNA_def_property(srna, "grid_levels", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "maxRefine");
RNA_def_property_range(prop, -1, 4);
- RNA_def_property_ui_text(prop, "Grid Levels", "Number of coursened grids to use (-1 for automatic).");
+ RNA_def_property_ui_text(prop, "Grid Levels", "Number of coarsened grids to use (-1 for automatic).");
prop= RNA_def_property(srna, "compressibility", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "gstar");
@@ -413,13 +413,13 @@ void RNA_def_fluidsim(BlenderRNA *brna)
prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "type", OB_FLUIDSIM_ENABLE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // needs to create modifier
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // needs to create modifier
RNA_def_property_ui_text(prop, "Enabled", "Sets object to participate in fluid simulation.");
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, prop_fluid_type_items);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // needs to update variables
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // needs to update variables
RNA_def_property_ui_text(prop, "Type", "Type of participation in the fluid simulation.");
//prop= RNA_def_property(srna, "ipo", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index c98a936030a..2e8659fd881 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -75,12 +75,12 @@ static void rna_def_imageuser(BlenderRNA *brna)
prop= RNA_def_property(srna, "multilayer_layer", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "layer");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* image_multi_cb */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* image_multi_cb */
RNA_def_property_ui_text(prop, "Layer", "Layer in multilayer image.");
prop= RNA_def_property(srna, "multilayer_pass", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "pass");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* image_multi_cb */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* image_multi_cb */
RNA_def_property_ui_text(prop, "Pass", "Pass in multilayer image.");
}
@@ -116,17 +116,17 @@ static void rna_def_image(BlenderRNA *brna)
prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "name");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* imagechanged */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
RNA_def_property_ui_text(prop, "Filename", "Image/Movie file name.");
prop= RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_source_items);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* imagechanged */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
RNA_def_property_ui_text(prop, "Source", "Where the image comes from.");
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_type_items);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* imagechanged */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* imagechanged */
RNA_def_property_ui_text(prop, "Type", "How to generate the image.");
prop= RNA_def_property(srna, "packed_file", PROP_POINTER, PROP_NONE);
@@ -179,7 +179,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Display Aspect", "Display Aspect for this image, does not affect rendering.");
prop= RNA_def_property(srna, "animated", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* B_TWINANIM */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* B_TWINANIM */
RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_TWINANIM);
RNA_def_property_ui_text(prop, "Animated", "Use as animated texture in the game engine.");
@@ -199,7 +199,7 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Animation Speed", "Speed of the animation in frames per second.");
prop= RNA_def_property(srna, "tiles", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* B_SIMAGETILE */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* B_SIMAGETILE */
RNA_def_property_boolean_sdna(prop, NULL, "tpageflag", IMA_TILES);
RNA_def_property_ui_text(prop, "Tiles", "Use of tilemode for faces (default shift-LMB to pick the tile for selected faces).");
@@ -230,4 +230,3 @@ void RNA_def_image(BlenderRNA *brna)
#endif
-
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 2665d8eab09..4101291e825 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -105,6 +105,7 @@ void RNA_def_camera(struct BlenderRNA *brna);
void RNA_def_cloth(struct BlenderRNA *brna);
void RNA_def_color(struct BlenderRNA *brna);
void RNA_def_constraint(struct BlenderRNA *brna);
+void RNA_def_context(struct BlenderRNA *brna);
void RNA_def_controller(struct BlenderRNA *brna);
void RNA_def_curve(struct BlenderRNA *brna);
void RNA_def_fluidsim(struct BlenderRNA *brna);
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 0eea4ea5d39..bc0c2a07b35 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -41,6 +41,7 @@ struct bContext;
typedef void (*UpdateFunc)(struct bContext *C, struct PointerRNA *ptr);
typedef int (*EditableFunc)(struct PointerRNA *ptr);
typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr);
+typedef char *(*StructPathFunc)(struct PointerRNA *ptr);
typedef int (*PropBooleanGetFunc)(struct PointerRNA *ptr);
typedef void (*PropBooleanSetFunc)(struct PointerRNA *ptr, int value);
@@ -186,7 +187,7 @@ typedef struct PointerPropertyRNA {
PropPointerGetFunc get;
PropPointerSetFunc set;
- struct StructRNA *structtype;
+ struct StructRNA *type;
} PointerPropertyRNA;
typedef struct CollectionPropertyRNA {
@@ -200,7 +201,7 @@ typedef struct CollectionPropertyRNA {
PropCollectionLookupIntFunc lookupint; /* optional */
PropCollectionLookupStringFunc lookupstring; /* optional */
- struct StructRNA *structtype;
+ struct StructRNA *type;
} CollectionPropertyRNA;
@@ -208,6 +209,10 @@ typedef struct CollectionPropertyRNA {
struct StructRNA {
struct StructRNA *next, *prev;
+ /* python type, this is a subtype of pyrna_struct_Type but used so each struct can have its own type
+ * which is useful for subclassing RNA */
+ void *py_type;
+
/* unique identifier */
const char *identifier;
/* various options */
@@ -236,6 +241,9 @@ struct StructRNA {
/* function to give the more specific type */
StructRefineFunc refine;
+ /* function to find path to this struct in an ID */
+ StructPathFunc path;
+
/* properties of this struct */
ListBase properties;
};
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index 753bd21d7b8..0a21ad1d940 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -1,5 +1,5 @@
/**
- * $Id$
+ * $Id: rna_key.c 19382 2009-03-23 13:24:48Z blendix $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -292,7 +292,7 @@ static void rna_def_keyblock(BlenderRNA *brna)
/* keys need to be sorted to edit this */
prop= RNA_def_property(srna, "frame", PROP_FLOAT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_float_sdna(prop, NULL, "pos");
RNA_def_property_ui_text(prop, "Frame", "Frame for absolute keys.");
@@ -311,7 +311,7 @@ static void rna_def_keyblock(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex weight group, to blend with basis shape.");
prop= RNA_def_property(srna, "relative_key", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "ShapeKey");
RNA_def_property_ui_text(prop, "Relative Key", "Shape used as a relative key.");
RNA_def_property_pointer_funcs(prop, "rna_ShapeKey_relative_key_get", NULL);
@@ -332,6 +332,7 @@ static void rna_def_keyblock(BlenderRNA *brna)
prop= RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "data", "totelem");
+ RNA_def_property_struct_type(prop, "UnknownType");
RNA_def_property_ui_text(prop, "Data", "");
RNA_def_property_collection_funcs(prop, "rna_ShapeKey_data_begin", 0, 0, "rna_ShapeKey_data_get", "rna_ShapeKey_data_length", 0, 0);
}
@@ -345,7 +346,7 @@ static void rna_def_key(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Key", "Shape keys datablock containing different shapes of geometric datablocks.");
prop= RNA_def_property(srna, "reference_key", PROP_POINTER, PROP_NEVER_NULL);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_pointer_sdna(prop, NULL, "refkey");
RNA_def_property_ui_text(prop, "Reference Key", "");
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index 80b7658c6ef..202d1af9154 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -311,7 +311,7 @@ static void rna_def_lamp(BlenderRNA *brna)
/* script link */
prop= RNA_def_property(srna, "script_link", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "scriptlink");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Script Link", "Scripts linked to this lamp.");
}
@@ -328,7 +328,7 @@ static void rna_def_lamp_falloff(StructRNA *srna)
{0, NULL, NULL, NULL}};
prop= RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* needs to be able to create curve mapping */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* needs to be able to create curve mapping */
RNA_def_property_enum_items(prop, prop_fallofftype_items);
RNA_def_property_ui_text(prop, "Falloff Type", "Intensity Decay with distance.");
RNA_def_property_update(prop, NC_LAMP|ND_LIGHTING, NULL);
diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c
index d18142b3fcd..ca77d3b519f 100644
--- a/source/blender/makesrna/intern/rna_lattice.c
+++ b/source/blender/makesrna/intern/rna_lattice.c
@@ -1,5 +1,5 @@
/**
- * $Id$
+ * $Id: rna_lattice.c 19382 2009-03-23 13:24:48Z blendix $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -89,7 +89,7 @@ static void rna_def_latticepoint(BlenderRNA *brna)
prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_array(prop, 3);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_float_funcs(prop, "rna_LatticePoint_co_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Location", "");
@@ -120,17 +120,17 @@ static void rna_def_lattice(BlenderRNA *brna)
prop= RNA_def_property(srna, "points_u", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pntsu");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "U", "Points in U direction.");
prop= RNA_def_property(srna, "points_v", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pntsv");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "V", "Points in V direction.");
prop= RNA_def_property(srna, "points_w", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pntsw");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "W", "Points in W direction.");
prop= RNA_def_property(srna, "interpolation_type_u", PROP_ENUM, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 39fc1dbc5ad..03ce385be32 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -252,7 +252,7 @@ void RNA_def_main(BlenderRNA *brna)
prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_maxlength(prop, 240);
RNA_def_property_string_funcs(prop, "rna_Main_filename_get", "rna_Main_filename_length", "rna_Main_filename_set");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Filename", "Path to the .blend file.");
for(i=0; lists[i][0]; i++)
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 6054d4e6a42..34a7ea7d1e9 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -923,7 +923,7 @@ void RNA_def_material(BlenderRNA *brna)
prop= RNA_def_property(srna, "script_link", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "scriptlink");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Script Link", "Scripts linked to this material.");
/* XXX: does Material.septex get RNA? */
@@ -952,7 +952,7 @@ void rna_def_mtex_common(StructRNA *srna, const char *begin, const char *activeg
RNA_def_property_ui_text(prop, "Textures", "Texture slots defining the mapping and influence of textures.");
prop= RNA_def_property(srna, "active_texture", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, structname);
RNA_def_property_pointer_funcs(prop, activeget, NULL);
RNA_def_property_ui_text(prop, "Active Texture", "Active texture slot being displayed.");
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 46a2fcf998a..3f862199ea0 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -155,7 +155,7 @@ static void rna_MeshColor_color4_set(PointerRNA *ptr, const float *values)
static int rna_Mesh_texspace_editable(PointerRNA *ptr)
{
Mesh *me= (Mesh*)ptr->data;
- return (me->texflag & AUTOSPACE)? PROP_NOT_EDITABLE: 0;
+ return (me->texflag & AUTOSPACE)? 0: PROP_EDITABLE;
}
static void rna_MeshVertex_groups_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
@@ -467,6 +467,111 @@ static int rna_Mesh_string_layers_length(PointerRNA *ptr)
return rna_CustomDataLayer_length(ptr, CD_PROP_STR);
}
+/* path construction */
+
+static char *rna_VertexGroupElement_path(PointerRNA *ptr)
+{
+ Mesh *me= (Mesh*)ptr->id.data; /* XXX not always! */
+ MDeformWeight *dw= (MDeformWeight*)ptr->data;
+ MDeformVert *dvert;
+ int a, b;
+
+ for(a=0, dvert=me->dvert; a<me->totvert; a++, dvert++)
+ for(b=0; b<dvert->totweight; b++)
+ if(dw == &dvert->dw[b])
+ return BLI_sprintfN("verts[%d].groups[%d]", a, b);
+
+ return NULL;
+}
+
+static char *rna_MeshFace_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("faces[%d]", (MFace*)ptr->data - ((Mesh*)ptr->id.data)->mface);
+}
+
+static char *rna_MeshEdge_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("edges[%d]", (MEdge*)ptr->data - ((Mesh*)ptr->id.data)->medge);
+}
+
+static char *rna_MeshVertex_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("verts[%d]", (MVert*)ptr->data - ((Mesh*)ptr->id.data)->mvert);
+}
+
+static char *rna_MeshTextureFaceLayer_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("uv_layers[%s]", ((CustomDataLayer*)ptr->data)->name);
+}
+
+static char *rna_CustomDataData_path(PointerRNA *ptr, char *collection, int type)
+{
+ Mesh *me= (Mesh*)ptr->id.data;
+ CustomDataLayer *cdl;
+ int a;
+ size_t b;
+
+ for(cdl=me->fdata.layers, a=0; a<me->fdata.totlayer; cdl++, a++) {
+ if(cdl->type == type) {
+ b= ((char*)ptr->data - ((char*)cdl->data))/CustomData_sizeof(type);
+ if(b >= 0 && b < me->totface)
+ return BLI_sprintfN("%s[%s].data[%d]", collection, cdl->name, b);
+ }
+ }
+
+ return NULL;
+}
+
+static char *rna_MeshTextureFace_path(PointerRNA *ptr)
+{
+ return rna_CustomDataData_path(ptr, "uv_layers", CD_MTFACE);
+}
+
+static char *rna_MeshColorLayer_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("vcol_layers[%s]", ((CustomDataLayer*)ptr->data)->name);
+}
+
+static char *rna_MeshColor_path(PointerRNA *ptr)
+{
+ return rna_CustomDataData_path(ptr, "vcol_layers", CD_MCOL);
+}
+
+static char *rna_MeshSticky_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("sticky[%d]", (MSticky*)ptr->data - ((Mesh*)ptr->id.data)->msticky);
+}
+
+static char *rna_MeshIntPropertyLayer_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("int_layers[%s]", ((CustomDataLayer*)ptr->data)->name);
+}
+
+static char *rna_MeshIntProperty_path(PointerRNA *ptr)
+{
+ return rna_CustomDataData_path(ptr, "int_layers", CD_MCOL);
+}
+
+static char *rna_MeshFloatPropertyLayer_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("float_layers[%s]", ((CustomDataLayer*)ptr->data)->name);
+}
+
+static char *rna_MeshFloatProperty_path(PointerRNA *ptr)
+{
+ return rna_CustomDataData_path(ptr, "float_layers", CD_MCOL);
+}
+
+static char *rna_MeshStringPropertyLayer_path(PointerRNA *ptr)
+{
+ return BLI_sprintfN("string_layers[%s]", ((CustomDataLayer*)ptr->data)->name);
+}
+
+static char *rna_MeshStringProperty_path(PointerRNA *ptr)
+{
+ return rna_CustomDataData_path(ptr, "string_layers", CD_MCOL);
+}
+
#else
static void rna_def_mvert_group(BlenderRNA *brna)
@@ -477,12 +582,13 @@ static void rna_def_mvert_group(BlenderRNA *brna)
srna= RNA_def_struct(brna, "VertexGroupElement", NULL);
RNA_def_struct_ui_text(srna, "Vertex Group Element", "Weight value of a vertex in a vertex group.");
RNA_def_struct_sdna(srna, "MDeformWeight");
+ RNA_def_struct_path_func(srna, "rna_VertexGroupElement_path");
/* we can't point to actual group, it is in the object and so
* there is no unique group to point to, hence the index */
prop= RNA_def_property(srna, "group", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "def_nr");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Group Index", "");
prop= RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE);
@@ -498,6 +604,7 @@ static void rna_def_mvert(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshVertex", NULL);
RNA_def_struct_sdna(srna, "MVert");
RNA_def_struct_ui_text(srna, "Mesh Vertex", "Vertex in a Mesh datablock.");
+ RNA_def_struct_path_func(srna, "rna_MeshVertex_path");
prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_ui_text(prop, "Location", "");
@@ -505,7 +612,7 @@ static void rna_def_mvert(BlenderRNA *brna)
/*prop= RNA_def_property(srna, "no", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_float_funcs(prop, "rna_MeshVertex_no_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Normal", "Vertex Normal");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);*/
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);*/
prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
@@ -533,11 +640,12 @@ static void rna_def_medge(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshEdge", NULL);
RNA_def_struct_sdna(srna, "MEdge");
RNA_def_struct_ui_text(srna, "Mesh Edge", "Edge in a Mesh datablock.");
+ RNA_def_struct_path_func(srna, "rna_MeshEdge_path");
prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "v1");
RNA_def_property_array(prop, 2);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
prop= RNA_def_property(srna, "crease", PROP_FLOAT, PROP_NONE);
@@ -573,11 +681,12 @@ static void rna_def_mface(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshFace", NULL);
RNA_def_struct_sdna(srna, "MFace");
RNA_def_struct_ui_text(srna, "Mesh Face", "Face in a Mesh datablock.");
+ RNA_def_struct_path_func(srna, "rna_MeshFace_path");
prop= RNA_def_property(srna, "verts", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "v1");
RNA_def_property_array(prop, 4);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Vertices", "Vertex indices");
prop= RNA_def_property(srna, "material_index", PROP_INT, PROP_UNSIGNED);
@@ -613,6 +722,7 @@ static void rna_def_mtface(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshTextureFaceLayer", NULL);
RNA_def_struct_ui_text(srna, "Mesh Texture Face Layer", "Layer of texture faces in a Mesh datablock.");
RNA_def_struct_sdna(srna, "CustomDataLayer");
+ RNA_def_struct_path_func(srna, "rna_MeshTextureFaceLayer_path");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
@@ -635,6 +745,7 @@ static void rna_def_mtface(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshTextureFace", NULL);
RNA_def_struct_sdna(srna, "MTFace");
RNA_def_struct_ui_text(srna, "Mesh Texture Face", "UV mapping, texturing and game engine data for a face.");
+ RNA_def_struct_path_func(srna, "rna_MeshTextureFace_path");
/* prop= RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tpage");
@@ -735,6 +846,7 @@ static void rna_def_msticky(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshSticky", NULL);
RNA_def_struct_sdna(srna, "MSticky");
RNA_def_struct_ui_text(srna, "Mesh Vertex Sticky Texture Coordinate", "Stricky texture coordinate.");
+ RNA_def_struct_path_func(srna, "rna_MeshSticky_path");
prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_ui_text(prop, "Location", "Sticky texture coordinate location.");
@@ -748,6 +860,7 @@ static void rna_def_mcol(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshColorLayer", NULL);
RNA_def_struct_ui_text(srna, "Mesh Vertex Color Layer", "Layer of vertex colors in a Mesh datablock.");
RNA_def_struct_sdna(srna, "CustomDataLayer");
+ RNA_def_struct_path_func(srna, "rna_MeshColorLayer_path");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
@@ -770,6 +883,7 @@ static void rna_def_mcol(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshColor", NULL);
RNA_def_struct_sdna(srna, "MCol");
RNA_def_struct_ui_text(srna, "Mesh Vertex Color", "Vertex colors for a face in a Mesh.");
+ RNA_def_struct_path_func(srna, "rna_MeshColor_path");
prop= RNA_def_property(srna, "color1", PROP_FLOAT, PROP_COLOR);
RNA_def_property_array(prop, 3);
@@ -801,6 +915,7 @@ static void rna_def_mproperties(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshFloatPropertyLayer", NULL);
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(srna, "Mesh Float Property Layer", "User defined layer of floating pointer number values.");
+ RNA_def_struct_path_func(srna, "rna_MeshFloatPropertyLayer_path");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
@@ -814,6 +929,7 @@ static void rna_def_mproperties(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshFloatProperty", NULL);
RNA_def_struct_sdna(srna, "MFloatProperty");
RNA_def_struct_ui_text(srna, "Mesh Float Property", "User defined floating point number value in a float properties layer.");
+ RNA_def_struct_path_func(srna, "rna_MeshFloatProperty_path");
prop= RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "f");
@@ -823,6 +939,7 @@ static void rna_def_mproperties(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshIntPropertyLayer", NULL);
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(srna, "Mesh Int Property Layer", "User defined layer of integer number values.");
+ RNA_def_struct_path_func(srna, "rna_MeshIntPropertyLayer_path");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
@@ -836,6 +953,7 @@ static void rna_def_mproperties(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshIntProperty", NULL);
RNA_def_struct_sdna(srna, "MIntProperty");
RNA_def_struct_ui_text(srna, "Mesh Int Property", "User defined integer number value in an integer properties layer.");
+ RNA_def_struct_path_func(srna, "rna_MeshIntProperty_path");
prop= RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "i");
@@ -845,6 +963,7 @@ static void rna_def_mproperties(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshStringPropertyLayer", NULL);
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_ui_text(srna, "Mesh String Property Layer", "User defined layer of string text values.");
+ RNA_def_struct_path_func(srna, "rna_MeshStringPropertyLayer_path");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
@@ -858,6 +977,7 @@ static void rna_def_mproperties(BlenderRNA *brna)
srna= RNA_def_struct(brna, "MeshStringProperty", NULL);
RNA_def_struct_sdna(srna, "MStringProperty");
RNA_def_struct_ui_text(srna, "Mesh String Property", "User defined string text value in a string properties layer.");
+ RNA_def_struct_path_func(srna, "rna_MeshStringProperty_path");
prop= RNA_def_property(srna, "value", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "s");
@@ -896,7 +1016,6 @@ void rna_def_texmat_common(StructRNA *srna, const char *texspace_editable)
RNA_def_property_ui_text(prop, "Materials", "");
}
-
static void rna_def_mesh(BlenderRNA *brna)
{
StructRNA *srna;
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index 5107ed0df70..737bb52a466 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -37,7 +37,7 @@
static int rna_Meta_texspace_editable(PointerRNA *ptr)
{
MetaBall *mb= (MetaBall*)ptr->data;
- return (mb->texflag & AUTOSPACE)? PROP_NOT_EDITABLE: 0;
+ return (mb->texflag & AUTOSPACE)? 0: PROP_EDITABLE;
}
#else
@@ -60,7 +60,7 @@ void rna_def_metaelement(BlenderRNA *brna)
/* enums */
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Type", "Metaball types.");
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 0284d428939..5c609550d3f 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -471,7 +471,7 @@ static void rna_def_modifier_decimate(BlenderRNA *brna)
prop= RNA_def_property(srna, "face_count", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "faceCount");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Face Count", "The current number of faces in the decimated mesh.");
}
@@ -1569,7 +1569,7 @@ void RNA_def_modifier(BlenderRNA *brna)
/* enums */
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Type", "");
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 1588544966a..6fb6a67650f 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -17,12 +17,13 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * Contributor(s): Blender Foundation (2008), Nathan Letwory
+ * Contributor(s): Blender Foundation (2008), Nathan Letwory, Robin Allen
*
* ***** END GPL LICENSE BLOCK *****
*/
#include <stdlib.h>
+#include <string.h>
#include "RNA_define.h"
#include "RNA_types.h"
@@ -34,47 +35,436 @@
#ifdef RNA_RUNTIME
-static void rna_Nodetree_nodes_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
+StructRNA *rna_Node_refine(struct PointerRNA *ptr)
{
- bNodeTree *ntree= (bNodeTree*)ptr->data;
- rna_iterator_listbase_begin(iter, &ntree->nodes, NULL);
+ bNode *node= (bNode*)ptr->data;
+
+ switch(node->type) {
+
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ case ID: return &RNA_##Category##StructName;
+
+ #include "rna_nodetree_types.h"
+
+ #undef DefNode
+
+ default:
+ return &RNA_Node;
+ }
}
#else
+#define MaxNodes 1000
+
+enum
+{
+ Category_NoCategory,
+ Category_ShaderNode,
+ Category_CompositorNode,
+ Category_TextureNode
+};
+
+typedef struct NodeInfo
+{
+ int defined;
+ int category;
+ const char *enum_name;
+ const char *struct_name;
+ const char *base_name;
+ const char *ui_name;
+ const char *ui_desc;
+} NodeInfo;
+
+static NodeInfo nodes[MaxNodes];
+
+static void reg_node(
+ int ID,
+ int category,
+ const char *enum_name,
+ const char *struct_name,
+ const char *base_name,
+ const char *ui_name,
+ const char *ui_desc
+){
+ NodeInfo *ni = nodes + ID;
+
+ ni->defined = 1;
+ ni->category = category;
+ ni->enum_name = enum_name;
+ ni->struct_name = struct_name;
+ ni->base_name = base_name;
+ ni->ui_name = ui_name;
+ ni->ui_desc = ui_desc;
+}
+
+static void init(void)
+{
+ memset(nodes, 0, sizeof nodes);
+
+ #define Str(x) #x
+
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ reg_node(ID, Category_##Category, EnumName, Str(Category##StructName), #Category, UIName, UIDesc);
+
+ #include "rna_nodetree_types.h"
+
+ #undef DefNode
+ #undef Str
+}
+
+static StructRNA* def_node(BlenderRNA *brna, int node_id)
+{
+ StructRNA *srna;
+ NodeInfo *node = nodes + node_id;
+
+ srna= RNA_def_struct(brna, node->struct_name, node->base_name);
+ RNA_def_struct_ui_text(srna, node->ui_name, node->ui_desc);
+ RNA_def_struct_sdna(srna, "bNode");
+
+ return srna;
+}
+
+static EnumPropertyItem* alloc_node_type_items(int category)
+{
+ int i;
+ int count = 2;
+ EnumPropertyItem *item, *items;
+
+ for(i=0; i<MaxNodes; i++)
+ if(nodes[i].defined && nodes[i].category == category)
+ count++;
+
+ item = items = malloc(count * sizeof(EnumPropertyItem));
+
+ for(i=0; i<MaxNodes; i++) {
+ NodeInfo *node = nodes + i;
+ if(node->defined && node->category == category) {
+ item->value = i;
+ item->identifier = node->enum_name;
+ item->name = node->ui_name;
+ item->description = node->ui_desc;
+
+ item++;
+ }
+ }
+
+ item->value = NODE_DYNAMIC;
+ item->identifier = "SCRIPT";
+ item->name = "Script";
+ item->description = "";
+
+ item++;
+
+ memset(item, 0, sizeof(EnumPropertyItem));
+
+ return items;
+}
+
+
+/* -- Common nodes ---------------------------------------------------------- */
+
+static void def_math(BlenderRNA *brna, int id)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem items[] ={
+ { 0, "ADD", "Add", ""},
+ { 1, "SUBTRACT", "Subtract", ""},
+ { 2, "MULTIPLY", "Multiply", ""},
+ { 3, "DIVIDE", "Divide", ""},
+ { 4, "SINE", "Sine", ""},
+ { 5, "COSINE", "Cosine", ""},
+ { 6, "TANGENT", "Tangent", ""},
+ { 7, "ARCSINE", "Arcsine", ""},
+ { 8, "ARCCOSINE", "Arccosine", ""},
+ { 9, "ARCTANGENT", "Arctangent", ""},
+ {10, "POWER", "Power", ""},
+ {11, "LOGARITHM", "Logarithm", ""},
+ {12, "MINIMUM", "Minimum", ""},
+ {13, "MAXIMUM", "Maximum", ""},
+ {14, "ROUND", "Round", ""},
+ {15, "LESS_THAN", "Less Than", ""},
+ {16, "GREATER_THAN", "Greater Than", ""},
+
+ {0, NULL, NULL, NULL}
+ };
+
+ srna= def_node(brna, id);
+
+ prop= RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, items);
+ RNA_def_property_ui_text(prop, "Operation", "");
+}
+
+static void def_vector_math(BlenderRNA *brna, int id)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem items[] ={
+ {0, "ADD", "Add", ""},
+ {1, "SUBTRACT", "Subtract", ""},
+ {2, "AVERAGE", "Average", ""},
+ {3, "DOT_PRODUCT", "Dot Product", ""},
+ {4, "CROSS_PRODUCT", "Cross Product", ""},
+ {5, "NORMALIZE", "Normalize", ""},
+
+ {0, NULL, NULL, NULL}
+ };
+
+ srna= def_node(brna, id);
+
+ prop= RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, items);
+ RNA_def_property_ui_text(prop, "Operation", "");
+}
+
+static void def_rgb_curve(BlenderRNA *brna, int id)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= def_node(brna, id);
+
+ prop= RNA_def_property(srna, "mapping", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "storage");
+ RNA_def_property_struct_type(prop, "CurveMapping");
+ RNA_def_property_ui_text(prop, "Mapping", "");
+}
+
+static void def_vector_curve(BlenderRNA *brna, int id)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= def_node(brna, id);
+
+ prop= RNA_def_property(srna, "mapping", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "storage");
+ RNA_def_property_struct_type(prop, "CurveMapping");
+ RNA_def_property_ui_text(prop, "Mapping", "");
+}
+
+static void def_val_to_rgb(BlenderRNA *brna, int id)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= def_node(brna, id);
+
+ /* TODO: uncomment when ColorBand is wrapped */
+ /*prop= RNA_def_property(srna, "color_band", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "storage");
+ RNA_def_property_struct_type(prop, "ColorBand");
+ RNA_def_property_ui_text(prop, "Color Band", "");*/
+}
+
+static void def_mix_rgb(BlenderRNA *brna, int id)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem blend_type_items[] ={
+ { 0, "MIX", "Mix", ""},
+ { 1, "ADD", "Add", ""},
+ { 3, "SUBTRACT", "Subtract", ""},
+ { 2, "MULTIPLY", "Multiply", ""},
+ { 4, "SCREEN", "Screen", ""},
+ { 9, "OVERLAY", "Overlay", ""},
+ { 5, "DIVIDE", "Divide", ""},
+ { 6, "DIFFERENCE", "Difference", ""},
+ { 7, "DARKEN", "Darken", ""},
+ { 8, "LIGHTEN", "Lighten", ""},
+ {10, "DODGE", "Dodge", ""},
+ {11, "BURN", "Burn", ""},
+ {15, "COLOR", "Color", ""},
+ {14, "VALUE", "Value", ""},
+ {13, "SATURATION", "Saturation", ""},
+ {12, "HUE", "Hue", ""},
+ {0, NULL, NULL, NULL}
+ };
+
+ srna= def_node(brna, id);
+
+ prop= RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, blend_type_items);
+ RNA_def_property_ui_text(prop, "Blend Type", "");
+
+ prop= RNA_def_property(srna, "alpha", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom2", 1);
+ RNA_def_property_ui_text(prop, "Diffuse", "Include alpha of second input in this operation");
+}
+
+
+/* -- Shader Node Storage Types --------------------------------------------- */
+
+static void rna_def_storage_node_geometry(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "NodeGeometry", NULL);
+ RNA_def_struct_ui_text(srna, "Node Geometry", "");
+
+ prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "uvname");
+ RNA_def_property_ui_text(prop, "UV Layer", "");
+
+ prop= RNA_def_property(srna, "color_layer", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "colname");
+ RNA_def_property_ui_text(prop, "Vertex Color Layer", "");
+}
+
+
+/* -- Shader Nodes ---------------------------------------------------------- */
+
+static void def_sh_texture(BlenderRNA *brna, int id)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= def_node(brna, id);
+
+ prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "Texture");
+ RNA_def_property_ui_text(prop, "Texture", "");
+
+ prop= RNA_def_property(srna, "node_output", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "custom1");
+ RNA_def_property_ui_text(prop, "Node Output", "For node-based textures, which output node to use");
+}
+
+static void def_sh_material(BlenderRNA *brna, int id)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= def_node(brna, id);
+
+ prop= RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "id");
+ RNA_def_property_struct_type(prop, "Material");
+ RNA_def_property_ui_text(prop, "Material", "");
+
+ prop= RNA_def_property(srna, "diffuse", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_DIFF);
+ RNA_def_property_ui_text(prop, "Diffuse", "Material Node outputs Diffuse");
+
+ prop= RNA_def_property(srna, "specular", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_SPEC);
+ RNA_def_property_ui_text(prop, "Specular", "Material Node outputs Specular");
+
+ prop= RNA_def_property(srna, "invert_normal", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom1", SH_NODE_MAT_NEG);
+ RNA_def_property_ui_text(prop, "Invert Normal", "Material Node uses inverted normal");
+}
+
+static void def_sh_mapping(BlenderRNA *brna, int id)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= def_node(brna, id);
+
+ prop= RNA_def_property(srna, "mapping", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "storage");
+ RNA_def_property_struct_type(prop, "TexMapping");
+ RNA_def_property_ui_text(prop, "Mapping", "");
+}
+
+static void def_sh_geometry(BlenderRNA *brna, int id)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= def_node(brna, id);
+
+ prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "storage");
+ RNA_def_property_struct_type(prop, "NodeGeometry");
+ RNA_def_property_ui_text(prop, "Settings", "");
+}
+
+/* -- Compositor Nodes ------------------------------------------------------ */
+
+/* -- Texture Nodes --------------------------------------------------------- */
+
+/* -------------------------------------------------------------------------- */
+
+static void rna_def_shader_node(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ EnumPropertyItem *node_type_items;
+
+ node_type_items = alloc_node_type_items(Category_ShaderNode);
+
+ srna= RNA_def_struct(brna, "ShaderNode", "Node");
+ RNA_def_struct_ui_text(srna, "Shader Node", "Material shader node.");
+ RNA_def_struct_sdna(srna, "bNode");
+
+ prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_enum_items(prop, node_type_items);
+ RNA_def_property_ui_text(prop, "Type", "");
+
+ /* Shader storage types */
+ rna_def_storage_node_geometry(brna);
+}
+
+static void rna_def_compositor_node(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ EnumPropertyItem *node_type_items;
+
+ node_type_items = alloc_node_type_items(Category_CompositorNode);
+
+ srna= RNA_def_struct(brna, "CompositorNode", "Node");
+ RNA_def_struct_ui_text(srna, "Compositor Node", "");
+ RNA_def_struct_sdna(srna, "bNode");
+
+ prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_enum_items(prop, node_type_items);
+ RNA_def_property_ui_text(prop, "Type", "");
+}
+
+static void rna_def_texture_node(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ EnumPropertyItem *node_type_items;
+
+ node_type_items = alloc_node_type_items(Category_TextureNode);
+
+ srna= RNA_def_struct(brna, "TextureNode", "Node");
+ RNA_def_struct_ui_text(srna, "Texture Node", "");
+ RNA_def_struct_sdna(srna, "bNode");
+
+ prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_enum_items(prop, node_type_items);
+ RNA_def_property_ui_text(prop, "Type", "");
+}
+
+/* -------------------------------------------------------------------------- */
+
static void rna_def_node(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem node_type_items[] ={
- {SH_NODE_OUTPUT, "OUTPUT", "Output", ""},
- {SH_NODE_MATERIAL, "MATERIAL", "Material", ""},
- {SH_NODE_RGB, "RGB", "RGB", ""},
- {SH_NODE_VALUE, "VALUE", "Value", ""},
- {SH_NODE_MIX_RGB, "MIX_RGB", "Mix RGB", ""},
- {SH_NODE_VALTORGB, "VALUE_TO_RGB", "Value to RGB", ""},
- {SH_NODE_RGBTOBW, "RGB_TO_BW", "RGB to BW", ""},
- {SH_NODE_TEXTURE, "TEXTURE", "Texture", ""},
- {SH_NODE_NORMAL, "NORMAL", "Normal", ""},
- {SH_NODE_GEOMETRY, "GEOMETRY", "Geometry", ""},
- {SH_NODE_MAPPING, "MAPPING", "Mapping", ""},
- {SH_NODE_CURVE_VEC, "VECTOR_CURVES", "Vector Curves", ""},
- {SH_NODE_CURVE_RGB, "RGB_CURVES", "RGB Curves", ""},
- {SH_NODE_CAMERA, "CAMERA", "Camera", ""},
- {SH_NODE_MATH, "MATH", "Math", ""},
- {SH_NODE_VECT_MATH, "VECTOR_MATH", "Vector Math", ""},
- {SH_NODE_SQUEEZE, "SQUEEZE", "Squeeze", ""},
- {SH_NODE_MATERIAL_EXT, "MATERIAL_EXTENDED", "Material Extended", ""},
- {SH_NODE_INVERT, "INVERT", "Invert", ""},
- {SH_NODE_SEPRGB, "SEPARATE_RGB", "Seperate RGB", ""},
- {SH_NODE_COMBRGB, "COMBINE_RGB", "Combine RGB", ""},
- {SH_NODE_HUE_SAT, "HUE_SATURATION", "Hue/Saturation", ""},
- {NODE_DYNAMIC, "SCRIPT", "Script", ""},
- {0, NULL, NULL, NULL}};
srna= RNA_def_struct(brna, "Node", NULL);
RNA_def_struct_ui_text(srna, "Node", "Node in a node tree.");
RNA_def_struct_sdna(srna, "bNode");
+ RNA_def_struct_refine_func(srna, "rna_Node_refine");
prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_float_sdna(prop, NULL, "locx");
@@ -85,14 +475,9 @@ static void rna_def_node(BlenderRNA *brna)
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "Node name.");
RNA_def_struct_name_property(srna, prop);
-
- prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
- RNA_def_property_enum_items(prop, node_type_items);
- RNA_def_property_ui_text(prop, "Type", "");
}
-void RNA_def_nodetree(BlenderRNA *brna)
+static void rna_def_nodetree(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -103,11 +488,35 @@ void RNA_def_nodetree(BlenderRNA *brna)
prop= RNA_def_property(srna, "nodes", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "nodes", NULL);
- RNA_def_property_collection_funcs(prop, "rna_Nodetree_nodes_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0);
RNA_def_property_struct_type(prop, "Node");
RNA_def_property_ui_text(prop, "Nodes", "");
-
+}
+
+static void define_simple_node(BlenderRNA *brna, int id)
+{
+ def_node(brna, id);
+}
+
+static void define_specific_node(BlenderRNA *brna, int id, void (*func)(BlenderRNA*, int))
+{
+ func(brna, id);
+}
+
+void RNA_def_nodetree(BlenderRNA *brna)
+{
+ init();
+ rna_def_nodetree(brna);
rna_def_node(brna);
+ rna_def_shader_node(brna);
+ rna_def_compositor_node(brna);
+ rna_def_texture_node(brna);
+
+ #define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+ define_specific_node(brna, ID, DefFunc ? DefFunc : define_simple_node);
+
+ #include "rna_nodetree_types.h"
+
+ #undef DefNode
}
#endif
diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h
new file mode 100644
index 00000000000..00b7f7e62cb
--- /dev/null
+++ b/source/blender/makesrna/intern/rna_nodetree_types.h
@@ -0,0 +1,131 @@
+/**
+ * $Id$
+ *
+ * ***** 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.
+ *
+ * Contributor(s): Blender Foundation (2008), Robin Allen
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* Tree type Node ID RNA def function Enum name Struct name UI Name UI Description */
+DefNode( ShaderNode, SH_NODE_OUTPUT, 0, "OUTPUT", Output, "Output", "" )
+DefNode( ShaderNode, SH_NODE_MATERIAL, def_sh_material, "MATERIAL", Material, "Material", "" )
+DefNode( ShaderNode, SH_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
+DefNode( ShaderNode, SH_NODE_VALUE, 0, "VALUE", Value, "Value", "" )
+DefNode( ShaderNode, SH_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "MixRGB", "" )
+DefNode( ShaderNode, SH_NODE_VALTORGB, def_val_to_rgb, "VALTORGB", ValToRGB, "Value to RGB", "" )
+DefNode( ShaderNode, SH_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
+DefNode( ShaderNode, SH_NODE_TEXTURE, def_sh_texture, "TEXTURE", Texture, "Texture", "" )
+DefNode( ShaderNode, SH_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" )
+DefNode( ShaderNode, SH_NODE_GEOMETRY, def_sh_geometry, "GEOMETRY", Geometry, "Geometry", "" )
+DefNode( ShaderNode, SH_NODE_MAPPING, def_sh_mapping, "MAPPING", Mapping, "Mapping", "" )
+DefNode( ShaderNode, SH_NODE_CURVE_VEC, def_vector_curve, "CURVE_VEC", VectorCurve, "Vector Curve", "" )
+DefNode( ShaderNode, SH_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", RGBCurve, "RGB Curve", "" )
+DefNode( ShaderNode, SH_NODE_CAMERA, 0, "CAMERA", CameraData, "Camera Data", "" )
+DefNode( ShaderNode, SH_NODE_MATH, def_math, "MATH", Math, "Math", "" )
+DefNode( ShaderNode, SH_NODE_VECT_MATH, def_vector_math, "VECT_MATH", VectorMath, "Vector Math", "" )
+DefNode( ShaderNode, SH_NODE_SQUEEZE, 0, "SQUEEZE", Squeeze, "Squeeze", "" )
+DefNode( ShaderNode, SH_NODE_MATERIAL_EXT, def_sh_material, "MATERIAL_EXT", ExtendedMaterial, "Extended Material", "" )
+DefNode( ShaderNode, SH_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
+DefNode( ShaderNode, SH_NODE_SEPRGB, 0, "SEPRGB", SeparateRGB, "Separate RGB", "" )
+DefNode( ShaderNode, SH_NODE_COMBRGB, 0, "COMBRGB", CombineRGB, "Combine RGB", "" )
+DefNode( ShaderNode, SH_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" )
+
+DefNode( CompositorNode, CMP_NODE_VIEWER, 0, "VIEWER", Viewer, "Viewer", "" )
+DefNode( CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
+DefNode( CompositorNode, CMP_NODE_VALUE, 0, "VALUE", Value, "Value", "" )
+DefNode( CompositorNode, CMP_NODE_MIX_RGB, 0, "MIX_RGB", MixRGB, "Mix RGB", "" )
+DefNode( CompositorNode, CMP_NODE_VALTORGB, 0, "VALTORGB", ValToRGB, "Val to RGB", "" )
+DefNode( CompositorNode, CMP_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB to BW", "" )
+DefNode( CompositorNode, CMP_NODE_NORMAL, 0, "NORMAL", Normal, "Normal", "" )
+DefNode( CompositorNode, CMP_NODE_CURVE_VEC, 0, "CURVE_VEC", CurveVec, "Vector Curve", "" )
+DefNode( CompositorNode, CMP_NODE_CURVE_RGB, 0, "CURVE_RGB", CurveRGB, "RGB Curve", "" )
+DefNode( CompositorNode, CMP_NODE_ALPHAOVER, 0, "ALPHAOVER", AlphaOver, "Alpha Over", "" )
+DefNode( CompositorNode, CMP_NODE_BLUR, 0, "BLUR", Blur, "Blur", "" )
+DefNode( CompositorNode, CMP_NODE_FILTER, 0, "FILTER", Filter, "Filter", "" )
+DefNode( CompositorNode, CMP_NODE_MAP_VALUE, 0, "MAP_VALUE", MapValue, "Map Value", "" )
+DefNode( CompositorNode, CMP_NODE_TIME, 0, "TIME", Time, "Time", "" )
+DefNode( CompositorNode, CMP_NODE_VECBLUR, 0, "VECBLUR", VecBlur, "Vector Blur", "" )
+DefNode( CompositorNode, CMP_NODE_SEPRGBA, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" )
+DefNode( CompositorNode, CMP_NODE_SEPHSVA, 0, "SEPHSVA", SepHSVA, "Separate HSVA", "" )
+DefNode( CompositorNode, CMP_NODE_SETALPHA, 0, "SETALPHA", SetAlpha, "Set Alpha", "" )
+DefNode( CompositorNode, CMP_NODE_HUE_SAT, 0, "HUE_SAT", HueSat, "Hue/Saturation", "" )
+DefNode( CompositorNode, CMP_NODE_IMAGE, 0, "IMAGE", Image, "Image", "" )
+DefNode( CompositorNode, CMP_NODE_R_LAYERS, 0, "R_LAYERS", RLayers, "Render Layers", "" )
+DefNode( CompositorNode, CMP_NODE_COMPOSITE, 0, "COMPOSITE", Composite, "Composite", "" )
+DefNode( CompositorNode, CMP_NODE_OUTPUT_FILE, 0, "OUTPUT_FILE", OutputFile, "Output File", "" )
+DefNode( CompositorNode, CMP_NODE_TEXTURE, 0, "TEXTURE", Texture, "Texture", "" )
+DefNode( CompositorNode, CMP_NODE_TRANSLATE, 0, "TRANSLATE", Translate, "Translate", "" )
+DefNode( CompositorNode, CMP_NODE_ZCOMBINE, 0, "ZCOMBINE", Zcombine, "Z Combine", "" )
+DefNode( CompositorNode, CMP_NODE_COMBRGBA, 0, "COMBRGBA", CombRGBA, "Combine RGBA", "" )
+DefNode( CompositorNode, CMP_NODE_DILATEERODE, 0, "DILATEERODE", DilateErode, "Dilate/Erode", "" )
+DefNode( CompositorNode, CMP_NODE_ROTATE, 0, "ROTATE", Rotate, "Rotate", "" )
+DefNode( CompositorNode, CMP_NODE_SCALE, 0, "SCALE", Scale, "Scale", "" )
+DefNode( CompositorNode, CMP_NODE_SEPYCCA, 0, "SEPYCCA", SepYCCA, "Separate YCCA", "" )
+DefNode( CompositorNode, CMP_NODE_COMBYCCA, 0, "COMBYCCA", CombYCCA, "Combine YCCA", "" )
+DefNode( CompositorNode, CMP_NODE_SEPYUVA, 0, "SEPYUVA", SepYUVA, "Separate YUVA", "" )
+DefNode( CompositorNode, CMP_NODE_COMBYUVA, 0, "COMBYUVA", CombYUVA, "Combine YUVA", "" )
+DefNode( CompositorNode, CMP_NODE_DIFF_MATTE, 0, "DIFF_MATTE", DiffMatte, "Diff Matte", "" )
+DefNode( CompositorNode, CMP_NODE_COLOR_SPILL, 0, "COLOR_SPILL", ColorSpill, "Color Spill", "" )
+DefNode( CompositorNode, CMP_NODE_CHROMA, 0, "CHROMA", Chroma, "Chroma", "" )
+DefNode( CompositorNode, CMP_NODE_CHANNEL_MATTE, 0, "CHANNEL_MATTE", ChannelMatte, "Channel Matte", "" )
+DefNode( CompositorNode, CMP_NODE_FLIP, 0, "FLIP", Flip, "Flip", "" )
+DefNode( CompositorNode, CMP_NODE_SPLITVIEWER, 0, "SPLITVIEWER", SplitViewer, "Split Viewer", "" )
+DefNode( CompositorNode, CMP_NODE_INDEX_MASK, 0, "INDEX_MASK", IndexMask, "Index Mask", "" )
+DefNode( CompositorNode, CMP_NODE_MAP_UV, 0, "MAP_UV", MapUV, "Map UV", "" )
+DefNode( CompositorNode, CMP_NODE_ID_MASK, 0, "ID_MASK", IDMask, "ID Mask", "" )
+DefNode( CompositorNode, CMP_NODE_DEFOCUS, 0, "DEFOCUS", Defocus, "Defocus", "" )
+DefNode( CompositorNode, CMP_NODE_DISPLACE, 0, "DISPLACE", Displace, "Displace", "" )
+DefNode( CompositorNode, CMP_NODE_COMBHSVA, 0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
+DefNode( CompositorNode, CMP_NODE_MATH, def_math, "MATH", Math, "Math", "" )
+DefNode( CompositorNode, CMP_NODE_LUMA_MATTE, 0, "LUMA_MATTE", LumaMatte, "Luma Matte", "" )
+DefNode( CompositorNode, CMP_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright Contrast", "" )
+DefNode( CompositorNode, CMP_NODE_GAMMA, 0, "GAMMA", Gamma, "Gamma", "" )
+DefNode( CompositorNode, CMP_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
+DefNode( CompositorNode, CMP_NODE_NORMALIZE, 0, "NORMALIZE", Normalize, "Normalize", "" )
+DefNode( CompositorNode, CMP_NODE_CROP, 0, "CROP", Crop, "Crop", "" )
+DefNode( CompositorNode, CMP_NODE_DBLUR, 0, "DBLUR", DBlur, "DBlur", "" )
+DefNode( CompositorNode, CMP_NODE_BILATERALBLUR, 0, "BILATERALBLUR", Bilateralblur, "Bilateral Blur", "" )
+DefNode( CompositorNode, CMP_NODE_PREMULKEY, 0, "PREMULKEY", PremulKey, "Premul Key", "" )
+DefNode( CompositorNode, CMP_NODE_GLARE, 0, "GLARE", Glare, "Glare", "" )
+DefNode( CompositorNode, CMP_NODE_TONEMAP, 0, "TONEMAP", Tonemap, "Tonemap", "" )
+DefNode( CompositorNode, CMP_NODE_LENSDIST, 0, "LENSDIST", Lensdist, "Lensdist", "" )
+
+DefNode( TextureNode, TEX_NODE_OUTPUT, 0, "OUTPUT", Output, "Output", "" )
+DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
+DefNode( TextureNode, TEX_NODE_TEXTURE, 0, "TEXTURE", Texture, "Texture", "" )
+DefNode( TextureNode, TEX_NODE_BRICKS, 0, "BRICKS", Bricks, "Bricks", "" )
+DefNode( TextureNode, TEX_NODE_MATH, def_math, "MATH", Math, "Math", "" )
+DefNode( TextureNode, TEX_NODE_MIX_RGB, def_mix_rgb, "MIX_RGB", MixRGB, "Mix RGB", "" )
+DefNode( TextureNode, TEX_NODE_RGBTOBW, 0, "RGBTOBW", RGBToBW, "RGB To BW", "" )
+DefNode( TextureNode, TEX_NODE_VALTORGB, def_val_to_rgb, "VALTORGB", ValToRGB, "Val To RGB", "" )
+DefNode( TextureNode, TEX_NODE_IMAGE, 0, "IMAGE", Image, "Image", "" )
+DefNode( TextureNode, TEX_NODE_CURVE_RGB, def_rgb_curve, "CURVE_RGB", CurveRGB, "RGB Curve", "" )
+DefNode( TextureNode, TEX_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
+DefNode( TextureNode, TEX_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" )
+DefNode( TextureNode, TEX_NODE_CURVE_TIME, 0, "CURVE_TIME", CurveTime, "Curve Time", "" )
+DefNode( TextureNode, TEX_NODE_ROTATE, 0, "ROTATE", Rotate, "Rotate", "" )
+DefNode( TextureNode, TEX_NODE_VIEWER, 0, "VIEWER", Viewer, "Viewer", "" )
+DefNode( TextureNode, TEX_NODE_TRANSLATE, 0, "TRANSLATE", Translate, "Translate", "" )
+DefNode( TextureNode, TEX_NODE_COORD, 0, "COORD", Coordinates, "Coordinates", "" )
+DefNode( TextureNode, TEX_NODE_DISTANCE, 0, "DISTANCE", Distance, "Distance", "" )
+DefNode( TextureNode, TEX_NODE_COMPOSE, 0, "COMPOSE", Compose, "Compose", "" )
+DefNode( TextureNode, TEX_NODE_DECOMPOSE, 0, "DECOMPOSE", Decompose, "Decompose", "" )
+DefNode( TextureNode, TEX_NODE_VALTONOR, 0, "VALTONOR", ValToNor, "Val to Nor", "" )
+DefNode( TextureNode, TEX_NODE_SCALE, 0, "SCALE", Scale, "Scale", "" )
+
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 2907658b17e..534f1ea0e98 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -255,7 +255,7 @@ static void rna_def_vertex_group(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
prop= RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_VertexGroup_index_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Index", "Index number of the vertex group.");
}
@@ -324,7 +324,7 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
prop= RNA_def_property(srna, "physics_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "body_type");
RNA_def_property_enum_items(prop, body_type_items);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // this controls various gameflags
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // this controls various gameflags
RNA_def_property_ui_text(prop, "Physics Type", "Selects the type of physical representation.");
prop= RNA_def_property(srna, "actor", PROP_BOOLEAN, PROP_NONE);
@@ -508,13 +508,13 @@ static StructRNA *rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "parent_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "partype");
RNA_def_property_enum_items(prop, parent_type_items);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Parent Type", "Type of parent relation.");
prop= RNA_def_property(srna, "parent_vertices", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "par1");
RNA_def_property_array(prop, 3);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Parent Vertices", "Indices of vertices in cases of a vertex parenting relation.");
prop= RNA_def_property(srna, "parent_bone", PROP_STRING, PROP_NONE);
@@ -550,7 +550,7 @@ static StructRNA *rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Materials", "");
prop= RNA_def_property(srna, "active_material", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Material");
RNA_def_property_pointer_funcs(prop, "rna_Object_active_material_get", NULL);
RNA_def_property_ui_text(prop, "Active Material", "Active material being displayed.");
@@ -704,7 +704,7 @@ static StructRNA *rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "draw_keys", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_DRAWKEY);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // update ipo flag indirect
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // update ipo flag indirect
RNA_def_property_ui_text(prop, "Draw Keys", "Draw object as key positions.");
prop= RNA_def_property(srna, "draw_keys_selected", PROP_BOOLEAN, PROP_NONE);
@@ -722,22 +722,22 @@ static StructRNA *rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "dupli_frames", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLIFRAMES);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // clear other flags
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // clear other flags
RNA_def_property_ui_text(prop, "Dupli Frames", "Make copy of object for every frame.");
prop= RNA_def_property(srna, "dupli_verts", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLIVERTS);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // clear other flags
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // clear other flags
RNA_def_property_ui_text(prop, "Dupli Verts", "Duplicate child objects on all vertices.");
prop= RNA_def_property(srna, "dupli_faces", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLIFACES);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // clear other flags
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // clear other flags
RNA_def_property_ui_text(prop, "Dupli Faces", "Duplicate child objects on all faces.");
prop= RNA_def_property(srna, "use_dupli_group", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLIGROUP);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // clear other flags
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // clear other flags
RNA_def_property_ui_text(prop, "Use Dupli Group", "Enable group instancing.");
prop= RNA_def_property(srna, "dupli_frames_no_speed", PROP_BOOLEAN, PROP_NONE);
@@ -814,7 +814,7 @@ static StructRNA *rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "script_link", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "scriptlink");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Script Link", "Scripts linked to this object.");
/* drawing */
@@ -830,7 +830,7 @@ static StructRNA *rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Draw Bounds", "Displays the object's bounds.");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
- prop= RNA_def_property(srna, "draw_bounds_types", PROP_ENUM, PROP_NONE);
+ prop= RNA_def_property(srna, "draw_bounds_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "boundtype");
RNA_def_property_enum_items(prop, boundtype_items);
RNA_def_property_ui_text(prop, "Draw Bounds Type", "Object boundary display type.");
@@ -879,7 +879,7 @@ static StructRNA *rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "pose_mode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", OB_POSEMODE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Pose Mode", "Object with armature data is in pose mode.");
// XXX this stuff should be moved to AnimData...
@@ -890,18 +890,18 @@ static StructRNA *rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "nla_collapsed", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "nlaflag", OB_NLA_COLLAPSED);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "NLA Collapsed", "");
prop= RNA_def_property(srna, "nla_override", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "nlaflag", OB_NLA_OVERRIDE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "NLA Override", "");
prop= RNA_def_property(srna, "nla_strips", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "nlastrips", NULL);
RNA_def_property_struct_type(prop, "UnknownType");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "NLA Strips", "NLA strips of the object.");
*/
@@ -909,12 +909,12 @@ static StructRNA *rna_def_object(BlenderRNA *brna)
prop= RNA_def_property(srna, "shape_key_lock", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "shapeflag", OB_SHAPE_LOCK);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Shape Key Lock", "Always show the current Shape for this Object.");
prop= RNA_def_property(srna, "active_shape_key", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "shapenr");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active Shape Key", "Current shape key index.");
return srna;
diff --git a/source/blender/makesrna/intern/rna_packedfile.c b/source/blender/makesrna/intern/rna_packedfile.c
index 5645765ed83..6b6db71ef87 100644
--- a/source/blender/makesrna/intern/rna_packedfile.c
+++ b/source/blender/makesrna/intern/rna_packedfile.c
@@ -1,5 +1,5 @@
/**
- * $Id$
+ * $Id: rna_packedfile.c 19382 2009-03-23 13:24:48Z blendix $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -43,7 +43,7 @@ void RNA_def_packedfile(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Packed File", "External file packed into the .blend file.");
prop= RNA_def_property(srna, "size", PROP_INT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Size", "Size of packed file in bytes.");
}
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 1e5ccfd9750..7de0b4e3400 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -32,6 +32,7 @@
#include "rna_internal.h"
#include "DNA_particle_types.h"
+#include "DNA_object_force.h"
#ifdef RNA_RUNTIME
@@ -87,30 +88,24 @@ static float rna_PartSetting_linelenhead_get(struct PointerRNA *ptr)
}
#else
-static void rna_def_hair_key(BlenderRNA *brna)
+static void rna_def_particle_hair_key(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- srna = RNA_def_struct(brna, "HairKey", NULL);
- RNA_def_struct_ui_text(srna, "Hair Key", "DOC_BROKEN");
+ srna = RNA_def_struct(brna, "ParticleHairKey", NULL);
+ RNA_def_struct_sdna(srna, "HairKey");
+ RNA_def_struct_ui_text(srna, "Particle Hair Key", "Particle key for hair particle system.");
- prop= RNA_def_property(srna, "hair_vertex_location", PROP_FLOAT, PROP_VECTOR);
+ prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_float_sdna(prop, NULL, "co");
- RNA_def_property_array(prop, 3);
- //TODO:bounds
- RNA_def_property_ui_text(prop, "Hair Vertex Location", "");
-
- prop= RNA_def_property(srna, "time", PROP_FLOAT, PROP_NONE);
-// RNA_def_property_range(prop, lowerLimitf, upperLimitf);
- RNA_def_property_ui_text(prop, "Time", "Time along hair");
-
- prop= RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE);
-// RNA_def_property_range(prop, lowerLimitf, upperLimitf);
- RNA_def_property_ui_text(prop, "Softbody Weight", "");
+ RNA_def_property_ui_text(prop, "Location", "Key location.");
-// short editflag; /* saved particled edit mode flags */
+ prop= RNA_def_property(srna, "time", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_ui_text(prop, "Time", "Relative time of key over hair length.");
+ prop= RNA_def_property(srna, "weight", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_ui_text(prop, "Weight", "Weight for softbody simulation.");
}
static void rna_def_particle_key(BlenderRNA *brna)
@@ -119,36 +114,26 @@ static void rna_def_particle_key(BlenderRNA *brna)
PropertyRNA *prop;
srna = RNA_def_struct(brna, "ParticleKey", NULL);
- RNA_def_struct_ui_text(srna, "Particle Key", "DOC_BROKEN");
+ RNA_def_struct_ui_text(srna, "Particle Key", "Key location for a particle over time.");
prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_float_sdna(prop, NULL, "co");
- RNA_def_property_array(prop, 3);
- //TODO:bounds
- RNA_def_property_ui_text(prop, "Location", "");
+ RNA_def_property_ui_text(prop, "Location", "Key location.");
prop= RNA_def_property(srna, "velocity", PROP_FLOAT, PROP_VECTOR);
RNA_def_property_float_sdna(prop, NULL, "vel");
- RNA_def_property_array(prop, 3);
- //TODO:bounds
- RNA_def_property_ui_text(prop, "Velocity", "");
+ RNA_def_property_ui_text(prop, "Velocity", "Key velocity");
- prop= RNA_def_property(srna, "rotation_quaternion", PROP_FLOAT, PROP_VECTOR);
+ prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ROTATION);
RNA_def_property_float_sdna(prop, NULL, "rot");
- RNA_def_property_array(prop, 4);
- //TODO:bounds
- RNA_def_property_ui_text(prop, "Rotation Quaternion", "");
+ RNA_def_property_ui_text(prop, "Rotation", "Key rotation quaterion.");
- prop= RNA_def_property(srna, "angular_velocity", PROP_FLOAT, PROP_VECTOR);
+ prop= RNA_def_property(srna, "angular_velocity", PROP_FLOAT, PROP_ROTATION);
RNA_def_property_float_sdna(prop, NULL, "ave");
- RNA_def_property_array(prop, 3);
- //TODO:bounds
- RNA_def_property_ui_text(prop, "Angular Velocity", "");
+ RNA_def_property_ui_text(prop, "Angular Velocity", "Key angular velocity.");
- prop= RNA_def_property(srna, "time", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "time");//optional if prop names are the same
-// RNA_def_property_range(prop, lowerLimitf, upperLimitf);
- RNA_def_property_ui_text(prop, "Time", "Time along hair");
+ prop= RNA_def_property(srna, "time", PROP_FLOAT, PROP_UNSIGNED);
+ RNA_def_property_ui_text(prop, "Time", "Time of key over the simulation.");
}
static void rna_def_child_particle(BlenderRNA *brna)
@@ -157,7 +142,7 @@ static void rna_def_child_particle(BlenderRNA *brna)
//PropertyRNA *prop;
srna = RNA_def_struct(brna, "ChildParticle", NULL);
- RNA_def_struct_ui_text(srna, "Child Particle", "DOC_BROKEN");
+ RNA_def_struct_ui_text(srna, "Child Particle", "Child particle interpolated from simulated or edited particles.");
// int num, parent; /* num is face index on the final derived mesh */
@@ -167,7 +152,7 @@ static void rna_def_child_particle(BlenderRNA *brna)
// float rand[3];
}
-static void rna_def_particle_data(BlenderRNA *brna)
+static void rna_def_particle(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -299,14 +284,14 @@ static void rna_def_particle_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Alive State", "");
prop= RNA_def_property(srna, "loop", PROP_INT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
//TODO: bounds
RNA_def_property_ui_text(prop, "Loop", "How may times the particle life has looped");
// short rt2;
}
-static void rna_def_particlesettings(BlenderRNA *brna)
+static void rna_def_particle_settings(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -521,7 +506,7 @@ static void rna_def_particlesettings(BlenderRNA *brna)
prop= RNA_def_property(srna, "branching", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_BRANCHING);
- RNA_def_property_ui_text(prop, "Branching", "Branch child paths from eachother.");
+ RNA_def_property_ui_text(prop, "Branching", "Branch child paths from each other.");
prop= RNA_def_property(srna, "animate_branching", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_ANIM_BRANCHING);
@@ -1034,12 +1019,12 @@ static void rna_def_particlesettings(BlenderRNA *brna)
prop= RNA_def_property(srna, "clump_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clumpfac");
RNA_def_property_range(prop, -1.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Clump", "Amount of clumpimg");
+ RNA_def_property_ui_text(prop, "Clump", "Amount of clumping");
prop= RNA_def_property(srna, "clumppow", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clumppow");
RNA_def_property_range(prop, -0.999f, 0.999f);
- RNA_def_property_ui_text(prop, "Shape", "Shape of clumpimg");
+ RNA_def_property_ui_text(prop, "Shape", "Shape of clumping");
/* kink */
@@ -1061,11 +1046,11 @@ static void rna_def_particlesettings(BlenderRNA *brna)
/* rough */
prop= RNA_def_property(srna, "rough1", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 10.0f);
- RNA_def_property_ui_text(prop, "Rough1", "Amount of location dependant rough.");
+ RNA_def_property_ui_text(prop, "Rough1", "Amount of location dependent rough.");
prop= RNA_def_property(srna, "rough1_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.01f, 10.0f);
- RNA_def_property_ui_text(prop, "Size1", "Size of location dependant rough.");
+ RNA_def_property_ui_text(prop, "Size1", "Size of location dependent rough.");
prop= RNA_def_property(srna, "rough2", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rough2");
@@ -1173,7 +1158,7 @@ static void rna_def_particlesettings(BlenderRNA *brna)
#if 0
prop= RNA_def_property(srna, "ipo", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_pointer_sdna(prop, NULL, "ipo");
RNA_def_property_struct_type(prop, "Ipo");
RNA_def_property_ui_text(prop, "Ipo", "");
@@ -1183,7 +1168,7 @@ static void rna_def_particlesettings(BlenderRNA *brna)
// struct PartDeflect *pd2;
}
-static void rna_def_particlesystem(BlenderRNA *brna)
+static void rna_def_particle_system(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -1205,10 +1190,24 @@ static void rna_def_particlesystem(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "ChildParticle");
RNA_def_property_ui_text(prop, "Child Particles", "Child particles generated by the particle system.");
+ prop= RNA_def_property(srna, "seed", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_ui_text(prop, "Seed", "Offset in the random number table, to get a different randomized result.");
+
+ /* hair */
prop= RNA_def_property(srna, "softbody", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "soft");
RNA_def_property_ui_text(prop, "Soft Body", "Soft body settings for hair physics simulation.");
+ prop= RNA_def_property(srna, "use_softbody", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "softflag", OB_SB_ENABLE);
+ RNA_def_property_ui_text(prop, "Use Soft Body", "Enable use of soft body for hair physics simulation.");
+
+ prop= RNA_def_property(srna, "editable", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_EDITED);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* various checks needed */
+ RNA_def_property_ui_text(prop, "Editable", "For hair particle systems, finalize the hair to enable editing.");
+
+ /* reactor */
prop= RNA_def_property(srna, "reactor_target_object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "target_ob");
RNA_def_property_ui_text(prop, "Reactor Target Object", "For reactor systems, the object that has the target particle system (empty if same object).");
@@ -1218,10 +1217,12 @@ static void rna_def_particlesystem(BlenderRNA *brna)
RNA_def_property_range(prop, 1, INT_MAX);
RNA_def_property_ui_text(prop, "Reactor Target Particle System", "For reactor systems, index of particle system on the target object.");
+ /* boids */
prop= RNA_def_property(srna, "boids_surface_object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "keyed_ob");
RNA_def_property_ui_text(prop, "Boids Surface Object", "For boids physics systems, constrain boids to this object's surface.");
+ /* keyed */
prop= RNA_def_property(srna, "keyed_object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "keyed_ob");
RNA_def_property_ui_text(prop, "Keyed Object", "For keyed physics systems, the object that has the target particle system.");
@@ -1231,18 +1232,129 @@ static void rna_def_particlesystem(BlenderRNA *brna)
RNA_def_property_range(prop, 1, INT_MAX);
RNA_def_property_ui_text(prop, "Keyed Particle System", "For keyed physics systems, index of particle system on the keyed object.");
- prop= RNA_def_property(srna, "seed", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_ui_text(prop, "Seed", "Offset in the random number table, to get a different randomized result.");
+ prop= RNA_def_property(srna, "keyed_first", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_FIRST_KEYED);
+ RNA_def_property_ui_text(prop, "Keyed First", "Set the system to be the starting point of keyed particles");
+
+ prop= RNA_def_property(srna, "keyed_timed", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", PSYS_KEYED_TIME);
+ RNA_def_property_ui_text(prop, "Keyed Timed", "Use intermediate key times for keyed particles (setting for starting point only).");
+
+
+ /* billboard */
+ prop= RNA_def_property(srna, "billboard_normal_uv", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "bb_uvname[0]");
+ RNA_def_property_string_maxlength(prop, 32);
+ RNA_def_property_ui_text(prop, "Billboard Normal UV", "UV Layer to control billboard normals.");
+
+ prop= RNA_def_property(srna, "billboard_time_index_uv", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "bb_uvname[1]");
+ RNA_def_property_string_maxlength(prop, 32);
+ RNA_def_property_ui_text(prop, "Billboard Time Index UV", "UV Layer to control billboard time index (X-Y).");
+
+ prop= RNA_def_property(srna, "billboard_split_uv", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "bb_uvname[2]");
+ RNA_def_property_string_maxlength(prop, 32);
+ RNA_def_property_ui_text(prop, "Billboard Split UV", "UV Layer to control billboard splitting.");
+
+ /* vertex groups */
+ prop= RNA_def_property(srna, "vertex_group_density", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[0]");
+ RNA_def_property_ui_text(prop, "Vertex Group Density", "Vertex group to control density.");
+
+ prop= RNA_def_property(srna, "vertex_group_density_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_DENSITY));
+ RNA_def_property_ui_text(prop, "Vertex Group Density Negate", "Negate the effect of the density vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_velocity", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[1]");
+ RNA_def_property_ui_text(prop, "Vertex Group Velocity", "Vertex group to control velocity.");
+
+ prop= RNA_def_property(srna, "vertex_group_velocity_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_VEL));
+ RNA_def_property_ui_text(prop, "Vertex Group Velocity Negate", "Negate the effect of the velocity vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_length", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[2]");
+ RNA_def_property_ui_text(prop, "Vertex Group Length", "Vertex group to control length.");
+
+ prop= RNA_def_property(srna, "vertex_group_length_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_LENGTH));
+ RNA_def_property_ui_text(prop, "Vertex Group Length Negate", "Negate the effect of the length vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_clump", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[3]");
+ RNA_def_property_ui_text(prop, "Vertex Group Clump", "Vertex group to control clump.");
+
+ prop= RNA_def_property(srna, "vertex_group_clump_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_CLUMP));
+ RNA_def_property_ui_text(prop, "Vertex Group Clump Negate", "Negate the effect of the clump vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_kink", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[4]");
+ RNA_def_property_ui_text(prop, "Vertex Group Kink", "Vertex group to control kink.");
+
+ prop= RNA_def_property(srna, "vertex_group_kink_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_KINK));
+ RNA_def_property_ui_text(prop, "Vertex Group Kink Negate", "Negate the effect of the kink vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_roughness1", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[5]");
+ RNA_def_property_ui_text(prop, "Vertex Group Roughness 1", "Vertex group to control roughness 1.");
+
+ prop= RNA_def_property(srna, "vertex_group_roughness1_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_ROUGH1));
+ RNA_def_property_ui_text(prop, "Vertex Group Roughness 1 Negate", "Negate the effect of the roughness 1 vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_roughness2", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[6]");
+ RNA_def_property_ui_text(prop, "Vertex Group Roughness 2", "Vertex group to control roughness 2.");
+
+ prop= RNA_def_property(srna, "vertex_group_roughness2_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_ROUGH2));
+ RNA_def_property_ui_text(prop, "Vertex Group Roughness 2 Negate", "Negate the effect of the roughness 2 vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_roughness_end", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[7]");
+ RNA_def_property_ui_text(prop, "Vertex Group Roughness End", "Vertex group to control roughness end.");
+
+ prop= RNA_def_property(srna, "vertex_group_roughness_end_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_ROUGHE));
+ RNA_def_property_ui_text(prop, "Vertex Group Roughness End Negate", "Negate the effect of the roughness end vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_size", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[8]");
+ RNA_def_property_ui_text(prop, "Vertex Group Size", "Vertex group to control size.");
+
+ prop= RNA_def_property(srna, "vertex_group_size_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_SIZE));
+ RNA_def_property_ui_text(prop, "Vertex Group Size Negate", "Negate the effect of the size vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_tangent", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[9]");
+ RNA_def_property_ui_text(prop, "Vertex Group Tangent", "Vertex group to control tangent.");
+
+ prop= RNA_def_property(srna, "vertex_group_tangent_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_TAN));
+ RNA_def_property_ui_text(prop, "Vertex Group Tangent Negate", "Negate the effect of the tangent vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_rotation", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[10]");
+ RNA_def_property_ui_text(prop, "Vertex Group Rotation", "Vertex group to control rotation.");
+
+ prop= RNA_def_property(srna, "vertex_group_rotation_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_ROT));
+ RNA_def_property_ui_text(prop, "Vertex Group Rotation Negate", "Negate the effect of the rotation vertex group.");
+
+ prop= RNA_def_property(srna, "vertex_group_field", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "vgroup[11]");
+ RNA_def_property_ui_text(prop, "Vertex Group Field", "Vertex group to control field.");
- // int seed;
- // int flag, rt;
- // short recalc, totkeyed, softflag, bakespace;
- //
- // char bb_uvname[3][32]; /* billboard uv name */
- //
- // /* if you change these remember to update array lengths to PSYS_TOT_VG! */
- // short vgroup[12], vg_neg, rt3; /* vertex groups */
+ prop= RNA_def_property(srna, "vertex_group_field_negate", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "vg_neg", (1 << PSYS_VG_EFFECTOR));
+ RNA_def_property_ui_text(prop, "Vertex Group Field Negate", "Negate the effect of the field vertex group.");
+ /* pointcache */
prop= RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "pointcache");
RNA_def_property_struct_type(prop, "PointCache");
@@ -1251,12 +1363,12 @@ static void rna_def_particlesystem(BlenderRNA *brna)
void RNA_def_particle(BlenderRNA *brna)
{
- rna_def_hair_key(brna);
+ rna_def_particle_hair_key(brna);
rna_def_particle_key(brna);
rna_def_child_particle(brna);
- rna_def_particle_data(brna);
- rna_def_particlesystem(brna);
- rna_def_particlesettings(brna);
+ rna_def_particle(brna);
+ rna_def_particle_system(brna);
+ rna_def_particle_settings(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index dbaf4279884..f7964ba52ef 100755..100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -73,7 +73,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Constraints", "Constraints that act on this PoseChannel.");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_struct_name_property(srna, prop);
@@ -112,27 +112,27 @@ static void rna_def_pose_channel(BlenderRNA *brna)
prop= RNA_def_property(srna, "path_start_frame", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pathsf");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Bone Paths Calculation Start Frame", "Starting frame of range of frames to use for Bone Path calculations.");
prop= RNA_def_property(srna, "path_end_frame", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pathef");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Bone Paths Calculation End Frame", "End frame of range of frames to use for Bone Path calculations.");
prop= RNA_def_property(srna, "bone", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_struct_type(prop, "Bone");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Bone", "Bone associated with this Pose Channel.");
prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "PoseChannel");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Parent", "Parent of this pose channel.");
prop= RNA_def_property(srna, "child", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "PoseChannel");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Child", "Child of this pose channel.");
prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_VECTOR);
@@ -164,26 +164,26 @@ static void rna_def_pose_channel(BlenderRNA *brna)
/* These three matrix properties await an implementation of the PROP_MATRIX subtype, which currently doesn't exist. */
/* prop= RNA_def_property(srna, "channel_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_struct_type(prop, "chan_mat");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Channel Matrix", "4x4 matrix, before constraints.");*/
/* kaito says this should be not user-editable; I disagree; power users should be able to force this in python; he's the boss. */
/* prop= RNA_def_property(srna, "pose_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_struct_type(prop, "pose_mat");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Pose Matrix", "Final 4x4 matrix for this channel.");
prop= RNA_def_property(srna, "constraint_inverse_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_struct_type(prop, "constinv");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Constraint Inverse Matrix", "4x4 matrix, defines transform from final position to unconstrained position."); */
prop= RNA_def_property(srna, "pose_head", PROP_FLOAT, PROP_VECTOR);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Pose Head Position", "Location of head of the channel's bone.");
prop= RNA_def_property(srna, "pose_tail", PROP_FLOAT, PROP_VECTOR);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Pose Tail Position", "Location of tail of the channel's bone.");
prop= RNA_def_property(srna, "ik_min_limits", PROP_FLOAT, PROP_VECTOR);
diff --git a/source/blender/makesrna/intern/rna_property.c b/source/blender/makesrna/intern/rna_property.c
index 21d8958b665..c38b6342942 100644
--- a/source/blender/makesrna/intern/rna_property.c
+++ b/source/blender/makesrna/intern/rna_property.c
@@ -89,12 +89,12 @@ void RNA_def_gameproperty(BlenderRNA *brna)
RNA_def_struct_refine_func(srna, "rna_GameProperty_refine");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* must be unique */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* must be unique */
RNA_def_property_ui_text(prop, "Name", "Available as as GameObject attributes in the game engines python api");
RNA_def_struct_name_property(srna, prop);
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, gameproperty_type_items);
RNA_def_property_ui_text(prop, "Type", "");
diff --git a/source/blender/makesrna/intern/rna_radio.c b/source/blender/makesrna/intern/rna_radio.c
index 2668a17f979..54dbd59b52d 100644
--- a/source/blender/makesrna/intern/rna_radio.c
+++ b/source/blender/makesrna/intern/rna_radio.c
@@ -104,7 +104,7 @@ void RNA_def_radio(BlenderRNA *brna)
prop= RNA_def_property(srna, "subshoot_patch", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "subshootp");
RNA_def_property_range(prop, 0, 10);
- RNA_def_property_ui_text(prop, "SubShoot Patch", "Sets the number of times the environment is tested to detect pathes.");
+ RNA_def_property_ui_text(prop, "SubShoot Patch", "Sets the number of times the environment is tested to detect paths.");
prop= RNA_def_property(srna, "subshoot_element", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "subshoote");
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 4b9c1e0067b..f2e3f27edad 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -199,14 +199,10 @@ void rna_builtin_properties_begin(CollectionPropertyIterator *iter, PointerRNA *
newptr.type= &RNA_Struct;
newptr.data= ptr->type;
- if(ptr->type->flag & STRUCT_ID) {
- newptr.id.type= ptr->type;
+ if(ptr->type->flag & STRUCT_ID)
newptr.id.data= ptr->data;
- }
- else {
- newptr.id.type= NULL;
+ else
newptr.id.data= NULL;
- }
iter->parent= newptr;
@@ -441,14 +437,14 @@ static PointerRNA rna_PointerProperty_fixed_type_get(PointerRNA *ptr)
{
PropertyRNA *prop= (PropertyRNA*)ptr->data;
rna_idproperty_check(&prop, ptr);
- return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((PointerPropertyRNA*)prop)->structtype);
+ return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((PointerPropertyRNA*)prop)->type);
}
static PointerRNA rna_CollectionProperty_fixed_type_get(PointerRNA *ptr)
{
PropertyRNA *prop= (PropertyRNA*)ptr->data;
rna_idproperty_check(&prop, ptr);
- return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((CollectionPropertyRNA*)prop)->structtype);
+ return rna_pointer_inherit_refine(ptr, &RNA_Struct, ((CollectionPropertyRNA*)prop)->type);
}
/* Blender RNA */
@@ -469,41 +465,41 @@ static void rna_def_struct(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Struct Definition", "RNA structure definition");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Struct_name_get", "rna_Struct_name_length", NULL);
RNA_def_property_ui_text(prop, "Name", "Human readable name.");
prop= RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Struct_identifier_get", "rna_Struct_identifier_length", NULL);
RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting.");
RNA_def_struct_name_property(srna, prop);
prop= RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Struct_description_get", "rna_Struct_description_length", NULL);
RNA_def_property_ui_text(prop, "Description", "Description of the Struct's purpose.");
prop= RNA_def_property(srna, "base", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Struct");
RNA_def_property_pointer_funcs(prop, "rna_Struct_base_get", NULL);
RNA_def_property_ui_text(prop, "Base", "Struct definition this is derived from.");
prop= RNA_def_property(srna, "nested", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Struct");
RNA_def_property_pointer_funcs(prop, "rna_Struct_nested_get", NULL);
RNA_def_property_ui_text(prop, "Nested", "Struct in which this struct is always nested, and to which it logically belongs.");
prop= RNA_def_property(srna, "name_property", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "StringProperty");
RNA_def_property_pointer_funcs(prop, "rna_Struct_name_property_get", NULL);
RNA_def_property_ui_text(prop, "Name Property", "Property that gives the name of the struct.");
prop= RNA_def_property(srna, "properties", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Property");
RNA_def_property_collection_funcs(prop, "rna_Struct_properties_begin", "rna_Struct_properties_next", "rna_iterator_listbase_end", "rna_Struct_properties_get", 0, 0, 0);
RNA_def_property_ui_text(prop, "Properties", "Properties in the struct.");
@@ -540,35 +536,35 @@ static void rna_def_property(BlenderRNA *brna)
RNA_def_struct_refine_func(srna, "rna_Property_refine");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Property_name_get", "rna_Property_name_length", NULL);
RNA_def_property_ui_text(prop, "Name", "Human readable name.");
prop= RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Property_identifier_get", "rna_Property_identifier_length", NULL);
RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting.");
RNA_def_struct_name_property(srna, prop);
prop= RNA_def_property(srna, "description", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Property_description_get", "rna_Property_description_length", NULL);
RNA_def_property_ui_text(prop, "Description", "Description of the property for tooltips.");
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_enum_funcs(prop, "rna_Property_type_get", NULL);
RNA_def_property_ui_text(prop, "Type", "Data type of the property.");
prop= RNA_def_property(srna, "subtype", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, subtype_items);
RNA_def_property_enum_funcs(prop, "rna_Property_subtype_get", NULL);
RNA_def_property_ui_text(prop, "Subtype", "Semantic interpretation of the property.");
prop= RNA_def_property(srna, "editable", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Property_editable_get", NULL);
RNA_def_property_ui_text(prop, "Editable", "Property is editable through RNA.");
}
@@ -578,7 +574,7 @@ static void rna_def_number_property(StructRNA *srna, PropertyType type)
PropertyRNA *prop;
prop= RNA_def_property(srna, "array_length", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_Property_array_length_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Array Length", "Maximum length of the array, 0 means unlimited.");
@@ -586,38 +582,38 @@ static void rna_def_number_property(StructRNA *srna, PropertyType type)
return;
prop= RNA_def_property(srna, "hard_min", type, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
if(type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_hard_min_get", NULL, NULL);
else RNA_def_property_float_funcs(prop, "rna_FloatProperty_hard_min_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Hard Minimum", "Minimum value used by buttons.");
prop= RNA_def_property(srna, "hard_max", type, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
if(type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_hard_max_get", NULL, NULL);
else RNA_def_property_float_funcs(prop, "rna_FloatProperty_hard_max_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Hard Maximum", "Maximum value used by buttons.");
prop= RNA_def_property(srna, "soft_min", type, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
if(type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_soft_min_get", NULL, NULL);
else RNA_def_property_float_funcs(prop, "rna_FloatProperty_soft_min_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Soft Minimum", "Minimum value used by buttons.");
prop= RNA_def_property(srna, "soft_max", type, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
if(type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_soft_max_get", NULL, NULL);
else RNA_def_property_float_funcs(prop, "rna_FloatProperty_soft_max_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Soft Maximum", "Maximum value used by buttons.");
prop= RNA_def_property(srna, "step", type, PROP_UNSIGNED);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
if(type == PROP_INT) RNA_def_property_int_funcs(prop, "rna_IntProperty_step_get", NULL, NULL);
else RNA_def_property_float_funcs(prop, "rna_FloatProperty_step_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Step", "Step size used by number buttons, for floats 1/100th of the step size.");
if(type == PROP_FLOAT) {
prop= RNA_def_property(srna, "precision", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_FloatProperty_precision_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Precision", "Number of digits after the dot used by buttons.");
}
@@ -628,7 +624,7 @@ static void rna_def_string_property(StructRNA *srna)
PropertyRNA *prop;
prop= RNA_def_property(srna, "max_length", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_StringProperty_max_length_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Maximum Length", "Maximum length of the string, 0 means unlimited.");
}
@@ -638,7 +634,7 @@ static void rna_def_enum_property(BlenderRNA *brna, StructRNA *srna)
PropertyRNA *prop;
prop= RNA_def_property(srna, "items", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "EnumPropertyItem");
RNA_def_property_collection_funcs(prop, "rna_EnumProperty_items_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", 0, 0, 0);
RNA_def_property_ui_text(prop, "Items", "Possible values for the property.");
@@ -647,18 +643,18 @@ static void rna_def_enum_property(BlenderRNA *brna, StructRNA *srna)
RNA_def_struct_ui_text(srna, "Enum Item Definition", "Definition of a choice in an RNA enum property.");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_EnumPropertyItem_name_get", "rna_EnumPropertyItem_name_length", NULL);
RNA_def_property_ui_text(prop, "Name", "Human readable name.");
prop= RNA_def_property(srna, "identifier", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_EnumPropertyItem_identifier_get", "rna_EnumPropertyItem_identifier_length", NULL);
RNA_def_property_ui_text(prop, "Identifier", "Unique name used in the code and scripting.");
RNA_def_struct_name_property(srna, prop);
prop= RNA_def_property(srna, "value", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_EnumPropertyItem_value_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Value", "Value of the item.");
}
@@ -668,7 +664,7 @@ static void rna_def_pointer_property(StructRNA *srna, PropertyType type)
PropertyRNA *prop;
prop= RNA_def_property(srna, "fixed_type", PROP_POINTER, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Struct");
if(type == PROP_POINTER)
RNA_def_property_pointer_funcs(prop, "rna_PointerProperty_fixed_type_get", NULL);
@@ -728,7 +724,7 @@ void RNA_def_rna(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Blender RNA", "Blender RNA structure definitions.");
prop= RNA_def_property(srna, "structs", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "Struct");
RNA_def_property_collection_funcs(prop, "rna_BlenderRNA_structs_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0);
RNA_def_property_ui_text(prop, "Structs", "");
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 281ab5b097b..6e4fd39d039 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -33,6 +33,17 @@
#include "WM_types.h"
+/* prop_mode needs to be accessible from transform operator */
+EnumPropertyItem prop_mode_items[] ={
+ {PROP_SMOOTH, "SMOOTH", "Smooth", ""},
+ {PROP_SPHERE, "SPHERE", "Sphere", ""},
+ {PROP_ROOT, "ROOT", "Root", ""},
+ {PROP_SHARP, "SHARP", "Sharp", ""},
+ {PROP_LIN, "LINEAR", "Linear", ""},
+ {PROP_CONST, "CONSTANT", "Constant", ""},
+ {PROP_RANDOM, "RANDOM", "Random", ""},
+ {0, NULL, NULL, NULL}};
+
#ifdef RNA_RUNTIME
#include "BKE_context.h"
@@ -211,9 +222,9 @@ void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the rendered image.");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
- prop= RNA_def_property(srna, "resolution_percentage", PROP_INT, PROP_NONE);
+ prop= RNA_def_property(srna, "resolution_percentage", PROP_INT, PROP_PERCENTAGE);
RNA_def_property_int_sdna(prop, NULL, "size");
- RNA_def_property_range(prop, 1, 400);
+ RNA_def_property_ui_range(prop, 1, 100, 10, 1);
RNA_def_property_ui_text(prop, "Resolution %", "Preview scale for render resolution");
prop= RNA_def_property(srna, "parts_x", PROP_INT, PROP_NONE);
@@ -311,6 +322,11 @@ void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Render Radiosity", "Calculate radiosity in a pre-process before rendering.");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+ prop= RNA_def_property(srna, "render_sss", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SSS);
+ RNA_def_property_ui_text(prop, "Render SSS", "Calculate sub-surface scattering in materials rendering.");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
prop= RNA_def_property(srna, "render_raytracing", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_RAYTRACE);
RNA_def_property_ui_text(prop, "Render Raytracing", "Pre-calculate the raytrace accelerator and render raytracing effects.");
@@ -354,21 +370,57 @@ void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_enum_items(prop, threads_mode_items);
RNA_def_property_ui_text(prop, "Threads Mode", "");
+ prop= RNA_def_property(srna, "motion_blur", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", R_MBLUR);
+ RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled 3D scene motion blur (uses number of anti-aliasing samples).");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "border", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", R_BORDER);
+ RNA_def_property_ui_text(prop, "Border", "Render a user-defined border region, within the frame size.");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "crop_to_border", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", R_CROP);
+ RNA_def_property_ui_text(prop, "Crop to Border", "Crop the rendered frame to the defined border size.");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "placeholders", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", R_TOUCH);
+ RNA_def_property_ui_text(prop, "Placeholders", "Create empty placeholder files while rendering frames (similar to Unix 'touch').");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "no_overwrite", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", R_NO_OVERWRITE);
+ RNA_def_property_ui_text(prop, "No Overwrite", "Skip and don't overwrite existing files while rendering");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "do_composite", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_DOCOMP);
+ RNA_def_property_ui_text(prop, "Do Composite", "Process the render result through the compositing pipeline");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "do_sequence", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_DOSEQ);
+ RNA_def_property_ui_text(prop, "Do Sequence", "Process the render (and composited) result through the video sequence editor pipeline");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "file_extensions", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_EXTENSION);
+ RNA_def_property_ui_text(prop, "File Extensions", "Add the file format extensions to the rendered file name (eg: filename + .jpg)");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
+ prop= RNA_def_property(srna, "free_image_textures", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "scemode", R_FREE_IMAGE);
+ RNA_def_property_ui_text(prop, "Free Image Textures", "Free all image texture from memory after render, to save memory before compositing.");
+ RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
+
}
void RNA_def_scene(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem prop_mode_items[] ={
- {PROP_SMOOTH, "SMOOTH", "Smooth", ""},
- {PROP_SPHERE, "SPHERE", "Sphere", ""},
- {PROP_ROOT, "ROOT", "Root", ""},
- {PROP_SHARP, "SHARP", "Sharp", ""},
- {PROP_LIN, "LINEAR", "Linear", ""},
- {PROP_CONST, "CONSTANT", "Constant", ""},
- {PROP_RANDOM, "RANDOM", "Random", ""},
- {0, NULL, NULL, NULL}};
static EnumPropertyItem unwrapper_items[] = {
{0, "CONFORMAL", "Conformal", ""},
{1, "ANGLEBASED", "Angle Based", ""},
@@ -403,28 +455,28 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
prop= RNA_def_property(srna, "current_frame", PROP_INT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_ANIMATEABLE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
RNA_def_property_int_sdna(prop, NULL, "r.cfra");
RNA_def_property_range(prop, MINFRAME, MAXFRAME);
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, NC_SCENE|ND_FRAME, "rna_Scene_frame_update");
prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_ANIMATEABLE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
RNA_def_property_int_sdna(prop, NULL, "r.sfra");
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_start_frame_set", NULL);
RNA_def_property_ui_text(prop, "Start Frame", "");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "end_frame", PROP_INT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_ANIMATEABLE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
RNA_def_property_int_sdna(prop, NULL, "r.efra");
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_end_frame_set", NULL);
RNA_def_property_ui_text(prop, "End Frame", "");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "frame_step", PROP_INT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_ANIMATEABLE);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATEABLE);
RNA_def_property_int_sdna(prop, NULL, "frame_step");
RNA_def_property_ui_text(prop, "Frame Step", "Number of frames to skip forward while rendering/playing back each frame");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
@@ -457,7 +509,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Keying Sets", "Keying Sets for this Scene.");
prop= RNA_def_property(srna, "active_keyingset", PROP_INT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Active Keying Set", "Current Keying Set index.");
prop= RNA_def_property(srna, "tool_settings", PROP_POINTER, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c
index b8a1a1ade78..90a0972fa03 100644
--- a/source/blender/makesrna/intern/rna_sensor.c
+++ b/source/blender/makesrna/intern/rna_sensor.c
@@ -105,7 +105,7 @@ void rna_def_sensor(BlenderRNA *brna)
/* type is not editable, would need to do proper data free/alloc */
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, sensor_type_items);
RNA_def_property_ui_text(prop, "Type", "");
@@ -210,18 +210,18 @@ void rna_def_keyboard_sensor(BlenderRNA *brna)
RNA_def_struct_sdna_from(srna, "bKeyboardSensor", "data");
prop= RNA_def_property(srna, "key", PROP_INT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* need better range or enum check */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* need better range or enum check */
RNA_def_property_ui_text(prop, "Key", "Input key code.");
RNA_def_property_range(prop, 0, 255);
prop= RNA_def_property(srna, "modifier_key", PROP_INT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* need better range or enum check */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* need better range or enum check */
RNA_def_property_int_sdna(prop, NULL, "qual");
RNA_def_property_ui_text(prop, "Modifier Key", "Modifier key code.");
RNA_def_property_range(prop, 0, 255);
prop= RNA_def_property(srna, "second_modifier_key", PROP_INT, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); /* need better range or enum check */
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* need better range or enum check */
RNA_def_property_int_sdna(prop, NULL, "qual2");
RNA_def_property_ui_text(prop, "Second Modifier Key", "Modifier key code.");
RNA_def_property_range(prop, 0, 255);
@@ -407,7 +407,7 @@ void rna_def_ray_sensor(BlenderRNA *brna)
{0, NULL, NULL, NULL}};
srna= RNA_def_struct(brna, "RaySensor", "Sensor");
- RNA_def_struct_ui_text(srna, "Ray Sensor", "Sensor to detect interestions with a ray emanating from the current object.");
+ RNA_def_struct_ui_text(srna, "Ray Sensor", "Sensor to detect intersections with a ray emanating from the current object.");
RNA_def_struct_sdna_from(srna, "bRaySensor", "data");
prop= RNA_def_property(srna, "property", PROP_STRING, PROP_NONE);
@@ -495,7 +495,7 @@ void rna_def_joystick_sensor(BlenderRNA *brna)
/* Axis */
prop= RNA_def_property(srna, "axis_number", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "axis");
- RNA_def_property_ui_text(prop, "Axis Number", "Specify which axis pair to use, 1 is useually the main direction input.");
+ RNA_def_property_ui_text(prop, "Axis Number", "Specify which axis pair to use, 1 is usually the main direction input.");
RNA_def_property_range(prop, 1, 2);
prop= RNA_def_property(srna, "axis_threshold", PROP_INT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_sequence.c b/source/blender/makesrna/intern/rna_sequence.c
index 18af7913456..302e7623b18 100644
--- a/source/blender/makesrna/intern/rna_sequence.c
+++ b/source/blender/makesrna/intern/rna_sequence.c
@@ -283,7 +283,7 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, seq_type_items);
RNA_def_property_ui_text(prop, "Type", "");
@@ -320,39 +320,39 @@ static void rna_def_sequence(BlenderRNA *brna)
prop= RNA_def_property(srna, "length", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "len");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // computed from other values
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // computed from other values
RNA_def_property_ui_text(prop, "Length", "The length of the contents of this strip before the handles are applied");
prop= RNA_def_property(srna, "start_frame", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "start");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // overlap tests
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // overlap tests
RNA_def_property_ui_text(prop, "Start Frame", "");
prop= RNA_def_property(srna, "start_offset", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "startofs");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // overlap tests
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // overlap tests
RNA_def_property_ui_text(prop, "Start Offset", "");
prop= RNA_def_property(srna, "end_offset", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "endofs");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // overlap tests
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // overlap tests
RNA_def_property_ui_text(prop, "End offset", "");
prop= RNA_def_property(srna, "start_still", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "startstill");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // overlap tests
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // overlap tests
RNA_def_property_range(prop, 0, MAXFRAME);
RNA_def_property_ui_text(prop, "Start Still", "");
prop= RNA_def_property(srna, "end_still", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "endstill");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // overlap tests
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // overlap tests
RNA_def_property_range(prop, 0, MAXFRAME);
RNA_def_property_ui_text(prop, "End Still", "");
prop= RNA_def_property(srna, "channel", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "machine");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // overlap test
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // overlap test
RNA_def_property_ui_text(prop, "Channel", "Y position of the sequence strip.");
/* blending */
@@ -426,7 +426,7 @@ static void rna_def_filter_video(StructRNA *srna)
prop= RNA_def_property(srna, "use_color_balance", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_USE_COLOR_BALANCE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // allocate color balance
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // allocate color balance
RNA_def_property_ui_text(prop, "Use Color Balance", "(3-Way color correction) on input.");
prop= RNA_def_property(srna, "color_balance", PROP_POINTER, PROP_NONE);
@@ -435,7 +435,7 @@ static void rna_def_filter_video(StructRNA *srna)
prop= RNA_def_property(srna, "use_translation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_USE_TRANSFORM);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // allocate transform
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // allocate transform
RNA_def_property_ui_text(prop, "Use Translation", "Translate image before processing.");
prop= RNA_def_property(srna, "transform", PROP_POINTER, PROP_NONE);
@@ -444,7 +444,7 @@ static void rna_def_filter_video(StructRNA *srna)
prop= RNA_def_property(srna, "use_crop", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_USE_CROP);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // allocate crop
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // allocate crop
RNA_def_property_ui_text(prop, "Use Crop", "Crop image before processing.");
prop= RNA_def_property(srna, "crop", PROP_POINTER, PROP_NONE);
@@ -473,7 +473,7 @@ static void rna_def_proxy(StructRNA *srna)
prop= RNA_def_property(srna, "use_proxy", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_USE_PROXY);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // allocate proxy
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // allocate proxy
RNA_def_property_ui_text(prop, "Use Proxy", "Use a preview proxy for this strip.");
prop= RNA_def_property(srna, "proxy", PROP_POINTER, PROP_NONE);
@@ -491,12 +491,12 @@ static void rna_def_input(StructRNA *srna)
prop= RNA_def_property(srna, "animation_start_offset", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "anim_startofs");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // overlap test
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // overlap test
RNA_def_property_ui_text(prop, "Animation Start Offset", "Animation start offset (trim start).");
prop= RNA_def_property(srna, "animation_end_offset", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "anim_endofs");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE); // overlap test
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); // overlap test
RNA_def_property_ui_text(prop, "Animation End Offset", "Animation end offset (trim end).");
}
@@ -634,7 +634,7 @@ static void rna_def_plugin(BlenderRNA *brna)
prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "name");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Filename", "");
/* plugin properties need custom wrapping code like ID properties */
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index c889a0ec195..5184e904927 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -49,7 +49,7 @@ static StructRNA* rna_Space_refine(struct PointerRNA *ptr)
return &RNA_SpaceView3D;
case SPACE_IPO:
return &RNA_SpaceGraphEditor;
- case SPACE_OOPS:
+ case SPACE_OUTLINER:
return &RNA_SpaceOutliner;
case SPACE_BUTS:
return &RNA_SpaceButtonsWindow;
@@ -103,6 +103,14 @@ void rna_SpaceTextEditor_word_wrap_set(PointerRNA *ptr, int value)
st->left= 0;
}
+void rna_SpaceTextEditor_text_set(PointerRNA *ptr, PointerRNA value)
+{
+ SpaceText *st= (SpaceText*)(ptr->data);
+
+ st->text= value.data;
+ st->top= 0;
+}
+
#else
static void rna_def_space(BlenderRNA *brna)
@@ -114,7 +122,7 @@ static void rna_def_space(BlenderRNA *brna)
{SPACE_EMPTY, "EMPTY", "Empty", ""},
{SPACE_VIEW3D, "VIEW_3D", "3D View", ""},
{SPACE_IPO, "GRAPH_EDITOR", "Graph Editor", ""},
- {SPACE_OOPS, "OUTLINER", "Outliner", ""},
+ {SPACE_OUTLINER, "OUTLINER", "Outliner", ""},
{SPACE_BUTS, "BUTTONS_WINDOW", "Buttons Window", ""},
{SPACE_FILE, "FILE_BROWSER", "File Browser", ""},
{SPACE_IMAGE, "IMAGE_EDITOR", "Image Editor", ""},
@@ -138,7 +146,7 @@ static void rna_def_space(BlenderRNA *brna)
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "spacetype");
RNA_def_property_enum_items(prop, type_items);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Type", "Space data type.");
}
@@ -218,9 +226,9 @@ static void rna_def_space_image_uv(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_LOCAL_UV);
RNA_def_property_ui_text(prop, "Local View", "Draw only faces with the currently displayed image assigned.");*/
- prop= RNA_def_property(srna, "display_normalized_coordinates", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "normalized_coordinates", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_COORDFLOATS);
- RNA_def_property_ui_text(prop, "Display Normalized Coordinates", "Display UV coordinates from 0.0 to 1.0 rather than in pixels.");
+ RNA_def_property_ui_text(prop, "Normalized Coordinates", "Display UV coordinates from 0.0 to 1.0 rather than in pixels.");
/* todo: move edge and face drawing options here from G.f */
@@ -330,7 +338,10 @@ static void rna_def_space_text(BlenderRNA *brna)
/* text */
prop= RNA_def_property(srna, "text", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Text", "Text displayed and edited in this space.");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_SpaceTextEditor_text_set");
+ RNA_def_property_update(prop, NC_TEXT|ND_CURSOR, NULL);
/* display */
prop= RNA_def_property(srna, "syntax_highlight", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c
index 80b9e56eff5..838822119e8 100644
--- a/source/blender/makesrna/intern/rna_text.c
+++ b/source/blender/makesrna/intern/rna_text.c
@@ -36,6 +36,8 @@
#include "DNA_text_types.h"
+#include "WM_types.h"
+
#ifdef RNA_RUNTIME
static void rna_Text_filename_get(PointerRNA *ptr, char *value)
@@ -83,7 +85,6 @@ static int rna_TextLine_line_length(PointerRNA *ptr)
return line->len;
}
-#if 0
static void rna_TextLine_line_set(PointerRNA *ptr, const char *value)
{
TextLine *line= (TextLine*)ptr->data;
@@ -91,16 +92,14 @@ static void rna_TextLine_line_set(PointerRNA *ptr, const char *value)
if(line->line)
MEM_freeN(line->line);
- if(strlen(value)) {
- line->line= BLI_strdup(value);
- line->len= strlen(line->line);
- }
- else {
- line->line= NULL;
- line->len= 0;
+ line->line= BLI_strdup(value);
+ line->len= strlen(line->line);
+
+ if(line->format) {
+ MEM_freeN(line->format);
+ line->format= NULL;
}
}
-#endif
#else
@@ -113,9 +112,9 @@ static void rna_def_text_line(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Text Line", "Line of text in a Text datablock.");
prop= RNA_def_property(srna, "line", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_TextLine_line_get", "rna_TextLine_line_length", "rna_TextLine_line_set");
RNA_def_property_ui_text(prop, "Line", "Text in the line.");
+ RNA_def_property_update(prop, NC_TEXT|NA_EDITED, NULL);
}
static void rna_def_text_marker(BlenderRNA *brna)
@@ -128,30 +127,30 @@ static void rna_def_text_marker(BlenderRNA *brna)
prop= RNA_def_property(srna, "line", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "lineno");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Line", "Line in which the marker is located.");
prop= RNA_def_property(srna, "start", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Start", "Start position of the marker in the line.");
prop= RNA_def_property(srna, "end", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "End", "Start position of the marker in the line.");
prop= RNA_def_property(srna, "group", PROP_INT, PROP_UNSIGNED);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_range(prop, 0, (int)0xFFFF);
RNA_def_property_ui_text(prop, "Group", "");
prop= RNA_def_property(srna, "temporary", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", TMARK_TEMP);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Temporary", "Marker is temporary.");
prop= RNA_def_property(srna, "edit_all", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", TMARK_EDITALL);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Edit All", "Edit all markers of the same group as one.");
prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
@@ -172,12 +171,12 @@ static void rna_def_text(BlenderRNA *brna)
prop= RNA_def_property(srna, "dirty", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", TXT_ISDIRTY);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Dirty", "Text file has been edited since last save.");
prop= RNA_def_property(srna, "memory", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", TXT_ISMEM);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Memory", "Text file is in memory, without a corresponding file on disk.");
prop= RNA_def_property(srna, "lines", PROP_COLLECTION, PROP_NONE);
@@ -186,24 +185,24 @@ static void rna_def_text(BlenderRNA *brna)
prop= RNA_def_property(srna, "current_line", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "curl");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "TextLine");
RNA_def_property_ui_text(prop, "Current Line", "Current line, and start line of selection if one exists.");
prop= RNA_def_property(srna, "current_character", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "curc");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Current Character", "Index of current character in current line, and also start index of character in selection if one exists.");
prop= RNA_def_property(srna, "selection_end_line", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "sell");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "TextLine");
RNA_def_property_ui_text(prop, "Selection End Line", "End line of selection.");
prop= RNA_def_property(srna, "selection_end_character", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "selc");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Selection End Character", "Index of character after end of selection in the selection end line.");
prop= RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 8a001168302..e8fd753d16a 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -35,6 +35,42 @@
#ifdef RNA_RUNTIME
+StructRNA *rna_Texture_refine(struct PointerRNA *ptr)
+{
+ Tex *tex= (Tex*)ptr->data;
+
+ switch(tex->type) {
+ case TEX_CLOUDS:
+ return &RNA_CloudsTexture;
+ case TEX_WOOD:
+ return &RNA_WoodTexture;
+ case TEX_MARBLE:
+ return &RNA_MarbleTexture;
+ case TEX_MAGIC:
+ return &RNA_MagicTexture;
+ /*case TEX_BLEND:
+ return &RNA_BlendTexture; */
+ case TEX_STUCCI:
+ return &RNA_StucciTexture;
+ /*case TEX_NOISE:
+ return &RNA_NoiseTexture;
+ case TEX_IMAGE:
+ return &RNA_ImageTexture;
+ case TEX_PLUGIN:
+ return &RNA_PluginTexture;
+ case TEX_ENVMAP:
+ return &RNA_EnvironmentMapTexture;
+ case TEX_MUSGRAVE:
+ return &RNA_MusgraveTexture;
+ case TEX_VORONOI:
+ return &RNA_VoronoiTexture;
+ case TEX_DISTNOISE:
+ return &RNA_DistortedNoiseTexture; */
+ default:
+ return &RNA_Texture;
+ }
+}
+
#else
static void rna_def_color_ramp_element(BlenderRNA *brna)
@@ -55,8 +91,6 @@ static void rna_def_color_ramp_element(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "pos");
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Position", "");
-
- /* XXX: CBData.cur? */
}
static void rna_def_color_ramp(BlenderRNA *brna)
@@ -81,14 +115,49 @@ static void rna_def_color_ramp(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "ColorRampElement");
RNA_def_property_ui_text(prop, "Elements", "");
- /* XXX: CBData.flag, tot, cur ? */
-
prop= RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "ipotype");
RNA_def_property_enum_items(prop, prop_interpolation_items);
RNA_def_property_ui_text(prop, "Interpolation", "");
}
+static void rna_def_texmapping(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "TexMapping", NULL);
+ RNA_def_struct_ui_text(srna, "Texture Mapping", "Mapping settings");
+
+ prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_VECTOR);
+ RNA_def_property_float_sdna(prop, NULL, "loc");
+ RNA_def_property_ui_text(prop, "Location", "");
+
+ prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ROTATION);
+ RNA_def_property_float_sdna(prop, NULL, "rot");
+ RNA_def_property_ui_text(prop, "Rotation", "");
+
+ prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_VECTOR);
+ RNA_def_property_float_sdna(prop, NULL, "size");
+ RNA_def_property_ui_text(prop, "Scale", "");
+
+ prop= RNA_def_property(srna, "minimum", PROP_FLOAT, PROP_VECTOR);
+ RNA_def_property_float_sdna(prop, NULL, "min");
+ RNA_def_property_ui_text(prop, "Minimum", "Minimum value for clipping");
+
+ prop= RNA_def_property(srna, "maximum", PROP_FLOAT, PROP_VECTOR);
+ RNA_def_property_float_sdna(prop, NULL, "max");
+ RNA_def_property_ui_text(prop, "Maximum", "Maximum value for clipping");
+
+ prop= RNA_def_property(srna, "has_minimum", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN);
+ RNA_def_property_ui_text(prop, "Has Minimum", "Whether to use minimum clipping value");
+
+ prop= RNA_def_property(srna, "has_maximum", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX);
+ RNA_def_property_ui_text(prop, "Has Maximum", "Whether to use maximum clipping value");
+}
+
static void rna_def_mtex(BlenderRNA *brna)
{
StructRNA *srna;
@@ -238,7 +307,264 @@ static void rna_def_environment_map(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Depth", "Number of times a map will be rendered recursively (mirror effects.)");
}
-void RNA_def_texture(BlenderRNA *brna)
+static EnumPropertyItem prop_noise_basis_items[] = {
+ {TEX_BLENDER, "BLENDER_ORIGINAL", "Blender Original", ""},
+ {TEX_STDPERLIN, "ORIGINAL_PERLIN", "Original Perlin", ""},
+ {TEX_NEWPERLIN, "IMPROVED_PERLIN", "Improved Perlin", ""},
+ {TEX_VORONOI_F1, "VORONOI_F1", "Voronoi F1", ""},
+ {TEX_VORONOI_F2, "VORONOI_F2", "Voronoi F2", ""},
+ {TEX_VORONOI_F3, "VORONOI_F3", "Voronoi F3", ""},
+ {TEX_VORONOI_F4, "VORONOI_F4", "Voronoi F4", ""},
+ {TEX_VORONOI_F2F1, "VORONOI_F2_F1", "Voronoi F2-F1", ""},
+ {TEX_VORONOI_CRACKLE, "VORONOI_CRACKLE", "Voronoi Crackle", ""},
+ {TEX_CELLNOISE, "CELL_NOISE", "Cell Noise", ""},
+ {0, NULL, NULL, NULL}};
+
+static EnumPropertyItem prop_noise_type[] = {
+ {TEX_NOISESOFT, "SOFT_NOISE", "Soft Noise", ""},
+ {TEX_NOISEPERL, "HARD_NOISE", "Hard Noise", ""},
+ {0, NULL, NULL, NULL}
+ };
+
+
+static void rna_def_texture_clouds(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_clouds_stype[] = {
+ {TEX_DEFAULT, "DEFAULT", "Default", ""},
+ {TEX_COLOR, "COLOR", "Color", ""},
+ {0, NULL, NULL, NULL}
+ };
+
+ srna= RNA_def_struct(brna, "CloudsTexture", "Texture");
+ RNA_def_struct_ui_text(srna, "Clouds Texture", "Procedural noise texture.");
+ RNA_def_struct_sdna(srna, "Tex");
+
+ prop= RNA_def_property(srna, "noise_size", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "noisesize");
+ RNA_def_property_range(prop, 0.0001, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
+ RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
+
+ prop= RNA_def_property(srna, "noise_depth", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "noisedepth");
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_range(prop, 0, 6, 0, 2);
+ RNA_def_property_ui_text(prop, "Noise Depth", "Sets the depth of the cloud calculation");
+
+
+ prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
+ RNA_def_property_enum_items(prop, prop_noise_basis_items);
+ RNA_def_property_ui_text(prop, "Noise Basis", "Sets the noise basis used for turbulence");
+
+ prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "noisetype");
+ RNA_def_property_enum_items(prop, prop_noise_type);
+ RNA_def_property_ui_text(prop, "Noise Type", "");
+
+ prop= RNA_def_property(srna, "stype", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "stype");
+ RNA_def_property_enum_items(prop, prop_clouds_stype);
+ RNA_def_property_ui_text(prop, "Color", "");
+
+ prop= RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.001, 0.1);
+ RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
+ RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal.");
+
+}
+
+static void rna_def_texture_wood(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_wood_stype[] = {
+ {TEX_BAND, "BANDS", "Bands", "Uses standard wood texture in bands"},
+ {TEX_RING, "RINGS", "Rings", "Uses wood texture in rings"},
+ {TEX_BANDNOISE, "BANDNOISE", "BandNoise", "Adds noise to standard wood"},
+ {TEX_RINGNOISE, "RINGNOISE", "RingNoise", "Adds noise to rings"},
+ {0, NULL, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_wood_noisebasis2[] = {
+ {TEX_SIN, "SIN", "Sin", "Uses a sine wave to produce bands"},
+ {TEX_SAW, "SAW", "Saw", "Uses a saw wave to produce bands"},
+ {TEX_TRI, "TRI", "Tri", "Uses a triangle wave to produce bands"},
+ {0, NULL, NULL, NULL}
+ };
+
+ srna= RNA_def_struct(brna, "WoodTexture", "Texture");
+ RNA_def_struct_ui_text(srna, "Wood Texture", "Procedural noise texture.");
+ RNA_def_struct_sdna(srna, "Tex");
+
+ prop= RNA_def_property(srna, "noise_size", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "noisesize");
+ RNA_def_property_range(prop, 0.0001, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
+ RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
+
+ prop= RNA_def_property(srna, "turbulence", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "turbul");
+ RNA_def_property_range(prop, 0.0001, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0001, 200, 10, 2);
+ RNA_def_property_ui_text(prop, "Turbulence", "Sets the turbulence of the bandnoise and ringnoise types");
+
+ prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
+ RNA_def_property_enum_items(prop, prop_noise_basis_items);
+ RNA_def_property_ui_text(prop, "Noise Basis", "Sets the noise basis used for turbulence");
+
+ prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "noisetype");
+ RNA_def_property_enum_items(prop, prop_noise_type);
+ RNA_def_property_ui_text(prop, "Noise Type", "");
+
+ prop= RNA_def_property(srna, "stype", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "stype");
+ RNA_def_property_enum_items(prop, prop_wood_stype);
+ RNA_def_property_ui_text(prop, "Pattern", "");
+
+ prop= RNA_def_property(srna, "noisebasis2", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "noisebasis2");
+ RNA_def_property_enum_items(prop, prop_wood_noisebasis2);
+ RNA_def_property_ui_text(prop, "Noise Basis 2", "");
+
+ prop= RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.001, 0.1);
+ RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
+ RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal.");
+
+}
+
+static void rna_def_texture_marble(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_marble_stype[] = {
+ {TEX_SOFT, "SOFT", "Soft", "Uses soft marble"},
+ {TEX_SHARP, "SHARP", "Sharp", "Uses more clearly defined marble"},
+ {TEX_SHARPER, "SHARPER", "Sharper", "Uses very clearly defined marble"},
+ {0, NULL, NULL, NULL}
+ };
+
+ static EnumPropertyItem prop_marble_noisebasis2[] = {
+ {TEX_SIN, "SIN", "Sin", "Uses a sine wave to produce bands"},
+ {TEX_SAW, "SAW", "Saw", "Uses a saw wave to produce bands"},
+ {TEX_TRI, "TRI", "Tri", "Uses a triangle wave to produce bands"},
+ {0, NULL, NULL, NULL}
+ };
+
+ srna= RNA_def_struct(brna, "MarbleTexture", "Texture");
+ RNA_def_struct_ui_text(srna, "Marble Texture", "Procedural noise texture.");
+ RNA_def_struct_sdna(srna, "Tex");
+
+ prop= RNA_def_property(srna, "noise_size", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "noisesize");
+ RNA_def_property_range(prop, 0.0001, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
+ RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
+
+ prop= RNA_def_property(srna, "turbulence", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "turbul");
+ RNA_def_property_range(prop, 0.0001, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0001, 200, 10, 2);
+ RNA_def_property_ui_text(prop, "Turbulence", "Sets the turbulence of the bandnoise and ringnoise types");
+
+ prop= RNA_def_property(srna, "noise_depth", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "noisedepth");
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_range(prop, 0, 6, 0, 2);
+ RNA_def_property_ui_text(prop, "Noise Depth", "Sets the depth of the cloud calculation");
+
+ prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "noisetype");
+ RNA_def_property_enum_items(prop, prop_noise_type);
+ RNA_def_property_ui_text(prop, "Noise Type", "");
+
+ prop= RNA_def_property(srna, "stype", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "stype");
+ RNA_def_property_enum_items(prop, prop_marble_stype);
+ RNA_def_property_ui_text(prop, "Pattern", "");
+
+ prop= RNA_def_property(srna, "noisebasis2", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "noisebasis2");
+ RNA_def_property_enum_items(prop, prop_marble_noisebasis2);
+ RNA_def_property_ui_text(prop, "Noise Basis 2", "");
+
+ prop= RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.001, 0.1);
+ RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
+ RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal.");
+
+}
+
+static void rna_def_texture_magic(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna= RNA_def_struct(brna, "MagicTexture", "Texture");
+ RNA_def_struct_ui_text(srna, "Magic Texture", "Procedural noise texture.");
+ RNA_def_struct_sdna(srna, "Tex");
+
+ prop= RNA_def_property(srna, "turbulence", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "turbul");
+ RNA_def_property_range(prop, 0.0001, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0001, 200, 10, 2);
+ RNA_def_property_ui_text(prop, "Turbulence", "Sets the turbulence of the bandnoise and ringnoise types");
+
+ prop= RNA_def_property(srna, "noise_depth", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "noisedepth");
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_range(prop, 0, 6, 0, 2);
+ RNA_def_property_ui_text(prop, "Noise Depth", "Sets the depth of the cloud calculation");
+}
+
+static void rna_def_texture_stucci(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_stucci_stype[] = {
+ {TEX_PLASTIC, "PLASTIC", "Plastic", "Uses standard stucci"},
+ {TEX_WALLIN, "WALL_IN", "Wall in", "Creates Dimples"},
+ {TEX_WALLOUT, "WALL_OUT", "Wall out", "Creates Ridges"},
+ {0, NULL, NULL, NULL}
+ };
+
+ srna= RNA_def_struct(brna, "StucciTexture", "Texture");
+ RNA_def_struct_ui_text(srna, "Stucci Texture", "Procedural noise texture.");
+ RNA_def_struct_sdna(srna, "Tex");
+
+ prop= RNA_def_property(srna, "turbulence", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "turbul");
+ RNA_def_property_range(prop, 0.0001, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0001, 200, 10, 2);
+ RNA_def_property_ui_text(prop, "Turbulence", "Sets the turbulence of the bandnoise and ringnoise types");
+
+ prop= RNA_def_property(srna, "noise_size", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "noisesize");
+ RNA_def_property_range(prop, 0.0001, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
+ RNA_def_property_ui_text(prop, "Noise Size", "Sets scaling for noise input");
+
+ prop= RNA_def_property(srna, "noise_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "noisetype");
+ RNA_def_property_enum_items(prop, prop_noise_type);
+ RNA_def_property_ui_text(prop, "Noise Type", "");
+
+ prop= RNA_def_property(srna, "stype", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "stype");
+ RNA_def_property_enum_items(prop, prop_stucci_stype);
+ RNA_def_property_ui_text(prop, "Pattern", "");
+}
+
+static void rna_def_texture(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
@@ -260,56 +586,19 @@ void RNA_def_texture(BlenderRNA *brna)
{TEX_DISTNOISE, "DISTORTED_NOISE", "Distorted Noise", ""},
{0, NULL, NULL, NULL}};
- static EnumPropertyItem prop_distance_metric_items[] = {
- {TEX_DISTANCE, "DISTANCE", "Actual Distance", ""},
- {TEX_DISTANCE_SQUARED, "DISTANCE_SQUARED", "Distance Squared", ""},
- {TEX_MANHATTAN, "MANHATTAN", "Manhattan", ""},
- {TEX_CHEBYCHEV, "CHEBYCHEV", "Chebychev", ""},
- {TEX_MINKOVSKY_HALF, "MINKOVSKY_HALF", "Minkovsky 1/2", ""},
- {TEX_MINKOVSKY_FOUR, "MINKOVSKY_FOUR", "Minkovsky 4", ""},
- {TEX_MINKOVSKY, "MINKOVSKY", "Minkovsky", ""},
- {0, NULL, NULL, NULL}};
-
- static EnumPropertyItem prop_color_type_items[] = {
- /* XXX: OK names / descriptions? */
- {TEX_INTENSITY, "INTENSITY", "Intensity", "Only calculate intensity."},
- {TEX_COL1, "POSITION", "Position", "Color cells by position."},
- {TEX_COL2, "POSITION_OUTLINE", "Position and Outline", "Use position plus an outline based on F2-F.1"},
- {TEX_COL3, "POSITION_OUTLINE_INTENSITY", "Position, Outline, and Intensity", "Multiply position and outline by intensity."},
- {0, NULL, NULL, NULL}};
-
- static EnumPropertyItem prop_noise_basis_items[] = {
- {TEX_BLENDER, "BLENDER_ORIGINAL", "Blender Original", ""},
- {TEX_STDPERLIN, "ORIGINAL_PERLIN", "Original Perlin", ""},
- {TEX_NEWPERLIN, "IMPROVED_PERLIN", "Improved Perlin", ""},
- {TEX_VORONOI_F1, "VORONOI_F1", "Voronoi F1", ""},
- {TEX_VORONOI_F2, "VORONOI_F2", "Voronoi F2", ""},
- {TEX_VORONOI_F3, "VORONOI_F3", "Voronoi F3", ""},
- {TEX_VORONOI_F4, "VORONOI_F4", "Voronoi F4", ""},
- {TEX_VORONOI_F2F1, "VORONOI_F2_F1", "Voronoi F2-F1", ""},
- {TEX_VORONOI_CRACKLE, "VORONOI_CRACKLE", "Voronoi Crackle", ""},
- {TEX_CELLNOISE, "CELL_NOISE", "Cell Noise", ""},
- {0, NULL, NULL, NULL}};
-
srna= RNA_def_struct(brna, "Texture", "ID");
RNA_def_struct_sdna(srna, "Tex");
RNA_def_struct_ui_text(srna, "Texture", "Texture datablock used by materials, lamps, worlds and brushes.");
+ RNA_def_struct_refine_func(srna, "rna_Texture_refine");
prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_type_items);
RNA_def_property_ui_text(prop, "Type", "");
- prop= RNA_def_property(srna, "noise_size", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "noisesize");
- RNA_def_property_range(prop, 0.0001, FLT_MAX);
- RNA_def_property_ui_range(prop, 0.0001, 2, 10, 2);
- RNA_def_property_ui_text(prop, "Noise Size", "");
-
- prop= RNA_def_property(srna, "turbulence", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "turbul");
- RNA_def_property_range(prop, 0, FLT_MAX);
- RNA_def_property_ui_range(prop, 0, 200, 10, 2);
- RNA_def_property_ui_text(prop, "Turbulence", "");
+ prop= RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NEVER_NULL);
+ RNA_def_property_pointer_sdna(prop, NULL, "coba");
+ RNA_def_property_struct_type(prop, "ColorRamp");
+ RNA_def_property_ui_text(prop, "Color Ramp", "");
prop= RNA_def_property(srna, "brightness", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bright");
@@ -328,6 +617,44 @@ void RNA_def_texture(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 2);
RNA_def_property_ui_text(prop, "RGB Factor", "");
+ rna_def_animdata_common(srna);
+
+ /* specific types */
+ rna_def_texture_clouds(brna);
+ rna_def_texture_wood(brna);
+ rna_def_texture_marble(brna);
+ rna_def_texture_magic(brna);
+ rna_def_texture_stucci(brna);
+ /* XXX add more types here .. */
+
+ /* ********** XXX these should be moved to the specific types *****************/
+
+#if 0
+ static EnumPropertyItem prop_distance_metric_items[] = {
+ {TEX_DISTANCE, "DISTANCE", "Actual Distance", ""},
+ {TEX_DISTANCE_SQUARED, "DISTANCE_SQUARED", "Distance Squared", ""},
+ {TEX_MANHATTAN, "MANHATTAN", "Manhattan", ""},
+ {TEX_CHEBYCHEV, "CHEBYCHEV", "Chebychev", ""},
+ {TEX_MINKOVSKY_HALF, "MINKOVSKY_HALF", "Minkovsky 1/2", ""},
+ {TEX_MINKOVSKY_FOUR, "MINKOVSKY_FOUR", "Minkovsky 4", ""},
+ {TEX_MINKOVSKY, "MINKOVSKY", "Minkovsky", ""},
+ {0, NULL, NULL, NULL}};
+
+ static EnumPropertyItem prop_color_type_items[] = {
+ /* XXX: OK names / descriptions? */
+ {TEX_INTENSITY, "INTENSITY", "Intensity", "Only calculate intensity."},
+ {TEX_COL1, "POSITION", "Position", "Color cells by position."},
+ {TEX_COL2, "POSITION_OUTLINE", "Position and Outline", "Use position plus an outline based on F2-F.1"},
+ {TEX_COL3, "POSITION_OUTLINE_INTENSITY", "Position, Outline, and Intensity", "Multiply position and outline by intensity."},
+ {0, NULL, NULL, NULL}};
+
+
+ prop= RNA_def_property(srna, "turbulence", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "turbul");
+ RNA_def_property_range(prop, 0, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0, 200, 10, 2);
+ RNA_def_property_ui_text(prop, "Turbulence", "");
+
/* XXX: tex->filtersize */
/* Musgrave */
@@ -390,10 +717,6 @@ void RNA_def_texture(BlenderRNA *brna)
RNA_def_property_enum_items(prop, prop_color_type_items);
RNA_def_property_ui_text(prop, "Color Type", "");
- prop= RNA_def_property(srna, "noise_basis", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "noisebasis");
- RNA_def_property_enum_items(prop, prop_noise_basis_items);
- RNA_def_property_ui_text(prop, "Noise Basis", "");
/* XXX: noisebasis2 */
/* XXX: imaflag */
@@ -401,7 +724,7 @@ void RNA_def_texture(BlenderRNA *brna)
/* XXX: stype */
/* XXX: did this as an array, but needs better descriptions than "1 2 3 4"
- perhaps a new subtype could be added? */
+ perhaps a new subtype could be added? */
prop= RNA_def_property(srna, "crop_rectangle", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "cropxmin");
RNA_def_property_array(prop, 4);
@@ -413,17 +736,11 @@ void RNA_def_texture(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 1);
RNA_def_property_ui_text(prop, "Checker Separation", "");
- prop= RNA_def_property(srna, "nabla", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 0.001, 0.1);
- RNA_def_property_ui_range(prop, 0.001, 0.1, 1, 2);
- RNA_def_property_ui_text(prop, "Nabla", "Size of derivative offset used for calculating normal.");
prop= RNA_def_property(srna, "normal_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "norfac");
RNA_def_property_range(prop, 0, 25);
RNA_def_property_ui_text(prop, "Normal Factor", "Amount the texture affects normal values.");
-
- rna_def_animdata_common(srna);
prop= RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "ima");
@@ -432,20 +749,21 @@ void RNA_def_texture(BlenderRNA *brna)
/* XXX: plugin */
- prop= RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NEVER_NULL);
- RNA_def_property_pointer_sdna(prop, NULL, "coba");
- RNA_def_property_struct_type(prop, "ColorRamp");
- RNA_def_property_ui_text(prop, "Color Ramp", "");
-
prop= RNA_def_property(srna, "environment_map", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "env");
RNA_def_property_struct_type(prop, "EnvironmentMap");
RNA_def_property_ui_text(prop, "Environment Map", "");
+#endif
+}
+void RNA_def_texture(BlenderRNA *brna)
+{
+ rna_def_texture(brna);
rna_def_mtex(brna);
rna_def_environment_map(brna);
rna_def_color_ramp(brna);
rna_def_color_ramp_element(brna);
+ rna_def_texmapping(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_timeline.c b/source/blender/makesrna/intern/rna_timeline.c
index d42603e1952..d42603e1952 100755..100644
--- a/source/blender/makesrna/intern/rna_timeline.c
+++ b/source/blender/makesrna/intern/rna_timeline.c
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index e5a5293c9ea..b6767eac989 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -1272,7 +1272,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
prop= RNA_def_property(srna, "smooth_view", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "smooth_viewtx");
RNA_def_property_range(prop, 0, 1000);
- RNA_def_property_ui_text(prop, "Smooth View", "The time to animate the view in miliseconds, zero to disable.");
+ RNA_def_property_ui_text(prop, "Smooth View", "The time to animate the view in milliseconds, zero to disable.");
prop= RNA_def_property(srna, "rotation_angle", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pad_rot_angle");
diff --git a/source/blender/makesrna/intern/rna_vfont.c b/source/blender/makesrna/intern/rna_vfont.c
index ace6e4a6d25..d18b87e73ee 100644
--- a/source/blender/makesrna/intern/rna_vfont.c
+++ b/source/blender/makesrna/intern/rna_vfont.c
@@ -45,7 +45,7 @@ void RNA_def_vfont(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "VFont");
prop= RNA_def_property(srna, "filename", PROP_STRING, PROP_FILEPATH);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "Filename", "");
diff --git a/source/blender/makesrna/intern/rna_vpaint.c b/source/blender/makesrna/intern/rna_vpaint.c
index ae3491e857e..44219f032e7 100644
--- a/source/blender/makesrna/intern/rna_vpaint.c
+++ b/source/blender/makesrna/intern/rna_vpaint.c
@@ -72,20 +72,6 @@ void RNA_def_vpaint(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", VP_SPRAY);
RNA_def_property_ui_text(prop, "Spray", "Keep applying paint effect while holding mouse.");
- prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
- RNA_def_property_float_sdna(prop, NULL, "r");
- RNA_def_property_array(prop, 3);
- RNA_def_property_ui_text(prop, "Color", "Brush color.");
-
- prop= RNA_def_property(srna, "opacity", PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_sdna(prop, NULL, "a");
- RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Opacity", "Brush Opacity.");
-
- prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_NONE);
- RNA_def_property_range(prop, 2.0f, 64.0f);
- RNA_def_property_ui_text(prop, "Size", "Brush Size.");
-
prop= RNA_def_property(srna, "gamma", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.1f, 5.0f);
RNA_def_property_ui_text(prop, "Gamma", "Vpaint Gamma.");
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 69e7578da1a..cabecaaf832 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -87,7 +87,7 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "wmOperator");
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop, "rna_Operator_name_get", "rna_Operator_name_length", NULL);
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_struct_name_property(srna, prop);
diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c
index 0296361da56..0e3e68d1def 100644
--- a/source/blender/makesrna/intern/rna_world.c
+++ b/source/blender/makesrna/intern/rna_world.c
@@ -241,7 +241,7 @@ static void rna_def_world_mist(BlenderRNA *brna)
srna= RNA_def_struct(brna, "WorldMistSettings", NULL);
RNA_def_struct_sdna(srna, "World");
RNA_def_struct_nested(brna, srna, "World");
- RNA_def_struct_ui_text(srna, "World Mist", "Mist settings for a World datatblock.");
+ RNA_def_struct_ui_text(srna, "World Mist", "Mist settings for a World data-block.");
prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_MIST);
@@ -284,7 +284,7 @@ static void rna_def_world_stars(BlenderRNA *brna)
srna= RNA_def_struct(brna, "WorldStarsSettings", NULL);
RNA_def_struct_sdna(srna, "World");
RNA_def_struct_nested(brna, srna, "World");
- RNA_def_struct_ui_text(srna, "World Stars", "Stars setting for a World datatblock.");
+ RNA_def_struct_ui_text(srna, "World Stars", "Stars setting for a World data-block.");
prop= RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", WO_STARS);
@@ -411,7 +411,6 @@ void RNA_def_world(BlenderRNA *brna)
prop= RNA_def_property(srna, "script_link", PROP_POINTER, PROP_NEVER_NULL);
RNA_def_property_pointer_sdna(prop, NULL, "scriptlink");
- RNA_def_property_flag(prop, PROP_NOT_EDITABLE);
RNA_def_property_ui_text(prop, "Script Link", "Scripts linked to this object.");
rna_def_ambient_occlusion(brna);
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/python/epy_doc_gen.py b/source/blender/python/epy_doc_gen.py
index f14cd2f90f9..a108929febc 100644
--- a/source/blender/python/epy_doc_gen.py
+++ b/source/blender/python/epy_doc_gen.py
@@ -39,11 +39,27 @@ def get_array_str(length):
if length > 0: return ' array of %d items' % length
else: return ''
+def full_rna_struct_path(rna_struct):
+ '''
+ Needed when referencing one struct from another
+ '''
+ nested = rna_struct.nested
+ if nested:
+ return "%s.%s" % (full_rna_struct_path(nested), rna_struct.identifier)
+ else:
+ return rna_struct.identifier
+
+
def rna2epy(target_path):
-
+ # Use for faster lookups
+ # use rna_struct.identifier as the key for each dict
+ rna_full_path_dict = {} # store the result of full_rna_struct_path(rna_struct)
+ rna_children_dict = {} # store all rna_structs nested from here
+ rna_references_dict = {} # store a list of rna path strings that reference this type
+ rna_words = set()
- def write_struct(rna_struct, structs, ident):
+ def write_struct(rna_struct, ident):
identifier = rna_struct.identifier
rna_base = rna_struct.base
@@ -56,10 +72,30 @@ def rna2epy(target_path):
out.write(ident+ '\t"""\n')
title = 'The %s Object' % rna_struct.name
-
+ description = rna_struct.description
out.write(ident+ '\t%s\n' % title)
out.write(ident+ '\t%s\n' % ('=' * len(title)))
- out.write(ident+ '\t\t%s\n' % rna_struct.description)
+ out.write(ident+ '\t\t%s\n' % description)
+ rna_words.update(description.split())
+
+
+ # For convenience, give a list of all places were used.
+ rna_refs= rna_references_dict[identifier]
+
+ if rna_refs:
+ out.write(ident+ '\t\t\n')
+ out.write(ident+ '\t\tReferences\n')
+ out.write(ident+ '\t\t==========\n')
+
+ for rna_ref_string in rna_refs:
+ out.write(ident+ '\t\t\t- L{%s}\n' % rna_ref_string)
+
+ out.write(ident+ '\t\t\n')
+
+ else:
+ out.write(ident+ '\t\t\n')
+ out.write(ident+ '\t\t(no references to this struct found)\n')
+ out.write(ident+ '\t\t\n')
for rna_prop_identifier, rna_prop in rna_struct.properties.items():
@@ -70,6 +106,8 @@ def rna2epy(target_path):
continue
rna_desc = rna_prop.description
+
+ if rna_desc: rna_words.update(rna_desc.split())
if not rna_desc: rna_desc = rna_prop.name
if not rna_desc: rna_desc = 'Note - No documentation for this property!'
@@ -110,10 +148,8 @@ def rna2epy(target_path):
out.write(ident+ '\t"""\n\n')
# Now write children recursively
- for child in structs:
- if rna_struct == child.nested:
- write_struct(child, structs, ident + '\t')
-
+ for child in rna_children_dict[identifier]:
+ write_struct(child, ident + '\t')
out = open(target_path, 'w')
@@ -121,12 +157,33 @@ def rna2epy(target_path):
try: return rna_struct.base.identifier
except: return '' # invalid id
- #structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpydoc.structs.values()]
-
+ #structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpy.doc.structs.values()]
+ '''
structs = []
- for rna_struct in bpydoc.structs.values():
+ for rna_struct in bpy.doc.structs.values():
structs.append( (base_id(rna_struct), rna_struct.identifier, rna_struct) )
-
+ '''
+ structs = []
+ for rna_type_name in dir(bpy.types):
+ rna_type = getattr(bpy.types, rna_type_name)
+ if hasattr(rna_type, '__rna__'):
+ #if not rna_type_name.startswith('__'):
+ rna_struct = rna_type.__rna__
+ identifier = rna_struct.identifier
+ structs.append( (base_id(rna_struct), identifier, rna_struct) )
+
+
+
+ # Store full rna path 'GameObjectSettings' -> 'Object.GameObjectSettings'
+ rna_full_path_dict[identifier] = full_rna_struct_path(rna_struct)
+
+ # fill in these later
+ rna_children_dict[identifier]= []
+ rna_references_dict[identifier]= []
+
+ else:
+ print("Ignoring", rna_type_name)
+
structs.sort() # not needed but speeds up sort below, setting items without an inheritance first
@@ -153,19 +210,50 @@ def rna2epy(target_path):
i+=1
if not ok:
- print('Dependancy "%s"could not be found for "%s"' % (identifier, rna_base))
+ print('Dependancy "%s" could not be found for "%s"' % (identifier, rna_base))
break
- structs = [data[2] for data in structs]
# Done ordering structs
- for rna_struct in structs:
+ # precalc vars to avoid a lot of looping
+ for (rna_base, identifier, rna_struct) in structs:
+
+
+ # rna_struct_path = full_rna_struct_path(rna_struct)
+ rna_struct_path = rna_full_path_dict[identifier]
+
+ for rna_prop_identifier, rna_prop in rna_struct.properties.items():
+ if rna_prop_identifier=='RNA':
+ continue
+
+ if rna_prop_identifier=='rna_type':
+ continue
+
+ try: rna_prop_ptr = rna_prop.fixed_type
+ except: rna_prop_ptr = None
+
+ # Does this property point to me?
+ if rna_prop_ptr:
+ rna_references_dict[rna_prop_ptr.identifier].append( "%s.%s" % (rna_struct_path, rna_prop_identifier) )
+
+
+
+ # Store nested children
+ nested = rna_struct.nested
+ if nested:
+ rna_children_dict[nested.identifier].append(rna_struct)
+
+ # Sort the refs, just reads nicer
+ for rna_refs in rna_references_dict.values():
+ rna_refs.sort()
+
+ for (rna_base, identifier, rna_struct) in structs:
if rna_struct.nested:
continue
- write_struct(rna_struct, structs, '')
+ write_struct(rna_struct, '')
out.write('\n')
@@ -173,16 +261,89 @@ def rna2epy(target_path):
# # We could also just run....
# os.system('epydoc source/blender/python/doc/rna.py -o ./source/blender/python/doc/html -v')
+
+
+ # Write graphviz
+ out= open(target_path.replace('.py', '.dot'), 'w')
+ out.write('digraph "rna data api" {\n')
+ out.write('\tnode [style=filled, shape = "box"];\n')
+ out.write('\toverlap=false;\n')
+ out.write('\trankdir = LR;\n')
+ out.write('\tsplines=true;\n')
+ out.write('\tratio=auto;\n')
+
+
+
+ out.write('\tsize="10,10"\n')
+ #out.write('\tpage="8.5,11"\n')
+ #out.write('\tcenter=""\n')
+
+ def isop(rna_struct):
+ return '_OT_' in rna_struct.identifier
+
+
+ for (rna_base, identifier, rna_struct) in structs:
+ if isop(rna_struct):
+ continue
+
+ base = rna_struct.base
+
+
+ out.write('\t"%s";\n' % identifier)
+
+ for (rna_base, identifier, rna_struct) in structs:
+
+ if isop(rna_struct):
+ continue
+
+ base = rna_struct.base
+
+ if base and not isop(base):
+ out.write('\t"%s" -> "%s" [label="(base)" weight=1.0];\n' % (base.identifier, identifier))
+
+ nested = rna_struct.nested
+ if nested and not isop(nested):
+ out.write('\t"%s" -> "%s" [label="(nested)" weight=1.0];\n' % (nested.identifier, identifier))
+
+
+
+ rna_refs= rna_references_dict[identifier]
+
+ for rna_ref_string in rna_refs:
+
+ if '_OT_' in rna_ref_string:
+ continue
+
+ ref = rna_ref_string.split('.')[-2]
+ out.write('\t"%s" -> "%s" [label="%s" weight=0.01];\n' % (ref, identifier, rna_ref_string))
+
+
+
+ out.write('}\n')
+ out.close()
+
+ # # We could also just run....
+ # os.system('dot source/blender/python/doc/rna.dot -Tsvg -o ./source/blender/python/doc/rna.svg')
+
+
+ out= open(target_path.replace('.py', '.words'), 'w')
+ rna_words = list(rna_words)
+ rna_words.sort()
+ for w in rna_words:
+ out.write('%s\n' % w)
+
+
+
+
def op2epy(target_path):
out = open(target_path, 'w')
- operators = dir(bpyoperator)
+ operators = dir(bpy.ops)
operators.remove('add')
operators.remove('remove')
operators.sort()
-
for op in operators:
if op.startswith('__'):
@@ -192,7 +353,9 @@ def op2epy(target_path):
kw_args = [] # "foo = 1", "bar=0.5", "spam='ENUM'"
kw_arg_attrs = [] # "@type mode: int"
- rna = getattr(bpyoperator, op).rna
+ # rna = getattr(bpy.types, op).__rna__
+ rna = bpy.ops.__rna__(op)
+
rna_struct = rna.rna_type
# print (dir(rna))
# print (dir(rna_struct))
@@ -210,14 +373,18 @@ def op2epy(target_path):
try:
val = getattr(rna, rna_prop_identifier)
+ val_error = False
except:
- val = '<UNDEFINED>'
+ val = "'<UNDEFINED>'"
+ val_error = True
kw_type_str= "@type %s: %s%s" % (rna_prop_identifier, rna_prop_type, array_str)
kw_param_str= "@param %s: %s" % (rna_prop_identifier, rna_prop.description)
kw_param_set = False
- if rna_prop_type=='float':
+ if val_error:
+ val_str = val
+ elif rna_prop_type=='float':
if length==0:
val_str= '%g' % val
if '.' not in val_str:
diff --git a/source/blender/python/intern/bpy_compat.h b/source/blender/python/intern/bpy_compat.h
index e2337db4925..4f64c916ca2 100644
--- a/source/blender/python/intern/bpy_compat.h
+++ b/source/blender/python/intern/bpy_compat.h
@@ -37,7 +37,7 @@
#undef PyUnicode_Check
#define PyUnicode_Check PyString_Check
-#define PyLong_FromSize_t PyInt_FromLong
+#define PyLong_FromSsize_t PyInt_FromLong
#define PyLong_AsSsize_t PyInt_AsLong
#undef PyLong_Check
@@ -56,6 +56,18 @@
#endif
+#ifndef Py_REFCNT
+#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
+#endif
+
+#ifndef Py_TYPE
+#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
+#endif
+
+#ifndef Py_TYPE
+#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
+#endif
+
/* older then python 2.6 - define these */
// #if (PY_VERSION_HEX < 0x02060000)
// #endif
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index bb315cda47a..94ec8deebe4 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -34,36 +34,45 @@ void BPY_free_compiled_text( struct Text *text )
static PyObject *CreateGlobalDictionary( bContext *C )
{
+ PyObject *mod;
PyObject *dict = PyDict_New( );
PyObject *item = PyUnicode_FromString( "__main__" );
PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins( ) );
PyDict_SetItemString( dict, "__name__", item );
Py_DECREF(item);
- /* Add Modules */
- item = BPY_rna_module();
- PyDict_SetItemString( dict, "bpy", item );
- Py_DECREF(item);
+ /* add bpy to global namespace */
+ mod = PyModule_New("bpy");
+ PyDict_SetItemString( dict, "bpy", mod );
+ Py_DECREF(mod);
- item = BPY_rna_doc();
- PyDict_SetItemString( dict, "bpydoc", item );
- Py_DECREF(item);
-
- item = BPY_operator_module(C);
- PyDict_SetItemString( dict, "bpyoperator", item );
- Py_DECREF(item);
-
-
- // XXX very experemental, consiter this a test, especiall PyCObject is not meant to be perminant
- item = BPY_ui_module();
- PyDict_SetItemString( dict, "bpyui", item );
- Py_DECREF(item);
+ PyModule_AddObject( mod, "data", BPY_rna_module() );
+ /* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
+ PyModule_AddObject( mod, "types", BPY_rna_types() );
+ PyModule_AddObject( mod, "ops", BPY_operator_module(C) );
+ PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experemental, consider this a test, especially PyCObject is not meant to be perminant
// XXX - evil, need to access context
item = PyCObject_FromVoidPtr( C, NULL );
PyDict_SetItemString( dict, "__bpy_context__", item );
Py_DECREF(item);
+
+ // XXX - put somewhere more logical
+ {
+ PyMethodDef *ml;
+ static PyMethodDef bpy_prop_meths[] = {
+ {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
+ {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
+ {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
+ {NULL, NULL, 0, NULL}
+ };
+
+ for(ml = bpy_prop_meths; ml->ml_name; ml++) {
+ PyDict_SetItemString( dict, ml->ml_name, PyCFunction_New(ml, NULL));
+ }
+ }
+
return dict;
}
@@ -90,8 +99,10 @@ void BPY_end_python( void )
PyGILState_Ensure(); /* finalizing, no need to grab the state */
// free other python data.
+ //BPY_rna_free_types();
Py_Finalize( );
+
return;
}
@@ -122,8 +133,10 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text )
MEM_freeN( buf );
if( PyErr_Occurred( ) ) {
+ PyErr_Print();
BPY_free_compiled_text( text );
- return NULL;
+ PyGILState_Release(gilstate);
+ return 0;
}
}
py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict );
@@ -253,6 +266,7 @@ int BPY_run_python_script_space(const char *modulename, const char *func)
PyErr_SetFormat(PyExc_SystemError, "module has no function '%s.%s'\n", scpt->script.filename, func);
}
else {
+ Py_DECREF(py_func);
if (!PyCallable_Check(py_func)) {
PyErr_SetFormat(PyExc_SystemError, "module item is not callable '%s.%s'\n", scpt->script.filename, func);
}
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index ec8227c670d..02f4723c037 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -107,109 +107,27 @@ int PYOP_props_from_dict(PointerRNA *ptr, PyObject *kw)
return error_val;
}
-
-
-
-static int pyop_func_compare( BPy_OperatorFunc * a, BPy_OperatorFunc * b )
-{
- return (strcmp(a->name, b->name)==0) ? 0 : -1;
-}
-
-/* For some reason python3 needs these :/ */
-static PyObject *pyop_func_richcmp(BPy_OperatorFunc * a, BPy_OperatorFunc * b, int op)
-{
- int cmp_result= -1; /* assume false */
- if (BPy_OperatorFunc_Check(a) && BPy_OperatorFunc_Check(b)) {
- cmp_result= pyop_func_compare(a, b);
- }
-
- return Py_CmpToRich(op, cmp_result);
-}
-
-
-/*----------------------repr--------------------------------------------*/
-static PyObject *pyop_base_repr( BPy_OperatorBase * self )
-{
- return PyUnicode_FromFormat( "[BPy_OperatorBase]");
-}
-
-static PyObject *pyop_func_repr( BPy_OperatorFunc * self )
-{
- return PyUnicode_FromFormat( "[BPy_OperatorFunc \"%s\"]", self->name);
-}
-
+static PyObject *pyop_base_dir(PyObject *self);
+static PyObject *pyop_base_rna(PyObject *self, PyObject *pyname);
static struct PyMethodDef pyop_base_methods[] = {
- {"add", (PyCFunction)PYOP_wrap_add, METH_VARARGS, ""},
- {"remove", (PyCFunction)PYOP_wrap_remove, METH_VARARGS, ""},
+ {"__dir__", (PyCFunction)pyop_base_dir, METH_NOARGS, ""},
+ {"__rna__", (PyCFunction)pyop_base_rna, METH_O, ""},
+ {"add", (PyCFunction)PYOP_wrap_add, METH_O, ""},
+ {"remove", (PyCFunction)PYOP_wrap_remove, METH_O, ""},
{NULL, NULL, 0, NULL}
};
-//---------------getattr--------------------------------------------
-static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname )
-{
- char *name = _PyUnicode_AsString(pyname);
- PyObject *ret;
- wmOperatorType *ot;
- PyMethodDef *meth;
-
- if ((ot = WM_operatortype_find(name))) {
- ret= pyop_func_CreatePyObject(self->C, name);
- }
- else if (strcmp(name, "__dict__")==0) {
- ret = PyDict_New();
-
- for(ot= WM_operatortype_first(); ot; ot= ot->next) {
- PyDict_SetItemString(ret, ot->idname, Py_None);
- }
-
- for(meth=pyop_base_methods; meth->ml_name; meth++) {
- PyDict_SetItemString(ret, meth->ml_name, Py_None);
- }
- }
- else if ((ret = PyObject_GenericGetAttr((PyObject *)self, pyname))) {
- /* do nothing, this accounts for methoddef's add and remove */
- }
- else {
- PyErr_Format( PyExc_AttributeError, "Operator \"%s\" not found", name);
- ret= NULL;
- }
-
- return ret;
-}
-
-/* getseter's */
-PyObject *pyop_func_get_rna(BPy_OperatorFunc *self)
-{
- BPy_StructRNA *pyrna;
- PointerRNA ptr;
- wmOperatorType *ot;
-
- ot= WM_operatortype_find(self->name);
- if (ot == NULL) {
- PyErr_SetString( PyExc_SystemError, "Operator could not be found");
- return NULL;
- }
-
- pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); /* were not really using &ptr, overwite next */
-
- /* XXX POINTER - if this 'ot' is python generated, it could be free'd */
- RNA_pointer_create(NULL, ot->srna, NULL, &pyrna->ptr);
- pyrna->freeptr= 1;
-
- return (PyObject *)pyrna;
-}
-
-static PyGetSetDef pyop_func_getseters[] = {
- {"rna", (getter)pyop_func_get_rna, (setter)NULL, "Operator RNA properties", NULL},
- {NULL,NULL,NULL,NULL,NULL} /* Sentinel */
-};
-
-static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObject *kw)
+/* 'self' stores the operator string */
+static PyObject *pyop_base_call( PyObject * self, PyObject * args, PyObject * kw)
{
wmOperatorType *ot;
-
int error_val = 0;
PointerRNA ptr;
+
+ // XXX Todo, work out a better solution for passing on context, could make a tuple from self and pack the name and Context into it...
+ bContext *C = (bContext *)PyCObject_AsVoidPtr(PyDict_GetItemString(PyEval_GetGlobals(), "__bpy_context__"));
+
+ char *opname = _PyUnicode_AsString(self);
char *report_str= NULL;
if (PyTuple_Size(args)) {
@@ -217,18 +135,18 @@ static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObje
return NULL;
}
- ot= WM_operatortype_find(self->name);
+ ot= WM_operatortype_find(opname);
if (ot == NULL) {
- PyErr_SetString( PyExc_SystemError, "Operator could not be found");
+ PyErr_Format( PyExc_SystemError, "Operator \"%s\"could not be found", opname);
return NULL;
}
- if(ot->poll && (ot->poll(self->C) == 0)) {
+ if(ot->poll && (ot->poll(C) == 0)) {
PyErr_SetString( PyExc_SystemError, "Operator poll() function failed, context is incorrect");
return NULL;
}
- WM_operator_properties_create(&ptr, self->name);
+ WM_operator_properties_create(&ptr, opname);
error_val= PYOP_props_from_dict(&ptr, kw);
@@ -237,7 +155,7 @@ static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObje
BKE_reports_init(&reports, RPT_STORE);
- WM_operator_call_py(self->C, ot, &ptr, &reports);
+ WM_operator_call_py(C, ot, &ptr, &reports);
report_str= BKE_reports_string(&reports, RPT_ERROR);
@@ -258,11 +176,11 @@ static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObje
{
/* no props */
if (kw != NULL) {
- PyErr_Format(PyExc_AttributeError, "Operator \"%s\" does not take any args", self->name);
+ PyErr_Format(PyExc_AttributeError, "Operator \"%s\" does not take any args", opname);
return NULL;
}
- WM_operator_name_call(self->C, self->name, WM_OP_EXEC_DEFAULT, NULL);
+ WM_operator_name_call(C, opname, WM_OP_EXEC_DEFAULT, NULL);
}
#endif
@@ -273,222 +191,89 @@ static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObje
Py_RETURN_NONE;
}
-/*-----------------------BPy_OperatorBase method def------------------------------*/
-PyTypeObject pyop_base_Type = {
-#if (PY_VERSION_HEX >= 0x02060000)
- PyVarObject_HEAD_INIT(NULL, 0)
-#else
- /* python 2.5 and below */
- PyObject_HEAD_INIT( NULL ) /* required py macro */
- 0, /* ob_size */
-#endif
-
- "Operator", /* tp_name */
- sizeof( BPy_OperatorBase ), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- NULL, /* tp_dealloc */
- NULL, /* printfunc tp_print; */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL, /* tp_compare */
- ( reprfunc ) pyop_base_repr, /* tp_repr */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- NULL, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
- ( getattrofunc )pyop_base_getattro, /*PyObject_GenericGetAttr - MINGW Complains, assign later */ /* getattrofunc tp_getattro; */
- NULL, /*PyObject_GenericSetAttr - MINGW Complains, assign later */ /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- NULL, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- pyop_base_methods, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- NULL, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL
+static PyMethodDef pyop_base_call_meth[] = {
+ {"__op_call__", (PyCFunction)pyop_base_call, METH_VARARGS|METH_KEYWORDS, "generic operator calling function"}
};
-/*-----------------------BPy_OperatorBase method def------------------------------*/
-PyTypeObject pyop_func_Type = {
-#if (PY_VERSION_HEX >= 0x02060000)
- PyVarObject_HEAD_INIT(NULL, 0)
-#else
- /* python 2.5 and below */
- PyObject_HEAD_INIT( NULL ) /* required py macro */
- 0, /* ob_size */
-#endif
-
- "OperatorFunc", /* tp_name */
- sizeof( BPy_OperatorFunc ), /* tp_basicsize */
- 0, /* tp_itemsize */
- /* methods */
- NULL, /* tp_dealloc */
- NULL, /* printfunc tp_print; */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
- ( reprfunc ) pyop_func_repr, /* tp_repr */
-
- /* Method suites for standard classes */
-
- NULL, /* PyNumberMethods *tp_as_number; */
- NULL, /* PySequenceMethods *tp_as_sequence; */
- NULL, /* PyMappingMethods *tp_as_mapping; */
-
- /* More standard operations (here for binary compatibility) */
-
- NULL, /* hashfunc tp_hash; */
- (ternaryfunc)pyop_func_call, /* ternaryfunc tp_call; */
- NULL, /* reprfunc tp_str; */
- NULL, /* getattrofunc tp_getattro; */
- NULL, /*PyObject_GenericSetAttr - MINGW Complains, assign later */ /* setattrofunc tp_setattro; */
-
- /* Functions to access object as input/output buffer */
- NULL, /* PyBufferProcs *tp_as_buffer; */
-
- /*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
-
- NULL, /* char *tp_doc; Documentation string */
- /*** Assigned meaning in release 2.0 ***/
- /* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
-
- /* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
-
- /*** Assigned meaning in release 2.1 ***/
- /*** rich comparisons ***/
- (richcmpfunc)pyop_func_richcmp, /* richcmpfunc tp_richcompare; */
-
- /*** weak reference enabler ***/
- 0, /* long tp_weaklistoffset; */
-
- /*** Added in release 2.2 ***/
- /* Iterators */
- NULL, /* getiterfunc tp_iter; */
- NULL, /* iternextfunc tp_iternext; */
-
- /*** Attribute descriptor and subclassing stuff ***/
- NULL, /* struct PyMethodDef *tp_methods; */
- NULL, /* struct PyMemberDef *tp_members; */
- pyop_func_getseters, /* struct PyGetSetDef *tp_getset; */
- NULL, /* struct _typeobject *tp_base; */
- NULL, /* PyObject *tp_dict; */
- NULL, /* descrgetfunc tp_descr_get; */
- NULL, /* descrsetfunc tp_descr_set; */
- 0, /* long tp_dictoffset; */
- NULL, /* initproc tp_init; */
- NULL, /* allocfunc tp_alloc; */
- NULL, /* newfunc tp_new; */
- /* Low-level free-memory routine */
- NULL, /* freefunc tp_free; */
- /* For PyObject_IS_GC */
- NULL, /* inquiry tp_is_gc; */
- NULL, /* PyObject *tp_bases; */
- /* method resolution order */
- NULL, /* PyObject *tp_mro; */
- NULL, /* PyObject *tp_cache; */
- NULL, /* PyObject *tp_subclasses; */
- NULL, /* PyObject *tp_weaklist; */
- NULL
-};
-PyObject *pyop_base_CreatePyObject( bContext *C )
+//---------------getattr--------------------------------------------
+static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname )
{
- BPy_OperatorBase *pyop;
-
- pyop = ( BPy_OperatorBase * ) PyObject_NEW( BPy_OperatorBase, &pyop_base_Type );
-
- if( !pyop ) {
- PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_OperatorBase object" );
- return NULL;
+ char *name = _PyUnicode_AsString(pyname);
+ PyObject *ret;
+ wmOperatorType *ot;
+
+ if ((ot= WM_operatortype_find(name))) {
+ ret = PyCFunction_New( pyop_base_call_meth, pyname); /* set the name string as self, PyCFunction_New incref's self */
+ }
+ else if ((ret = PyObject_GenericGetAttr((PyObject *)self, pyname))) {
+ /* do nothing, this accounts for methoddef's add and remove */
+ }
+ else {
+ PyErr_Format( PyExc_AttributeError, "Operator \"%s\" not found", name);
+ ret= NULL;
}
- pyop->C = C; /* TODO - copy this? */
-
- return ( PyObject * ) pyop;
+ return ret;
}
-PyObject *pyop_func_CreatePyObject( bContext *C, char *name )
+static PyObject *pyop_base_dir(PyObject *self)
{
- BPy_OperatorFunc *pyop;
+ PyObject *list = PyList_New(0), *name;
+ wmOperatorType *ot;
+ PyMethodDef *meth;
+
+ for(ot= WM_operatortype_first(); ot; ot= ot->next) {
+ name = PyUnicode_FromString(ot->idname);
+ PyList_Append(list, name);
+ Py_DECREF(name);
+ }
- pyop = ( BPy_OperatorFunc * ) PyObject_NEW( BPy_OperatorFunc, &pyop_func_Type );
+ for(meth=pyop_base_methods; meth->ml_name; meth++) {
+ name = PyUnicode_FromString(meth->ml_name);
+ PyList_Append(list, name);
+ Py_DECREF(name);
+ }
+
+ return list;
+}
- if( !pyop ) {
- PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_OperatorFunc object" );
+static PyObject *pyop_base_rna(PyObject *self, PyObject *pyname)
+{
+ char *name = _PyUnicode_AsString(pyname);
+ wmOperatorType *ot;
+
+ if ((ot= WM_operatortype_find(name))) {
+ BPy_StructRNA *pyrna;
+ PointerRNA ptr;
+
+ /* XXX POINTER - if this 'ot' is python generated, it could be free'd */
+ RNA_pointer_create(NULL, ot->srna, NULL, &ptr);
+
+ pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr); /* were not really using &ptr, overwite next */
+ //pyrna->freeptr= 1;
+ return (PyObject *)pyrna;
+ }
+ else {
+ PyErr_Format(PyExc_AttributeError, "Operator \"%s\" not found", name);
return NULL;
}
-
- strcpy(pyop->name, name);
- pyop->C= C; /* TODO - how should contexts be dealt with? */
-
- return ( PyObject * ) pyop;
}
+PyTypeObject pyop_base_Type = {NULL};
+
PyObject *BPY_operator_module( bContext *C )
{
+ pyop_base_Type.tp_name = "OperatorBase";
+ pyop_base_Type.tp_basicsize = sizeof( BPy_OperatorBase );
+ pyop_base_Type.tp_getattro = ( getattrofunc )pyop_base_getattro;
+ pyop_base_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+ pyop_base_Type.tp_methods = pyop_base_methods;
+
if( PyType_Ready( &pyop_base_Type ) < 0 )
return NULL;
- if( PyType_Ready( &pyop_func_Type ) < 0 )
- return NULL;
-
//submodule = Py_InitModule3( "operator", M_rna_methods, "rna module" );
- return pyop_base_CreatePyObject(C);
+ return (PyObject *)PyObject_NEW( BPy_OperatorBase, &pyop_base_Type );
}
-
-
diff --git a/source/blender/python/intern/bpy_operator.h b/source/blender/python/intern/bpy_operator.h
index 2dfd17bb01b..8eb0b887baa 100644
--- a/source/blender/python/intern/bpy_operator.h
+++ b/source/blender/python/intern/bpy_operator.h
@@ -33,28 +33,15 @@
#include "BKE_context.h"
extern PyTypeObject pyop_base_Type;
-extern PyTypeObject pyop_func_Type;
#define BPy_OperatorBase_Check(v) (PyObject_TypeCheck(v, &pyop_base_Type))
-#define BPy_OperatorFunc_Check(v) (PyObject_TypeCheck(v, &pyop_func_Type))
-
typedef struct {
PyObject_HEAD /* required python macro */
- bContext *C;
} BPy_OperatorBase;
-typedef struct {
- PyObject_HEAD /* required python macro */
- char name[OP_MAX_TYPENAME];
- bContext *C;
-} BPy_OperatorFunc;
-
PyObject *BPY_operator_module(bContext *C );
-PyObject *pyop_base_CreatePyObject(bContext *C );
-PyObject *pyop_func_CreatePyObject(bContext *C, char *name );
-
/* fill in properties from a python dict */
int PYOP_props_from_dict(PointerRNA *ptr, PyObject *kw);
diff --git a/source/blender/python/intern/bpy_opwrapper.c b/source/blender/python/intern/bpy_opwrapper.c
index ca6104d087f..b7d4c82588e 100644
--- a/source/blender/python/intern/bpy_opwrapper.c
+++ b/source/blender/python/intern/bpy_opwrapper.c
@@ -40,44 +40,19 @@
#include "bpy_compat.h"
#include "bpy_util.h"
+#define PYOP_ATTR_PROP "__props__"
+#define PYOP_ATTR_UINAME "__label__"
+#define PYOP_ATTR_IDNAME "__name__" /* use pythons class name */
+#define PYOP_ATTR_DESCRIPTION "__doc__" /* use pythons docstring */
+
typedef struct PyOperatorType {
void *next, *prev;
char idname[OP_MAX_TYPENAME];
char name[OP_MAX_TYPENAME];
char description[OP_MAX_TYPENAME]; // XXX should be longer?
- PyObject *py_invoke;
- PyObject *py_exec;
+ PyObject *py_class;
} PyOperatorType;
-static PyObject *pyop_kwargs_from_operator(wmOperator *op)
-{
- PyObject *dict = PyDict_New();
- PyObject *item;
- PropertyRNA *prop, *iterprop;
- CollectionPropertyIterator iter;
- const char *arg_name;
-
- iterprop= RNA_struct_iterator_property(op->ptr);
- RNA_property_collection_begin(op->ptr, iterprop, &iter);
-
- for(; iter.valid; RNA_property_collection_next(&iter)) {
- prop= iter.ptr.data;
-
- arg_name= RNA_property_identifier(&iter.ptr, prop);
-
- if (strcmp(arg_name, "rna_type")==0) continue;
-
- item = pyrna_prop_to_py(op->ptr, prop);
- PyDict_SetItemString(dict, arg_name, item);
- Py_DECREF(item);
- }
-
- RNA_property_collection_end(&iter);
-
- return dict;
-}
-
-
static PyObject *pyop_dict_from_event(wmEvent *event)
{
PyObject *dict= PyDict_New();
@@ -191,33 +166,6 @@ static struct BPY_flag_def pyop_ret_flags[] = {
{NULL, 0}
};
-/* exec only - no user input */
-static int PYTHON_OT_exec(bContext *C, wmOperator *op)
-{
- PyOperatorType *pyot = op->type->pyop_data;
- PyObject *args= PyTuple_New(0);
- PyObject *kw= pyop_kwargs_from_operator(op);
- PyObject *ret;
- int ret_flag;
-
- ret = PyObject_Call(pyot->py_exec, args, kw);
-
- if (ret == NULL) {
- pyop_error_report(op->reports);
- }
- else {
- if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
- /* the returned value could not be converted into a flag */
- pyop_error_report(op->reports);
- }
- }
-
- Py_DECREF(args);
- Py_DECREF(kw);
-
- return ret_flag;
-}
-
/* This invoke function can take events and
*
* It is up to the pyot->py_invoke() python func to run pyot->py_exec()
@@ -233,26 +181,93 @@ static int PYTHON_OT_exec(bContext *C, wmOperator *op)
* op_exec(**prop_defs)
*
* when there is no invoke function, C calls exec and sets the props.
+ * python class instance is stored in op->customdata so exec() can access
*/
-static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- PyOperatorType *pyot = op->type->pyop_data;
- PyObject *args= PyTuple_New(2);
- PyObject *ret;
- int ret_flag;
- PyTuple_SET_ITEM(args, 0, pyop_dict_from_event(event));
- PyTuple_SET_ITEM(args, 1, pyop_kwargs_from_operator(op));
- ret = PyObject_Call(pyot->py_invoke, args, NULL);
+#define PYOP_EXEC 1
+#define PYOP_INVOKE 2
+#define PYOP_POLL 3
+
+static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *event)
+{
+ PyOperatorType *pyot = op->type->pyop_data;
+ PyObject *args;
+ PyObject *ret= NULL, *py_class_instance, *item;
+ int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
+
+ args = PyTuple_New(1);
+ PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(pyot->py_class, "__rna__")); // need to use an rna instance as the first arg
+ py_class_instance = PyObject_Call(pyot->py_class, args, NULL);
+ Py_DECREF(args);
+
+ if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
+
+
+ /* Assign instance attributes from operator properties */
+ {
+ PropertyRNA *prop, *iterprop;
+ CollectionPropertyIterator iter;
+ const char *arg_name;
+
+ iterprop= RNA_struct_iterator_property(op->ptr);
+ RNA_property_collection_begin(op->ptr, iterprop, &iter);
+
+ for(; iter.valid; RNA_property_collection_next(&iter)) {
+ prop= iter.ptr.data;
+ arg_name= RNA_property_identifier(&iter.ptr, prop);
+
+ if (strcmp(arg_name, "rna_type")==0) continue;
+
+ item = pyrna_prop_to_py(op->ptr, prop);
+ PyObject_SetAttrString(py_class_instance, arg_name, item);
+ Py_DECREF(item);
+ }
+ RNA_property_collection_end(&iter);
+ }
+
+
+ if (mode==PYOP_INVOKE) {
+ item= PyObject_GetAttrString(pyot->py_class, "invoke");
+ args = PyTuple_New(2);
+ PyTuple_SET_ITEM(args, 1, pyop_dict_from_event(event));
+ }
+ else if (mode==PYOP_EXEC) {
+ item= PyObject_GetAttrString(pyot->py_class, "exec");
+ args = PyTuple_New(1);
+ }
+ else if (mode==PYOP_POLL) {
+ item= PyObject_GetAttrString(pyot->py_class, "poll");
+ args = PyTuple_New(2);
+ //XXX Todo - wrap context in a useful way, None for now.
+ PyTuple_SET_ITEM(args, 1, Py_None);
+ }
+ PyTuple_SET_ITEM(args, 0, py_class_instance);
+
+ ret = PyObject_Call(item, args, NULL);
+
+ Py_DECREF(args);
+ Py_DECREF(item);
+ }
+
if (ret == NULL) {
pyop_error_report(op->reports);
}
else {
- if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
+ if (mode==PYOP_POLL) {
+ if (PyBool_Check(ret) == 0) {
+ PyErr_SetString(PyExc_ValueError, "Python poll function return value ");
+ pyop_error_report(op->reports);
+ }
+ else {
+ ret_flag= ret==Py_True ? 1:0;
+ }
+
+ } else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
/* the returned value could not be converted into a flag */
pyop_error_report(op->reports);
+
}
/* there is no need to copy the py keyword dict modified by
* pyot->py_invoke(), back to the operator props since they are just
@@ -261,131 +276,238 @@ static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
* If we ever want to do this and use the props again,
* it can be done with - PYOP_props_from_dict(op->ptr, kw)
*/
+
+ Py_DECREF(ret);
}
-
+ return ret_flag;
+}
+
+static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return PYTHON_OT_generic(PYOP_INVOKE, C, op, event);
+}
- Py_DECREF(args); /* also decref's kw */
+static int PYTHON_OT_exec(bContext *C, wmOperator *op)
+{
+ return PYTHON_OT_generic(PYOP_EXEC, C, op, NULL);
+}
- return ret_flag;
+static int PYTHON_OT_poll(bContext *C)
+{
+ // XXX TODO - no way to get the operator type (and therefor class) from the poll function.
+ //return PYTHON_OT_generic(PYOP_POLL, C, NULL, NULL);
+ return 1;
}
void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
{
PyOperatorType *pyot = (PyOperatorType *)userdata;
+ PyObject *py_class = pyot->py_class;
+ PyObject *props, *item;
/* identifiers */
ot->name= pyot->name;
ot->idname= pyot->idname;
ot->description= pyot->description;
- /* api callbacks */
- if (pyot->py_invoke != Py_None)
+ /* api callbacks, detailed checks dont on adding */
+ if (PyObject_HasAttrString(py_class, "invoke"))
ot->invoke= PYTHON_OT_invoke;
-
- ot->exec= PYTHON_OT_exec;
-
- ot->poll= ED_operator_screenactive; /* how should this work?? */
- /* ot->flag= OPTYPE_REGISTER; */
+ if (PyObject_HasAttrString(py_class, "exec"))
+ ot->exec= PYTHON_OT_exec;
+ if (PyObject_HasAttrString(py_class, "poll"))
+ ot->poll= PYTHON_OT_poll;
ot->pyop_data= userdata;
- /* inspect function keyword args to get properties */
- {
- PropertyRNA *prop;
-
- PyObject *var_names= PyObject_GetAttrString(PyFunction_GET_CODE(pyot->py_exec), "co_varnames");
- PyObject *var_vals = PyFunction_GET_DEFAULTS(pyot->py_exec);
- PyObject *py_val, *py_name;
+ props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
+
+ if (props) {
+ PyObject *dummy_args = PyTuple_New(0);
int i;
- char *name;
-
- if (PyTuple_Size(var_names) != PyTuple_Size(var_vals)) {
- printf("All args must be keywords");
- }
-
- for(i=0; i<PyTuple_Size(var_names); i++) {
- py_name = PyTuple_GetItem(var_names, i);
- name = _PyUnicode_AsString(py_name);
- py_val = PyTuple_GetItem(var_vals, i);
-
- if (PyBool_Check(py_val)) {
- prop = RNA_def_property(ot->srna, name, PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_default(prop, PyObject_IsTrue(py_val));
- }
- else if (PyLong_Check(py_val)) {
- prop = RNA_def_property(ot->srna, name, PROP_INT, PROP_NONE);
- RNA_def_property_int_default(prop, (int)PyLong_AsSsize_t(py_val));
- }
- else if (PyFloat_Check(py_val)) {
- prop = RNA_def_property(ot->srna, name, PROP_FLOAT, PROP_NONE);
- RNA_def_property_float_default(prop, (float)PyFloat_AsDouble(py_val));
- }
- else if (PyUnicode_Check(py_val)) {
- /* WARNING - holding a reference to the string from py_val is
- * not ideal since we rely on python keeping it,
- * however we're also keeping a reference to this function
- * so it should be OK!. just be careful with changes */
- prop = RNA_def_property(ot->srna, name, PROP_STRING, PROP_NONE);
- RNA_def_property_string_default(prop, _PyUnicode_AsString(py_val));
- }
- else {
- printf("error, python function arg \"%s\" was not a bool, int, float or string type\n", name);
+
+ Py_DECREF(props);
+
+ for(i=0; i<PyList_Size(props); i++) {
+ PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
+ item = PyList_GET_ITEM(props, i);
+
+ if (PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
+
+ PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
+ pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
+ py_srna_cobject = PyCObject_FromVoidPtr(ot->srna, NULL);
+
+ py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
+ if (py_ret) {
+ Py_DECREF(py_ret);
+ } else {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ Py_DECREF(py_srna_cobject);
+
+ } else {
+ /* cant return NULL from here */ // XXX a bit ugly
+ PyErr_Print();
+ PyErr_Clear();
}
+
+ // expect a tuple with a CObject and a dict
}
+ Py_DECREF(dummy_args);
+ } else {
+ PyErr_Clear();
}
-
}
+
/* pyOperators - Operators defined IN Python */
-PyObject *PYOP_wrap_add(PyObject *self, PyObject *args)
-{
+PyObject *PYOP_wrap_add(PyObject *self, PyObject *value)
+{
+ PyObject *optype, *item;
+
PyOperatorType *pyot;
-
char *idname= NULL;
char *name= NULL;
char *description= NULL;
- PyObject *invoke= NULL;
- PyObject *exec= NULL;
+
+ static char *pyop_func_names[] = {"exec", "invoke", "poll", NULL};
+ static int pyop_func_nargs[] = {1, 2, 2, 0};
+
+ PyObject *pyargcount;
+ int i, argcount;
+
+
+ // in python would be...
+ //PyObject *optype = PyObject_GetAttrString(PyObject_GetAttrString(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), "types"), "Operator");
+ optype = PyObject_GetAttrStringArgs(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), 2, "types", "Operator");
+ Py_DECREF(optype);
- if (!PyArg_ParseTuple(args, "sssOO", &idname, &name, &description, &invoke, &exec)) {
- PyErr_SetString( PyExc_AttributeError, "expected 2 strings and 2 function objects");
+
+ if (!PyObject_IsSubclass(value, optype)) {
+ PyErr_SetString( PyExc_AttributeError, "expected Operator subclass of bpy.types.Operator");
return NULL;
}
-
+
+ /* class name is used for operator ID - this can be changed later if we want */
+ item = PyObject_GetAttrString(value, PYOP_ATTR_IDNAME);
+ Py_DECREF(item);
+ idname = _PyUnicode_AsString(item);
+
+
if (WM_operatortype_find(idname)) {
- PyErr_Format( PyExc_AttributeError, "First argument \"%s\" operator alredy exists with this name", idname);
+ PyErr_Format( PyExc_AttributeError, "Operator alredy exists with this name \"%s\"", idname);
return NULL;
}
-
- if (((PyFunction_Check(invoke) || invoke==Py_None) && PyFunction_Check(exec)) == 0) {
- PyErr_SetString( PyExc_AttributeError, "the 2nd arg must be a function or None, the secons must be a function");
- return NULL;
+
+ /* Operator user readible name */
+ item = PyObject_GetAttrString(value, PYOP_ATTR_UINAME);
+ if (item) {
+ Py_DECREF(item);
+ name = _PyUnicode_AsString(item);
+ }
+ if (name == NULL) {
+ name = idname;
+ PyErr_Clear();
+ }
+
+ /* use py docstring for description, should always be None or a string */
+ item = PyObject_GetAttrString(value, PYOP_ATTR_DESCRIPTION);
+ Py_DECREF(item);
+
+ if (PyUnicode_Check(item)) {
+ description = _PyUnicode_AsString(item);
+ }
+ else {
+ description = "";
}
+
+ /* Check known functions and argument lengths */
+ for (i=0; pyop_func_names[i]; i++) {
+
+ item=PyObject_GetAttrString(value, pyop_func_names[i]);
+ if (item) {
+ Py_DECREF(item);
+
+ /* check its callable */
+ if (!PyFunction_Check(item)) {
+ PyErr_Format(PyExc_ValueError, "Cant register operator class - %s.%s() is not a function", idname, pyop_func_names[i]);
+ return NULL;
+ }
+ /* check the number of args is correct */
+ /* MyClass.exec.func_code.co_argcount */
+
+ pyargcount = PyObject_GetAttrString(PyFunction_GET_CODE(item), "co_argcount");
+ Py_DECREF(pyargcount);
+ argcount = PyLong_AsSsize_t(pyargcount);
+
+ if (argcount != pyop_func_nargs[i]) {
+ PyErr_Format(PyExc_ValueError, "Cant register operator class - %s.%s() takes %d args, should be %d", idname, pyop_func_names[i], argcount, pyop_func_nargs[i]);
+ return NULL;
+ }
+
+ } else {
+ PyErr_Clear();
+ }
+ }
+
+ /* If we have properties set, check its a list of dicts */
+ item = PyObject_GetAttrString(value, PYOP_ATTR_PROP);
+ if (item) {
+ Py_DECREF(item);
+ if (!PyList_Check(item)) {
+ PyErr_Format(PyExc_ValueError, "Cant register operator class - %s.properties must be a list", idname);
+ return NULL;
+ }
+
+ for(i=0; i<PyList_Size(item); i++) {
+ PyObject *py_args = PyList_GET_ITEM(item, i);
+ PyObject *py_func_ptr, *py_kw; /* place holders */
+
+ if (!PyArg_ParseTuple(py_args, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
+ PyErr_Format(PyExc_ValueError, "Cant register operator class - %s.properties must contain values from FloatProperty", idname);
+ return NULL;
+ }
+ }
+ }
+ else {
+ PyErr_Clear();
+ }
+
pyot= MEM_callocN(sizeof(PyOperatorType), "PyOperatorType");
strncpy(pyot->idname, idname, sizeof(pyot->idname));
strncpy(pyot->name, name, sizeof(pyot->name));
strncpy(pyot->description, description, sizeof(pyot->description));
- pyot->py_invoke= invoke;
- pyot->py_exec= exec;
- Py_INCREF(invoke);
- Py_INCREF(exec);
+ pyot->py_class= value;
+ Py_INCREF(value);
WM_operatortype_append_ptr(PYTHON_OT_wrapper, pyot);
Py_RETURN_NONE;
}
-PyObject *PYOP_wrap_remove(PyObject *self, PyObject *args)
+PyObject *PYOP_wrap_remove(PyObject *self, PyObject *value)
{
char *idname= NULL;
wmOperatorType *ot;
PyOperatorType *pyot;
- if (!PyArg_ParseTuple(args, "s", &idname))
+ if (PyUnicode_Check(value))
+ idname = _PyUnicode_AsString(value);
+ else if (PyCFunction_Check(value)) {
+ PyObject *cfunc_self = PyCFunction_GetSelf(value);
+ if (cfunc_self)
+ idname = _PyUnicode_AsString(cfunc_self);
+ }
+
+ if (idname==NULL) {
+ PyErr_SetString( PyExc_ValueError, "Expected the operator name as a string or the operator function");
return NULL;
+ }
if (!(ot= WM_operatortype_find(idname))) {
PyErr_Format( PyExc_AttributeError, "Operator \"%s\" does not exists, cant remove", idname);
@@ -397,8 +519,7 @@ PyObject *PYOP_wrap_remove(PyObject *self, PyObject *args)
return NULL;
}
- Py_XDECREF(pyot->py_invoke);
- Py_XDECREF(pyot->py_exec);
+ Py_XDECREF(pyot->py_class);
MEM_freeN(pyot);
WM_operatortype_remove(idname);
@@ -406,3 +527,5 @@ PyObject *PYOP_wrap_remove(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+
+
diff --git a/source/blender/python/intern/bpy_opwrapper.h b/source/blender/python/intern/bpy_opwrapper.h
index ae607735498..04120a81517 100644
--- a/source/blender/python/intern/bpy_opwrapper.h
+++ b/source/blender/python/intern/bpy_opwrapper.h
@@ -32,10 +32,3 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *args);
PyObject *PYOP_wrap_remove(PyObject *self, PyObject *args);
#endif
-
-
-
-
-
-
-
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index c4ba79d8373..23eed552a2a 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -26,13 +26,15 @@
#include "bpy_compat.h"
//#include "blendef.h"
#include "BLI_dynstr.h"
+#include "BLI_listbase.h"
+#include "float.h" /* FLT_MIN/MAX */
+
+#include "RNA_define.h" /* for defining our own rna */
#include "MEM_guardedalloc.h"
+#include "BKE_context.h"
#include "BKE_global.h" /* evil G.* */
-/* floats bigger then this are displayed as inf in the docstrings */
-#define MAXFLOAT_DOC 10000000
-
static int pyrna_struct_compare( BPy_StructRNA * a, BPy_StructRNA * b )
{
return (a->ptr.data==b->ptr.data) ? 0 : -1;
@@ -68,12 +70,39 @@ static PyObject *pyrna_prop_richcmp(BPy_PropertyRNA * a, BPy_PropertyRNA * b, in
/*----------------------repr--------------------------------------------*/
static PyObject *pyrna_struct_repr( BPy_StructRNA * self )
{
+ PropertyRNA *prop;
+ char str[512];
+
+ /* print name if available */
+ prop= RNA_struct_name_property(&self->ptr);
+ if(prop) {
+ RNA_property_string_get(&self->ptr, prop, str);
+ return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(&self->ptr), str);
+ }
+
return PyUnicode_FromFormat( "[BPy_StructRNA \"%s\"]", RNA_struct_identifier(&self->ptr));
}
static PyObject *pyrna_prop_repr( BPy_PropertyRNA * self )
{
- return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\" ]", RNA_struct_identifier(&self->ptr), RNA_property_identifier(&self->ptr, self->prop) );
+ PropertyRNA *prop;
+ PointerRNA ptr;
+ char str[512];
+
+ /* if a pointer, try to print name of pointer target too */
+ if(RNA_property_type(&self->ptr, self->prop) == PROP_POINTER) {
+ ptr= RNA_property_pointer_get(&self->ptr, self->prop);
+
+ if(ptr.data) {
+ prop= RNA_struct_name_property(&ptr);
+ if(prop) {
+ RNA_property_string_get(&ptr, prop, str);
+ return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\" -> \"%s\" ]", RNA_struct_identifier(&self->ptr), RNA_property_identifier(&self->ptr, self->prop), str);
+ }
+ }
+ }
+
+ return PyUnicode_FromFormat( "[BPy_PropertyRNA \"%s\" -> \"%s\"]", RNA_struct_identifier(&self->ptr), RNA_property_identifier(&self->ptr, self->prop));
}
static long pyrna_struct_hash( BPy_StructRNA * self )
@@ -91,7 +120,7 @@ static void pyrna_struct_dealloc( BPy_StructRNA * self )
self->ptr.data= NULL;
}
- ((PyObject *)self)->ob_type->tp_free(self);
+ Py_TYPE(self)->tp_free(self);
return;
}
@@ -132,7 +161,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
ret = PyBool_FromLong( RNA_property_boolean_get(ptr, prop) );
break;
case PROP_INT:
- ret = PyLong_FromSize_t( (size_t)RNA_property_int_get(ptr, prop) );
+ ret = PyLong_FromSsize_t( (Py_ssize_t)RNA_property_int_get(ptr, prop) );
break;
case PROP_FLOAT:
ret = PyFloat_FromDouble( RNA_property_float_get(ptr, prop) );
@@ -348,8 +377,25 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
}
case PROP_POINTER:
{
- PyErr_SetString(PyExc_AttributeError, "cant assign pointers yet");
- return -1;
+ StructRNA *ptype= RNA_property_pointer_type(ptr, prop);
+
+ if(!BPy_StructRNA_Check(value)) {
+ PointerRNA tmp;
+ RNA_pointer_create(NULL, ptype, NULL, &tmp);
+ PyErr_Format(PyExc_TypeError, "expected a %s type", RNA_struct_identifier(&tmp));
+ return -1;
+ } else {
+ BPy_StructRNA *param= (BPy_StructRNA*)value;
+
+ if(RNA_struct_is_a(&param->ptr, ptype)) {
+ RNA_property_pointer_set(ptr, prop, param->ptr);
+ } else {
+ PointerRNA tmp;
+ RNA_pointer_create(NULL, ptype, NULL, &tmp);
+ PyErr_Format(PyExc_TypeError, "expected a %s type", RNA_struct_identifier(&tmp));
+ return -1;
+ }
+ }
break;
}
case PROP_COLLECTION:
@@ -378,7 +424,7 @@ static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int
ret = PyBool_FromLong( RNA_property_boolean_get_index(ptr, prop, index) );
break;
case PROP_INT:
- ret = PyLong_FromSize_t( (size_t)RNA_property_int_get_index(ptr, prop, index) );
+ ret = PyLong_FromSsize_t( (Py_ssize_t)RNA_property_int_get_index(ptr, prop, index) );
break;
case PROP_FLOAT:
ret = PyFloat_FromDouble( RNA_property_float_get_index(ptr, prop, index) );
@@ -519,7 +565,7 @@ static int pyrna_prop_assign_subscript( BPy_PropertyRNA * self, PyObject *key, P
char *keyname = NULL;
if (!RNA_property_editable(&self->ptr, self->prop)) {
- PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(&self->ptr, self->prop), RNA_struct_identifier(&self->ptr) );
+ PyErr_Format( PyExc_AttributeError, "PropertyRNA - attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(&self->ptr, self->prop), RNA_struct_identifier(&self->ptr) );
return -1;
}
@@ -528,26 +574,26 @@ static int pyrna_prop_assign_subscript( BPy_PropertyRNA * self, PyObject *key, P
} else if (PyLong_Check(key)) {
keynum = PyLong_AsSsize_t(key);
} else {
- PyErr_SetString(PyExc_AttributeError, "invalid key, key must be a string or an int");
+ PyErr_SetString(PyExc_AttributeError, "PropertyRNA - invalid key, key must be a string or an int");
return -1;
}
if (RNA_property_type(&self->ptr, self->prop) == PROP_COLLECTION) {
- PyErr_SetString(PyExc_AttributeError, "assignment is not supported for collections (yet)");
+ PyErr_SetString(PyExc_AttributeError, "PropertyRNA - assignment is not supported for collections (yet)");
ret = -1;
} else if (keyname) {
- PyErr_SetString(PyExc_AttributeError, "string keys are only supported for collections");
+ PyErr_SetString(PyExc_AttributeError, "PropertyRNA - string keys are only supported for collections");
ret = -1;
} else {
int len = RNA_property_array_length(&self->ptr, self->prop);
if (len==0) { /* not an array*/
- PyErr_Format(PyExc_AttributeError, "not an array or collection %d", keynum);
+ PyErr_Format(PyExc_AttributeError, "PropertyRNA - not an array or collection %d", keynum);
ret = -1;
}
if (keynum >= len){
- PyErr_SetString(PyExc_AttributeError, "index out of range");
+ PyErr_SetString(PyExc_AttributeError, "PropertyRNA - index out of range");
ret = -1;
} else {
ret = pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value);
@@ -565,27 +611,34 @@ static PyMappingMethods pyrna_prop_as_mapping = {
( objobjargproc ) pyrna_prop_assign_subscript, /* mp_ass_subscript */
};
-//---------------getattr--------------------------------------------
-static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
+static PyObject *pyrna_struct_dir(BPy_StructRNA * self)
{
- char *name = _PyUnicode_AsString(pyname);
- PyObject *ret;
- PropertyRNA *prop;
+ PyObject *ret, *dict;
+ PyObject *pystring;
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
* */
- ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
- if (ret) return ret;
- else PyErr_Clear();
- /* done with subtypes */
- prop = RNA_struct_find_property(&self->ptr, name);
-
- if (prop) {
- ret = pyrna_prop_to_py(&self->ptr, prop);
+ if (BPy_StructRNA_CheckExact(self)) {
+ ret = PyList_New(0);
+ } else {
+ pystring = PyUnicode_FromString("__dict__");
+ dict = PyObject_GenericGetAttr((PyObject *)self, pystring);
+ Py_DECREF(pystring);
+
+ if (dict==NULL) {
+ PyErr_Clear();
+ ret = PyList_New(0);
+ }
+ else {
+ ret = PyDict_Keys(dict);
+ Py_DECREF(dict);
+ }
}
- else if (strcmp(name, "__dict__")==0) { /* Not quite correct, adding this so dir() gives good feedback */
+
+ /* Collect RNA items*/
+ {
PropertyRNA *iterprop, *nameprop;
CollectionPropertyIterator iter;
char name[256], *nameptr;
@@ -593,11 +646,13 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
iterprop= RNA_struct_iterator_property(&self->ptr);
RNA_property_collection_begin(&self->ptr, iterprop, &iter);
- ret = PyDict_New();
for(; iter.valid; RNA_property_collection_next(&iter)) {
if(iter.ptr.data && (nameprop = RNA_struct_name_property(&iter.ptr))) {
nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
- PyDict_SetItemString(ret, nameptr, Py_None);
+
+ pystring = PyUnicode_FromString(nameptr);
+ PyList_Append(ret, pystring);
+ Py_DECREF(pystring);
if ((char *)&name != nameptr)
MEM_freeN(nameptr);
@@ -606,8 +661,63 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
RNA_property_collection_end(&iter);
}
+
+ return ret;
+}
+
+
+//---------------getattr--------------------------------------------
+static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
+{
+ char *name = _PyUnicode_AsString(pyname);
+ PyObject *ret;
+ PropertyRNA *prop;
+
+ /* Include this incase this instance is a subtype of a python class
+ * In these instances we may want to return a function or variable provided by the subtype
+ *
+ * Also needed to return methods when its not a subtype
+ * */
+ ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
+ if (ret) return ret;
+ else PyErr_Clear();
+ /* done with subtypes */
+
+ prop = RNA_struct_find_property(&self->ptr, name);
+
+ if (prop) {
+ ret = pyrna_prop_to_py(&self->ptr, prop);
+ }
+ else if (/*self->ptr.type == &RNA_Context*/0) {
+ PointerRNA newptr;
+ ListBase newlb;
+
+ CTX_data_get(self->ptr.data, name, &newptr, &newlb);
+
+ if (newptr.data) {
+ ret = pyrna_struct_CreatePyObject(&newptr);
+ }
+ else if (newlb.first) {
+ CollectionPointerLink *link;
+ PyObject *linkptr;
+
+ ret = PyList_New(0);
+
+ for(link=newlb.first; link; link=link->next) {
+ linkptr= pyrna_struct_CreatePyObject(&link->ptr);
+ PyList_Append(ret, linkptr);
+ Py_DECREF(linkptr);
+ }
+ }
+ else {
+ ret = Py_None;
+ Py_INCREF(ret);
+ }
+
+ BLI_freelistN(&newlb);
+ }
else {
- PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name);
+ PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%s\" not found", name);
ret = NULL;
}
@@ -621,12 +731,17 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje
PropertyRNA *prop = RNA_struct_find_property(&self->ptr, name);
if (prop==NULL) {
- PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name);
- return -1;
+ if (!BPy_StructRNA_CheckExact(self) && PyObject_GenericSetAttr((PyObject *)self, pyname, value) >= 0) {
+ return 0;
+ }
+ else {
+ PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%s\" not found", name);
+ return -1;
+ }
}
if (!RNA_property_editable(&self->ptr, prop)) {
- PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(&self->ptr, prop), RNA_struct_identifier(&self->ptr) );
+ PyErr_Format( PyExc_AttributeError, "StructRNA - Attribute \"%s\" from \"%s\" is read-only", RNA_property_identifier(&self->ptr, prop), RNA_struct_identifier(&self->ptr) );
return -1;
}
@@ -765,10 +880,10 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
return NULL;
}
-/*static struct PyMethodDef pyrna_struct_methods[] = {
+static struct PyMethodDef pyrna_struct_methods[] = {
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, ""},
{NULL, NULL, 0, NULL}
-};*/
+};
static struct PyMethodDef pyrna_prop_methods[] = {
{"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, ""},
@@ -875,7 +990,7 @@ PyTypeObject pyrna_struct_Type = {
NULL, /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
- NULL, /* struct PyMethodDef *tp_methods; */
+ pyrna_struct_methods, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
NULL, /* struct PyGetSetDef *tp_getset; */
NULL, /* struct _typeobject *tp_base; */
@@ -985,17 +1100,101 @@ PyTypeObject pyrna_prop_Type = {
NULL
};
+PyObject* pyrna_struct_Subtype(PointerRNA *ptr)
+{
+ PyObject *newclass = NULL;
+ PropertyRNA *nameprop;
+
+ if (ptr->type==NULL) {
+ newclass= NULL; /* Nothing to do */
+ } else if ((newclass= (PyObject *)BPy_RNA_PYTYPE(ptr->data))) {
+ Py_INCREF(newclass);
+ } else if ((nameprop = RNA_struct_name_property(ptr))) {
+ /* for now, return the base RNA type rather then a real module */
+
+ /* Assume BPy_RNA_PYTYPE(ptr->data) was alredy checked */
+
+ /* subclass equivelents
+ - class myClass(myBase):
+ some='value' # or ...
+ - myClass = type(name='myClass', bases=(myBase,), dict={'some':'value'})
+ */
+ char name[256], *nameptr;
+
+ PyObject *args = PyTuple_New(3);
+ PyObject *bases = PyTuple_New(1);
+ PyObject *dict = PyDict_New();
+
+ nameptr= RNA_property_string_get_alloc(ptr, nameprop, name, sizeof(name));
+
+ // arg 1
+ //PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(tp_name));
+ PyTuple_SET_ITEM(args, 0, PyUnicode_FromString(nameptr));
+
+ // arg 2
+ PyTuple_SET_ITEM(bases, 0, (PyObject *)&pyrna_struct_Type);
+ Py_INCREF(&pyrna_struct_Type);
+
+ PyTuple_SET_ITEM(args, 1, bases);
+
+ // arg 3 - add an instance of the rna
+ PyTuple_SET_ITEM(args, 2, dict); // fill with useful subclass things!
+
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ newclass = PyObject_CallObject((PyObject *)&PyType_Type, args);
+ // Set this later
+
+
+ if (newclass) {
+ PyObject *rna;
+ BPy_RNA_PYTYPE(ptr->data) = (void *)newclass; /* Store for later use */
+
+ /* Not 100% needed but useful,
+ * having an instance within a type looks wrong however this instance IS an rna type */
+ rna = pyrna_struct_CreatePyObject(ptr);
+ PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", rna);
+ Py_DECREF(rna);
+ /* done with rna instance */
+ }
+
+ Py_DECREF(args);
+
+ if ((char *)&name != nameptr)
+ MEM_freeN(nameptr);
+
+ }
+
+ return newclass;
+}
+
/*-----------------------CreatePyObject---------------------------------*/
PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
{
- BPy_StructRNA *pyrna;
+ BPy_StructRNA *pyrna= NULL;
- if (ptr->data==NULL) {
+ if (ptr->data==NULL && ptr->type==NULL) { /* Operator RNA has NULL data */
Py_RETURN_NONE;
}
-
- pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
-
+
+ if (ptr->type == &RNA_Struct) { /* always return a python subtype from rna struct types */
+ PyTypeObject *tp = (PyTypeObject *)pyrna_struct_Subtype(ptr);
+
+ if (tp) {
+ pyrna = (BPy_StructRNA *) tp->tp_alloc(tp, 0);
+ }
+ else {
+ fprintf(stderr, "Could not make type\n");
+ pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
+ }
+ }
+ else {
+ pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
+ }
+
if( !pyrna ) {
PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_StructRNA object" );
return NULL;
@@ -1003,7 +1202,6 @@ PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
pyrna->ptr= *ptr;
pyrna->freeptr= 0;
-
return ( PyObject * ) pyrna;
}
@@ -1029,23 +1227,24 @@ PyObject *BPY_rna_module( void )
{
PointerRNA ptr;
- if( PyType_Ready( &pyrna_struct_Type ) < 0 )
- return NULL;
-
/* This can't be set in the pytype struct because some compilers complain */
pyrna_prop_Type.tp_getattro = PyObject_GenericGetAttr;
pyrna_prop_Type.tp_setattro = PyObject_GenericSetAttr;
+ if( PyType_Ready( &pyrna_struct_Type ) < 0 )
+ return NULL;
+
if( PyType_Ready( &pyrna_prop_Type ) < 0 )
return NULL;
+
/* for now, return the base RNA type rather then a real module */
RNA_main_pointer_create(G.main, &ptr);
- //submodule = Py_InitModule3( "rna", M_rna_methods, "rna module" );
return pyrna_struct_CreatePyObject(&ptr);
}
+#if 0
/* This is a way we can access docstrings for RNA types
* without having the datatypes in blender */
PyObject *BPY_rna_doc( void )
@@ -1057,5 +1256,158 @@ PyObject *BPY_rna_doc( void )
return pyrna_struct_CreatePyObject(&ptr);
}
+#endif
+
+
+/* pyrna_basetype_* - BPy_BaseTypeRNA is just a BPy_PropertyRNA struct with a differnt type
+ * the self->ptr and self->prop are always set to the "structs" collection */
+//---------------getattr--------------------------------------------
+static PyObject *pyrna_basetype_getattro( BPy_BaseTypeRNA * self, PyObject *pyname )
+{
+ PointerRNA newptr;
+ PyObject *ret;
+
+ ret = PyObject_GenericGetAttr((PyObject *)self, pyname);
+ if (ret) return ret;
+ else PyErr_Clear();
+
+ if (RNA_property_collection_lookup_string(&self->ptr, self->prop, _PyUnicode_AsString(pyname), &newptr)) {
+ return pyrna_struct_Subtype(&newptr);
+ }
+ else { /* Override the error */
+ PyErr_Format(PyExc_AttributeError, "bpy.types.%s not a valid RNA_Struct", _PyUnicode_AsString(pyname));
+ return NULL;
+ }
+}
+
+static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self);
+static struct PyMethodDef pyrna_basetype_methods[] = {
+ {"__dir__", (PyCFunction)pyrna_basetype_dir, METH_NOARGS, ""},
+ {NULL, NULL, 0, NULL}
+};
+
+static PyObject *pyrna_basetype_dir(BPy_BaseTypeRNA *self)
+{
+ PyObject *list, *name;
+ PyMethodDef *meth;
+
+ list= pyrna_prop_keys(self); /* like calling structs.keys(), avoids looping here */
+
+ for(meth=pyrna_basetype_methods; meth->ml_name; meth++) {
+ name = PyUnicode_FromString(meth->ml_name);
+ PyList_Append(list, name);
+ Py_DECREF(name);
+ }
+
+ return list;
+}
+
+PyTypeObject pyrna_basetype_Type = {NULL};
+
+PyObject *BPY_rna_types(void)
+{
+ BPy_BaseTypeRNA *self;
+ pyrna_basetype_Type.tp_name = "RNA_Types";
+ pyrna_basetype_Type.tp_basicsize = sizeof( BPy_BaseTypeRNA );
+ pyrna_basetype_Type.tp_getattro = ( getattrofunc )pyrna_basetype_getattro;
+ pyrna_basetype_Type.tp_flags = Py_TPFLAGS_DEFAULT;
+ pyrna_basetype_Type.tp_methods = pyrna_basetype_methods;
+
+ if( PyType_Ready( &pyrna_basetype_Type ) < 0 )
+ return NULL;
+
+ self= (BPy_BaseTypeRNA *)PyObject_NEW( BPy_BaseTypeRNA, &pyrna_basetype_Type );
+
+ /* avoid doing this lookup for every getattr */
+ RNA_blender_rna_pointer_create(&self->ptr);
+ self->prop = RNA_struct_find_property(&self->ptr, "structs");
+
+ return (PyObject *)self;
+}
+
+/* Orphan functions, not sure where they should go */
+
+/* Function that sets RNA, NOTE - self is NULL when called from python, but being abused from C so we can pass the srna allong
+ * This isnt incorrect since its a python object - but be careful */
+PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
+{
+ static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
+ char *id, *name="", *description="";
+ float min=FLT_MIN, max=FLT_MAX, soft_min=FLT_MIN, soft_max=FLT_MAX, def=0.0f;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssfffff:FloatProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
+ return NULL;
+
+ if (PyTuple_Size(args) > 0) {
+ PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
+ return NULL;
+ }
+
+ if (self) {
+ StructRNA *srna = PyCObject_AsVoidPtr(self);
+ RNA_def_float(srna, id, def, min, max, name, description, soft_min, soft_max);
+ Py_RETURN_NONE;
+ } else {
+ PyObject *ret = PyTuple_New(2);
+ PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_FloatProperty, NULL));
+ PyTuple_SET_ITEM(ret, 1, kw);
+ Py_INCREF(kw);
+ return ret;
+ }
+}
+
+PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
+{
+ static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
+ char *id, *name="", *description="";
+ int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, def=0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssiiiii:IntProperty", kwlist, &id, &name, &description, &min, &max, &soft_min, &soft_max, &def))
+ return NULL;
+
+ if (PyTuple_Size(args) > 0) {
+ PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
+ return NULL;
+ }
+
+ if (self) {
+ StructRNA *srna = PyCObject_AsVoidPtr(self);
+ RNA_def_int(srna, id, def, min, max, name, description, soft_min, soft_max);
+ Py_RETURN_NONE;
+ } else {
+ PyObject *ret = PyTuple_New(2);
+ PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_IntProperty, NULL));
+ PyTuple_SET_ITEM(ret, 1, kw);
+ Py_INCREF(kw);
+ return ret;
+ }
+}
+
+PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
+{
+ static char *kwlist[] = {"attr", "name", "description", "default", NULL};
+ char *id, *name="", *description="";
+ int def=0;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ssi:IntProperty", kwlist, &id, &name, &description, &def))
+ return NULL;
+
+ if (PyTuple_Size(args) > 0) {
+ PyErr_SetString(PyExc_ValueError, "all args must be keywors"); // TODO - py3 can enforce this.
+ return NULL;
+ }
+
+ if (self) {
+ StructRNA *srna = PyCObject_AsVoidPtr(self);
+ RNA_def_boolean(srna, id, def, name, description);
+ Py_RETURN_NONE;
+ } else {
+ PyObject *ret = PyTuple_New(2);
+ PyTuple_SET_ITEM(ret, 0, PyCObject_FromVoidPtr((void *)BPy_IntProperty, NULL));
+ PyTuple_SET_ITEM(ret, 1, kw);
+ Py_INCREF(kw);
+ return ret;
+ }
+}
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index fc16ad6ea9a..878b2a7d17a 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -33,8 +33,21 @@
extern PyTypeObject pyrna_struct_Type;
extern PyTypeObject pyrna_prop_Type;
-#define BPy_StructRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_struct_Type))
-#define BPy_PropertyRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_prop_Type))
+#define BPy_StructRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_struct_Type))
+#define BPy_StructRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_struct_Type)
+#define BPy_PropertyRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_prop_Type))
+#define BPy_PropertyRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_prop_Type)
+
+ //XXX add propper accessor function, we know this is just after next/prev pointers
+
+ #define BPy_RNA_PYTYPE( _data ) (((BPy_StructFakeType *)(_data))->py_type)
+
+typedef struct {
+ void * _a;
+ void * _b;
+ PyTypeObject *py_type;
+} BPy_StructFakeType;
+
typedef struct {
PyObject_HEAD /* required python macro */
@@ -48,8 +61,12 @@ typedef struct {
PropertyRNA *prop;
} BPy_PropertyRNA;
+/* cheap trick */
+#define BPy_BaseTypeRNA BPy_PropertyRNA
+
PyObject *BPY_rna_module( void );
-PyObject *BPY_rna_doc( void );
+/*PyObject *BPY_rna_doc( void );*/
+PyObject *BPY_rna_types( void );
PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr );
PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop );
@@ -57,4 +74,11 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop );
/* operators also need this to set args */
int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, PyObject *value);
PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop);
+
+/* functions for setting up new props - experemental */
+PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw);
+PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw);
+PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw);
+
+
#endif
diff --git a/source/blender/python/intern/bpy_ui.c b/source/blender/python/intern/bpy_ui.c
index 82d48b1dcda..7b3b4c01c55 100644
--- a/source/blender/python/intern/bpy_ui.c
+++ b/source/blender/python/intern/bpy_ui.c
@@ -115,7 +115,7 @@ static PyObject *Method_defAutoButR( PyObject * self, PyObject * args )
return NULL;
}
- return PyCObject_FromVoidPtr( uiDefAutoButR(PyCObject_AsVoidPtr(py_block), &py_rna->ptr, prop, index, butname, xco, yco, width, height), NULL);
+ return PyCObject_FromVoidPtr( uiDefAutoButR(PyCObject_AsVoidPtr(py_block), &py_rna->ptr, prop, index, butname, 0, xco, yco, width, height), NULL);
}
@@ -267,7 +267,7 @@ static PyObject *Method_newPanel( PyObject * self, PyObject * args )
if( !PyArg_ParseTuple( args, "O!O!O!ssiiii:newPanel", &PyCObject_Type, &py_context, &PyCObject_Type, &py_area, &PyCObject_Type, &py_block, &panelname, &tabname, &ofsx, &ofsy, &sizex, &sizey))
return NULL;
- return PyLong_FromSize_t(uiNewPanel(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_area), PyCObject_AsVoidPtr(py_block), panelname, tabname, ofsx, ofsy, sizex, sizey));
+ return PyLong_FromSsize_t(uiNewPanel(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_area), PyCObject_AsVoidPtr(py_block), panelname, tabname, ofsx, ofsy, sizex, sizey));
}
/* similar to Draw.c */
@@ -418,7 +418,6 @@ static struct PyMethodDef ui_methods[] = {
{"registerKey", (PyCFunction)Method_registerKey, METH_VARARGS, ""}, // XXX could have this in another place too
-
{"getRegonPtr", (PyCFunction)Method_getRegonPtr, METH_NOARGS, ""}, // XXX Nasty, we really need to improve dealing with context!
{"getAreaPtr", (PyCFunction)Method_getAreaPtr, METH_NOARGS, ""},
{"getScreenPtr", (PyCFunction)Method_getScreenPtr, METH_NOARGS, ""},
@@ -450,171 +449,171 @@ PyObject *BPY_ui_module( void )
/* uiBlock->flag (controls) */
mod = PyModule_New("ui");
PyModule_AddObject( submodule, "ui", mod );
- PyModule_AddObject( mod, "BLOCK_LOOP", PyLong_FromSize_t(UI_BLOCK_LOOP) );
- PyModule_AddObject( mod, "BLOCK_RET_1", PyLong_FromSize_t(UI_BLOCK_RET_1) );
- PyModule_AddObject( mod, "BLOCK_NUMSELECT", PyLong_FromSize_t(UI_BLOCK_NUMSELECT) );
- PyModule_AddObject( mod, "BLOCK_ENTER_OK", PyLong_FromSize_t(UI_BLOCK_ENTER_OK) );
- PyModule_AddObject( mod, "BLOCK_NOSHADOW", PyLong_FromSize_t(UI_BLOCK_NOSHADOW) );
- PyModule_AddObject( mod, "BLOCK_NO_HILITE", PyLong_FromSize_t(UI_BLOCK_NO_HILITE) );
- PyModule_AddObject( mod, "BLOCK_MOVEMOUSE_QUIT", PyLong_FromSize_t(UI_BLOCK_MOVEMOUSE_QUIT) );
- PyModule_AddObject( mod, "BLOCK_KEEP_OPEN", PyLong_FromSize_t(UI_BLOCK_KEEP_OPEN) );
- PyModule_AddObject( mod, "BLOCK_POPUP", PyLong_FromSize_t(UI_BLOCK_POPUP) );
+ PyModule_AddObject( mod, "BLOCK_LOOP", PyLong_FromSsize_t(UI_BLOCK_LOOP) );
+ PyModule_AddObject( mod, "BLOCK_RET_1", PyLong_FromSsize_t(UI_BLOCK_RET_1) );
+ PyModule_AddObject( mod, "BLOCK_NUMSELECT", PyLong_FromSsize_t(UI_BLOCK_NUMSELECT) );
+ PyModule_AddObject( mod, "BLOCK_ENTER_OK", PyLong_FromSsize_t(UI_BLOCK_ENTER_OK) );
+ PyModule_AddObject( mod, "BLOCK_NOSHADOW", PyLong_FromSsize_t(UI_BLOCK_NOSHADOW) );
+ PyModule_AddObject( mod, "BLOCK_NO_HILITE", PyLong_FromSsize_t(UI_BLOCK_NO_HILITE) );
+ PyModule_AddObject( mod, "BLOCK_MOVEMOUSE_QUIT", PyLong_FromSsize_t(UI_BLOCK_MOVEMOUSE_QUIT) );
+ PyModule_AddObject( mod, "BLOCK_KEEP_OPEN", PyLong_FromSsize_t(UI_BLOCK_KEEP_OPEN) );
+ PyModule_AddObject( mod, "BLOCK_POPUP", PyLong_FromSsize_t(UI_BLOCK_POPUP) );
/* for executing operators (XXX move elsewhere) */
mod = PyModule_New("wmTypes");
PyModule_AddObject( submodule, "wmTypes", mod );
- PyModule_AddObject( mod, "OP_INVOKE_DEFAULT", PyLong_FromSize_t(WM_OP_INVOKE_DEFAULT) );
- PyModule_AddObject( mod, "OP_INVOKE_REGION_WIN", PyLong_FromSize_t(WM_OP_INVOKE_REGION_WIN) );
- PyModule_AddObject( mod, "OP_INVOKE_AREA", PyLong_FromSize_t(WM_OP_INVOKE_AREA) );
- PyModule_AddObject( mod, "OP_INVOKE_SCREEN", PyLong_FromSize_t(WM_OP_INVOKE_SCREEN) );
- PyModule_AddObject( mod, "OP_EXEC_DEFAULT", PyLong_FromSize_t(WM_OP_EXEC_DEFAULT) );
- PyModule_AddObject( mod, "OP_EXEC_REGION_WIN", PyLong_FromSize_t(WM_OP_EXEC_REGION_WIN) );
- PyModule_AddObject( mod, "OP_EXEC_AREA", PyLong_FromSize_t(WM_OP_EXEC_AREA) );
- PyModule_AddObject( mod, "OP_EXEC_SCREEN", PyLong_FromSize_t(WM_OP_EXEC_SCREEN) );
+ PyModule_AddObject( mod, "OP_INVOKE_DEFAULT", PyLong_FromSsize_t(WM_OP_INVOKE_DEFAULT) );
+ PyModule_AddObject( mod, "OP_INVOKE_REGION_WIN", PyLong_FromSsize_t(WM_OP_INVOKE_REGION_WIN) );
+ PyModule_AddObject( mod, "OP_INVOKE_AREA", PyLong_FromSsize_t(WM_OP_INVOKE_AREA) );
+ PyModule_AddObject( mod, "OP_INVOKE_SCREEN", PyLong_FromSsize_t(WM_OP_INVOKE_SCREEN) );
+ PyModule_AddObject( mod, "OP_EXEC_DEFAULT", PyLong_FromSsize_t(WM_OP_EXEC_DEFAULT) );
+ PyModule_AddObject( mod, "OP_EXEC_REGION_WIN", PyLong_FromSsize_t(WM_OP_EXEC_REGION_WIN) );
+ PyModule_AddObject( mod, "OP_EXEC_AREA", PyLong_FromSsize_t(WM_OP_EXEC_AREA) );
+ PyModule_AddObject( mod, "OP_EXEC_SCREEN", PyLong_FromSsize_t(WM_OP_EXEC_SCREEN) );
mod = PyModule_New("keyValTypes");
PyModule_AddObject( submodule, "keyValTypes", mod );
- PyModule_AddObject( mod, "ANY", PyLong_FromSize_t(KM_ANY) );
- PyModule_AddObject( mod, "NOTHING", PyLong_FromSize_t(KM_NOTHING) );
- PyModule_AddObject( mod, "PRESS", PyLong_FromSize_t(KM_PRESS) );
- PyModule_AddObject( mod, "RELEASE", PyLong_FromSize_t(KM_RELEASE) );
+ PyModule_AddObject( mod, "ANY", PyLong_FromSsize_t(KM_ANY) );
+ PyModule_AddObject( mod, "NOTHING", PyLong_FromSsize_t(KM_NOTHING) );
+ PyModule_AddObject( mod, "PRESS", PyLong_FromSsize_t(KM_PRESS) );
+ PyModule_AddObject( mod, "RELEASE", PyLong_FromSsize_t(KM_RELEASE) );
mod = PyModule_New("keyModTypes");
PyModule_AddObject( submodule, "keyModTypes", mod );
- PyModule_AddObject( mod, "SHIFT", PyLong_FromSize_t(KM_SHIFT) );
- PyModule_AddObject( mod, "CTRL", PyLong_FromSize_t(KM_CTRL) );
- PyModule_AddObject( mod, "ALT", PyLong_FromSize_t(KM_ALT) );
- PyModule_AddObject( mod, "OSKEY", PyLong_FromSize_t(KM_OSKEY) );
+ PyModule_AddObject( mod, "SHIFT", PyLong_FromSsize_t(KM_SHIFT) );
+ PyModule_AddObject( mod, "CTRL", PyLong_FromSsize_t(KM_CTRL) );
+ PyModule_AddObject( mod, "ALT", PyLong_FromSsize_t(KM_ALT) );
+ PyModule_AddObject( mod, "OSKEY", PyLong_FromSsize_t(KM_OSKEY) );
- PyModule_AddObject( mod, "SHIFT2", PyLong_FromSize_t(KM_SHIFT2) );
- PyModule_AddObject( mod, "CTRL2", PyLong_FromSize_t(KM_CTRL2) );
- PyModule_AddObject( mod, "ALT2", PyLong_FromSize_t(KM_ALT2) );
- PyModule_AddObject( mod, "OSKEY2", PyLong_FromSize_t(KM_OSKEY2) );
+ PyModule_AddObject( mod, "SHIFT2", PyLong_FromSsize_t(KM_SHIFT2) );
+ PyModule_AddObject( mod, "CTRL2", PyLong_FromSsize_t(KM_CTRL2) );
+ PyModule_AddObject( mod, "ALT2", PyLong_FromSsize_t(KM_ALT2) );
+ PyModule_AddObject( mod, "OSKEY2", PyLong_FromSsize_t(KM_OSKEY2) );
mod = PyModule_New("keyTypes");
PyModule_AddObject( submodule, "keyTypes", mod );
- PyModule_AddObject( mod, "A", PyLong_FromSize_t(AKEY) );
- PyModule_AddObject( mod, "B", PyLong_FromSize_t(BKEY) );
- PyModule_AddObject( mod, "C", PyLong_FromSize_t(CKEY) );
- PyModule_AddObject( mod, "D", PyLong_FromSize_t(DKEY) );
- PyModule_AddObject( mod, "E", PyLong_FromSize_t(EKEY) );
- PyModule_AddObject( mod, "F", PyLong_FromSize_t(FKEY) );
- PyModule_AddObject( mod, "G", PyLong_FromSize_t(GKEY) );
- PyModule_AddObject( mod, "H", PyLong_FromSize_t(HKEY) );
- PyModule_AddObject( mod, "I", PyLong_FromSize_t(IKEY) );
- PyModule_AddObject( mod, "J", PyLong_FromSize_t(JKEY) );
- PyModule_AddObject( mod, "K", PyLong_FromSize_t(KKEY) );
- PyModule_AddObject( mod, "L", PyLong_FromSize_t(LKEY) );
- PyModule_AddObject( mod, "M", PyLong_FromSize_t(MKEY) );
- PyModule_AddObject( mod, "N", PyLong_FromSize_t(NKEY) );
- PyModule_AddObject( mod, "O", PyLong_FromSize_t(OKEY) );
- PyModule_AddObject( mod, "P", PyLong_FromSize_t(PKEY) );
- PyModule_AddObject( mod, "Q", PyLong_FromSize_t(QKEY) );
- PyModule_AddObject( mod, "R", PyLong_FromSize_t(RKEY) );
- PyModule_AddObject( mod, "S", PyLong_FromSize_t(SKEY) );
- PyModule_AddObject( mod, "T", PyLong_FromSize_t(TKEY) );
- PyModule_AddObject( mod, "U", PyLong_FromSize_t(UKEY) );
- PyModule_AddObject( mod, "V", PyLong_FromSize_t(VKEY) );
- PyModule_AddObject( mod, "W", PyLong_FromSize_t(WKEY) );
- PyModule_AddObject( mod, "X", PyLong_FromSize_t(XKEY) );
- PyModule_AddObject( mod, "Y", PyLong_FromSize_t(YKEY) );
- PyModule_AddObject( mod, "Z", PyLong_FromSize_t(ZKEY) );
- PyModule_AddObject( mod, "ZERO", PyLong_FromSize_t(ZEROKEY) );
- PyModule_AddObject( mod, "ONE", PyLong_FromSize_t(ONEKEY) );
- PyModule_AddObject( mod, "TWO", PyLong_FromSize_t(TWOKEY) );
- PyModule_AddObject( mod, "THREE", PyLong_FromSize_t(THREEKEY) );
- PyModule_AddObject( mod, "FOUR", PyLong_FromSize_t(FOURKEY) );
- PyModule_AddObject( mod, "FIVE", PyLong_FromSize_t(FIVEKEY) );
- PyModule_AddObject( mod, "SIX", PyLong_FromSize_t(SIXKEY) );
- PyModule_AddObject( mod, "SEVEN", PyLong_FromSize_t(SEVENKEY) );
- PyModule_AddObject( mod, "EIGHT", PyLong_FromSize_t(EIGHTKEY) );
- PyModule_AddObject( mod, "NINE", PyLong_FromSize_t(NINEKEY) );
- PyModule_AddObject( mod, "CAPSLOCK", PyLong_FromSize_t(CAPSLOCKKEY) );
- PyModule_AddObject( mod, "LEFTCTRL", PyLong_FromSize_t(LEFTCTRLKEY) );
- PyModule_AddObject( mod, "LEFTALT", PyLong_FromSize_t(LEFTALTKEY) );
- PyModule_AddObject( mod, "RIGHTALT", PyLong_FromSize_t(RIGHTALTKEY) );
- PyModule_AddObject( mod, "RIGHTCTRL", PyLong_FromSize_t(RIGHTCTRLKEY) );
- PyModule_AddObject( mod, "RIGHTSHIFT", PyLong_FromSize_t(RIGHTSHIFTKEY) );
- PyModule_AddObject( mod, "LEFTSHIFT", PyLong_FromSize_t(LEFTSHIFTKEY) );
- PyModule_AddObject( mod, "ESC", PyLong_FromSize_t(ESCKEY) );
- PyModule_AddObject( mod, "TAB", PyLong_FromSize_t(TABKEY) );
- PyModule_AddObject( mod, "RET", PyLong_FromSize_t(RETKEY) );
- PyModule_AddObject( mod, "SPACE", PyLong_FromSize_t(SPACEKEY) );
- PyModule_AddObject( mod, "LINEFEED", PyLong_FromSize_t(LINEFEEDKEY) );
- PyModule_AddObject( mod, "BACKSPACE", PyLong_FromSize_t(BACKSPACEKEY) );
- PyModule_AddObject( mod, "DEL", PyLong_FromSize_t(DELKEY) );
- PyModule_AddObject( mod, "SEMICOLON", PyLong_FromSize_t(SEMICOLONKEY) );
- PyModule_AddObject( mod, "PERIOD", PyLong_FromSize_t(PERIODKEY) );
- PyModule_AddObject( mod, "COMMA", PyLong_FromSize_t(COMMAKEY) );
- PyModule_AddObject( mod, "QUOTE", PyLong_FromSize_t(QUOTEKEY) );
- PyModule_AddObject( mod, "ACCENTGRAVE", PyLong_FromSize_t(ACCENTGRAVEKEY) );
- PyModule_AddObject( mod, "MINUS", PyLong_FromSize_t(MINUSKEY) );
- PyModule_AddObject( mod, "SLASH", PyLong_FromSize_t(SLASHKEY) );
- PyModule_AddObject( mod, "BACKSLASH", PyLong_FromSize_t(BACKSLASHKEY) );
- PyModule_AddObject( mod, "EQUAL", PyLong_FromSize_t(EQUALKEY) );
- PyModule_AddObject( mod, "LEFTBRACKET", PyLong_FromSize_t(LEFTBRACKETKEY) );
- PyModule_AddObject( mod, "RIGHTBRACKET", PyLong_FromSize_t(RIGHTBRACKETKEY) );
- PyModule_AddObject( mod, "LEFTARROW", PyLong_FromSize_t(LEFTARROWKEY) );
- PyModule_AddObject( mod, "DOWNARROW", PyLong_FromSize_t(DOWNARROWKEY) );
- PyModule_AddObject( mod, "RIGHTARROW", PyLong_FromSize_t(RIGHTARROWKEY) );
- PyModule_AddObject( mod, "UPARROW", PyLong_FromSize_t(UPARROWKEY) );
- PyModule_AddObject( mod, "PAD0", PyLong_FromSize_t(PAD0) );
- PyModule_AddObject( mod, "PAD1", PyLong_FromSize_t(PAD1) );
- PyModule_AddObject( mod, "PAD2", PyLong_FromSize_t(PAD2) );
- PyModule_AddObject( mod, "PAD3", PyLong_FromSize_t(PAD3) );
- PyModule_AddObject( mod, "PAD4", PyLong_FromSize_t(PAD4) );
- PyModule_AddObject( mod, "PAD5", PyLong_FromSize_t(PAD5) );
- PyModule_AddObject( mod, "PAD6", PyLong_FromSize_t(PAD6) );
- PyModule_AddObject( mod, "PAD7", PyLong_FromSize_t(PAD7) );
- PyModule_AddObject( mod, "PAD8", PyLong_FromSize_t(PAD8) );
- PyModule_AddObject( mod, "PAD9", PyLong_FromSize_t(PAD9) );
- PyModule_AddObject( mod, "PADPERIOD", PyLong_FromSize_t(PADPERIOD) );
- PyModule_AddObject( mod, "PADSLASH", PyLong_FromSize_t(PADSLASHKEY) );
- PyModule_AddObject( mod, "PADASTER", PyLong_FromSize_t(PADASTERKEY) );
- PyModule_AddObject( mod, "PADMINUS", PyLong_FromSize_t(PADMINUS) );
- PyModule_AddObject( mod, "PADENTER", PyLong_FromSize_t(PADENTER) );
- PyModule_AddObject( mod, "PADPLUS", PyLong_FromSize_t(PADPLUSKEY) );
- PyModule_AddObject( mod, "F1", PyLong_FromSize_t(F1KEY) );
- PyModule_AddObject( mod, "F2", PyLong_FromSize_t(F2KEY) );
- PyModule_AddObject( mod, "F3", PyLong_FromSize_t(F3KEY) );
- PyModule_AddObject( mod, "F4", PyLong_FromSize_t(F4KEY) );
- PyModule_AddObject( mod, "F5", PyLong_FromSize_t(F5KEY) );
- PyModule_AddObject( mod, "F6", PyLong_FromSize_t(F6KEY) );
- PyModule_AddObject( mod, "F7", PyLong_FromSize_t(F7KEY) );
- PyModule_AddObject( mod, "F8", PyLong_FromSize_t(F8KEY) );
- PyModule_AddObject( mod, "F9", PyLong_FromSize_t(F9KEY) );
- PyModule_AddObject( mod, "F10", PyLong_FromSize_t(F10KEY) );
- PyModule_AddObject( mod, "F11", PyLong_FromSize_t(F11KEY) );
- PyModule_AddObject( mod, "F12", PyLong_FromSize_t(F12KEY) );
- PyModule_AddObject( mod, "PAUSE", PyLong_FromSize_t(PAUSEKEY) );
- PyModule_AddObject( mod, "INSERT", PyLong_FromSize_t(INSERTKEY) );
- PyModule_AddObject( mod, "HOME", PyLong_FromSize_t(HOMEKEY) );
- PyModule_AddObject( mod, "PAGEUP", PyLong_FromSize_t(PAGEUPKEY) );
- PyModule_AddObject( mod, "PAGEDOWN", PyLong_FromSize_t(PAGEDOWNKEY) );
- PyModule_AddObject( mod, "END", PyLong_FromSize_t(ENDKEY) );
- PyModule_AddObject( mod, "UNKNOWN", PyLong_FromSize_t(UNKNOWNKEY) );
- PyModule_AddObject( mod, "COMMAND", PyLong_FromSize_t(COMMANDKEY) );
- PyModule_AddObject( mod, "GRLESS", PyLong_FromSize_t(GRLESSKEY) );
+ PyModule_AddObject( mod, "A", PyLong_FromSsize_t(AKEY) );
+ PyModule_AddObject( mod, "B", PyLong_FromSsize_t(BKEY) );
+ PyModule_AddObject( mod, "C", PyLong_FromSsize_t(CKEY) );
+ PyModule_AddObject( mod, "D", PyLong_FromSsize_t(DKEY) );
+ PyModule_AddObject( mod, "E", PyLong_FromSsize_t(EKEY) );
+ PyModule_AddObject( mod, "F", PyLong_FromSsize_t(FKEY) );
+ PyModule_AddObject( mod, "G", PyLong_FromSsize_t(GKEY) );
+ PyModule_AddObject( mod, "H", PyLong_FromSsize_t(HKEY) );
+ PyModule_AddObject( mod, "I", PyLong_FromSsize_t(IKEY) );
+ PyModule_AddObject( mod, "J", PyLong_FromSsize_t(JKEY) );
+ PyModule_AddObject( mod, "K", PyLong_FromSsize_t(KKEY) );
+ PyModule_AddObject( mod, "L", PyLong_FromSsize_t(LKEY) );
+ PyModule_AddObject( mod, "M", PyLong_FromSsize_t(MKEY) );
+ PyModule_AddObject( mod, "N", PyLong_FromSsize_t(NKEY) );
+ PyModule_AddObject( mod, "O", PyLong_FromSsize_t(OKEY) );
+ PyModule_AddObject( mod, "P", PyLong_FromSsize_t(PKEY) );
+ PyModule_AddObject( mod, "Q", PyLong_FromSsize_t(QKEY) );
+ PyModule_AddObject( mod, "R", PyLong_FromSsize_t(RKEY) );
+ PyModule_AddObject( mod, "S", PyLong_FromSsize_t(SKEY) );
+ PyModule_AddObject( mod, "T", PyLong_FromSsize_t(TKEY) );
+ PyModule_AddObject( mod, "U", PyLong_FromSsize_t(UKEY) );
+ PyModule_AddObject( mod, "V", PyLong_FromSsize_t(VKEY) );
+ PyModule_AddObject( mod, "W", PyLong_FromSsize_t(WKEY) );
+ PyModule_AddObject( mod, "X", PyLong_FromSsize_t(XKEY) );
+ PyModule_AddObject( mod, "Y", PyLong_FromSsize_t(YKEY) );
+ PyModule_AddObject( mod, "Z", PyLong_FromSsize_t(ZKEY) );
+ PyModule_AddObject( mod, "ZERO", PyLong_FromSsize_t(ZEROKEY) );
+ PyModule_AddObject( mod, "ONE", PyLong_FromSsize_t(ONEKEY) );
+ PyModule_AddObject( mod, "TWO", PyLong_FromSsize_t(TWOKEY) );
+ PyModule_AddObject( mod, "THREE", PyLong_FromSsize_t(THREEKEY) );
+ PyModule_AddObject( mod, "FOUR", PyLong_FromSsize_t(FOURKEY) );
+ PyModule_AddObject( mod, "FIVE", PyLong_FromSsize_t(FIVEKEY) );
+ PyModule_AddObject( mod, "SIX", PyLong_FromSsize_t(SIXKEY) );
+ PyModule_AddObject( mod, "SEVEN", PyLong_FromSsize_t(SEVENKEY) );
+ PyModule_AddObject( mod, "EIGHT", PyLong_FromSsize_t(EIGHTKEY) );
+ PyModule_AddObject( mod, "NINE", PyLong_FromSsize_t(NINEKEY) );
+ PyModule_AddObject( mod, "CAPSLOCK", PyLong_FromSsize_t(CAPSLOCKKEY) );
+ PyModule_AddObject( mod, "LEFTCTRL", PyLong_FromSsize_t(LEFTCTRLKEY) );
+ PyModule_AddObject( mod, "LEFTALT", PyLong_FromSsize_t(LEFTALTKEY) );
+ PyModule_AddObject( mod, "RIGHTALT", PyLong_FromSsize_t(RIGHTALTKEY) );
+ PyModule_AddObject( mod, "RIGHTCTRL", PyLong_FromSsize_t(RIGHTCTRLKEY) );
+ PyModule_AddObject( mod, "RIGHTSHIFT", PyLong_FromSsize_t(RIGHTSHIFTKEY) );
+ PyModule_AddObject( mod, "LEFTSHIFT", PyLong_FromSsize_t(LEFTSHIFTKEY) );
+ PyModule_AddObject( mod, "ESC", PyLong_FromSsize_t(ESCKEY) );
+ PyModule_AddObject( mod, "TAB", PyLong_FromSsize_t(TABKEY) );
+ PyModule_AddObject( mod, "RET", PyLong_FromSsize_t(RETKEY) );
+ PyModule_AddObject( mod, "SPACE", PyLong_FromSsize_t(SPACEKEY) );
+ PyModule_AddObject( mod, "LINEFEED", PyLong_FromSsize_t(LINEFEEDKEY) );
+ PyModule_AddObject( mod, "BACKSPACE", PyLong_FromSsize_t(BACKSPACEKEY) );
+ PyModule_AddObject( mod, "DEL", PyLong_FromSsize_t(DELKEY) );
+ PyModule_AddObject( mod, "SEMICOLON", PyLong_FromSsize_t(SEMICOLONKEY) );
+ PyModule_AddObject( mod, "PERIOD", PyLong_FromSsize_t(PERIODKEY) );
+ PyModule_AddObject( mod, "COMMA", PyLong_FromSsize_t(COMMAKEY) );
+ PyModule_AddObject( mod, "QUOTE", PyLong_FromSsize_t(QUOTEKEY) );
+ PyModule_AddObject( mod, "ACCENTGRAVE", PyLong_FromSsize_t(ACCENTGRAVEKEY) );
+ PyModule_AddObject( mod, "MINUS", PyLong_FromSsize_t(MINUSKEY) );
+ PyModule_AddObject( mod, "SLASH", PyLong_FromSsize_t(SLASHKEY) );
+ PyModule_AddObject( mod, "BACKSLASH", PyLong_FromSsize_t(BACKSLASHKEY) );
+ PyModule_AddObject( mod, "EQUAL", PyLong_FromSsize_t(EQUALKEY) );
+ PyModule_AddObject( mod, "LEFTBRACKET", PyLong_FromSsize_t(LEFTBRACKETKEY) );
+ PyModule_AddObject( mod, "RIGHTBRACKET", PyLong_FromSsize_t(RIGHTBRACKETKEY) );
+ PyModule_AddObject( mod, "LEFTARROW", PyLong_FromSsize_t(LEFTARROWKEY) );
+ PyModule_AddObject( mod, "DOWNARROW", PyLong_FromSsize_t(DOWNARROWKEY) );
+ PyModule_AddObject( mod, "RIGHTARROW", PyLong_FromSsize_t(RIGHTARROWKEY) );
+ PyModule_AddObject( mod, "UPARROW", PyLong_FromSsize_t(UPARROWKEY) );
+ PyModule_AddObject( mod, "PAD0", PyLong_FromSsize_t(PAD0) );
+ PyModule_AddObject( mod, "PAD1", PyLong_FromSsize_t(PAD1) );
+ PyModule_AddObject( mod, "PAD2", PyLong_FromSsize_t(PAD2) );
+ PyModule_AddObject( mod, "PAD3", PyLong_FromSsize_t(PAD3) );
+ PyModule_AddObject( mod, "PAD4", PyLong_FromSsize_t(PAD4) );
+ PyModule_AddObject( mod, "PAD5", PyLong_FromSsize_t(PAD5) );
+ PyModule_AddObject( mod, "PAD6", PyLong_FromSsize_t(PAD6) );
+ PyModule_AddObject( mod, "PAD7", PyLong_FromSsize_t(PAD7) );
+ PyModule_AddObject( mod, "PAD8", PyLong_FromSsize_t(PAD8) );
+ PyModule_AddObject( mod, "PAD9", PyLong_FromSsize_t(PAD9) );
+ PyModule_AddObject( mod, "PADPERIOD", PyLong_FromSsize_t(PADPERIOD) );
+ PyModule_AddObject( mod, "PADSLASH", PyLong_FromSsize_t(PADSLASHKEY) );
+ PyModule_AddObject( mod, "PADASTER", PyLong_FromSsize_t(PADASTERKEY) );
+ PyModule_AddObject( mod, "PADMINUS", PyLong_FromSsize_t(PADMINUS) );
+ PyModule_AddObject( mod, "PADENTER", PyLong_FromSsize_t(PADENTER) );
+ PyModule_AddObject( mod, "PADPLUS", PyLong_FromSsize_t(PADPLUSKEY) );
+ PyModule_AddObject( mod, "F1", PyLong_FromSsize_t(F1KEY) );
+ PyModule_AddObject( mod, "F2", PyLong_FromSsize_t(F2KEY) );
+ PyModule_AddObject( mod, "F3", PyLong_FromSsize_t(F3KEY) );
+ PyModule_AddObject( mod, "F4", PyLong_FromSsize_t(F4KEY) );
+ PyModule_AddObject( mod, "F5", PyLong_FromSsize_t(F5KEY) );
+ PyModule_AddObject( mod, "F6", PyLong_FromSsize_t(F6KEY) );
+ PyModule_AddObject( mod, "F7", PyLong_FromSsize_t(F7KEY) );
+ PyModule_AddObject( mod, "F8", PyLong_FromSsize_t(F8KEY) );
+ PyModule_AddObject( mod, "F9", PyLong_FromSsize_t(F9KEY) );
+ PyModule_AddObject( mod, "F10", PyLong_FromSsize_t(F10KEY) );
+ PyModule_AddObject( mod, "F11", PyLong_FromSsize_t(F11KEY) );
+ PyModule_AddObject( mod, "F12", PyLong_FromSsize_t(F12KEY) );
+ PyModule_AddObject( mod, "PAUSE", PyLong_FromSsize_t(PAUSEKEY) );
+ PyModule_AddObject( mod, "INSERT", PyLong_FromSsize_t(INSERTKEY) );
+ PyModule_AddObject( mod, "HOME", PyLong_FromSsize_t(HOMEKEY) );
+ PyModule_AddObject( mod, "PAGEUP", PyLong_FromSsize_t(PAGEUPKEY) );
+ PyModule_AddObject( mod, "PAGEDOWN", PyLong_FromSsize_t(PAGEDOWNKEY) );
+ PyModule_AddObject( mod, "END", PyLong_FromSsize_t(ENDKEY) );
+ PyModule_AddObject( mod, "UNKNOWN", PyLong_FromSsize_t(UNKNOWNKEY) );
+ PyModule_AddObject( mod, "COMMAND", PyLong_FromSsize_t(COMMANDKEY) );
+ PyModule_AddObject( mod, "GRLESS", PyLong_FromSsize_t(GRLESSKEY) );
mod = PyModule_New("spaceTypes");
PyModule_AddObject( submodule, "spaceTypes", mod );
- PyModule_AddObject( mod, "EMPTY", PyLong_FromSize_t(SPACE_EMPTY) );
- PyModule_AddObject( mod, "VIEW3D", PyLong_FromSize_t(SPACE_VIEW3D) );
- PyModule_AddObject( mod, "IPO", PyLong_FromSize_t(SPACE_IPO) );
- PyModule_AddObject( mod, "OOPS", PyLong_FromSize_t(SPACE_OOPS) );
- PyModule_AddObject( mod, "BUTS", PyLong_FromSize_t(SPACE_BUTS) );
- PyModule_AddObject( mod, "FILE", PyLong_FromSize_t(SPACE_FILE) );
- PyModule_AddObject( mod, "IMAGE", PyLong_FromSize_t(SPACE_IMAGE) );
- PyModule_AddObject( mod, "INFO", PyLong_FromSize_t(SPACE_INFO) );
- PyModule_AddObject( mod, "SEQ", PyLong_FromSize_t(SPACE_SEQ) );
- PyModule_AddObject( mod, "TEXT", PyLong_FromSize_t(SPACE_TEXT) );
- PyModule_AddObject( mod, "IMASEL", PyLong_FromSize_t(SPACE_IMASEL) );
- PyModule_AddObject( mod, "SOUND", PyLong_FromSize_t(SPACE_SOUND) );
- PyModule_AddObject( mod, "ACTION", PyLong_FromSize_t(SPACE_ACTION) );
- PyModule_AddObject( mod, "NLA", PyLong_FromSize_t(SPACE_NLA) );
- PyModule_AddObject( mod, "SCRIPT", PyLong_FromSize_t(SPACE_SCRIPT) );
- PyModule_AddObject( mod, "TIME", PyLong_FromSize_t(SPACE_TIME) );
- PyModule_AddObject( mod, "NODE", PyLong_FromSize_t(SPACE_NODE) );
+ PyModule_AddObject( mod, "EMPTY", PyLong_FromSsize_t(SPACE_EMPTY) );
+ PyModule_AddObject( mod, "VIEW3D", PyLong_FromSsize_t(SPACE_VIEW3D) );
+ PyModule_AddObject( mod, "IPO", PyLong_FromSsize_t(SPACE_IPO) );
+ PyModule_AddObject( mod, "OUTLINER", PyLong_FromSsize_t(SPACE_OUTLINER) );
+ PyModule_AddObject( mod, "BUTS", PyLong_FromSsize_t(SPACE_BUTS) );
+ PyModule_AddObject( mod, "FILE", PyLong_FromSsize_t(SPACE_FILE) );
+ PyModule_AddObject( mod, "IMAGE", PyLong_FromSsize_t(SPACE_IMAGE) );
+ PyModule_AddObject( mod, "INFO", PyLong_FromSsize_t(SPACE_INFO) );
+ PyModule_AddObject( mod, "SEQ", PyLong_FromSsize_t(SPACE_SEQ) );
+ PyModule_AddObject( mod, "TEXT", PyLong_FromSsize_t(SPACE_TEXT) );
+ PyModule_AddObject( mod, "IMASEL", PyLong_FromSsize_t(SPACE_IMASEL) );
+ PyModule_AddObject( mod, "SOUND", PyLong_FromSsize_t(SPACE_SOUND) );
+ PyModule_AddObject( mod, "ACTION", PyLong_FromSsize_t(SPACE_ACTION) );
+ PyModule_AddObject( mod, "NLA", PyLong_FromSsize_t(SPACE_NLA) );
+ PyModule_AddObject( mod, "SCRIPT", PyLong_FromSsize_t(SPACE_SCRIPT) );
+ PyModule_AddObject( mod, "TIME", PyLong_FromSsize_t(SPACE_TIME) );
+ PyModule_AddObject( mod, "NODE", PyLong_FromSsize_t(SPACE_NODE) );
diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c
index 8bdb6334a91..7979ca9cd37 100644
--- a/source/blender/python/intern/bpy_util.c
+++ b/source/blender/python/intern/bpy_util.c
@@ -163,7 +163,7 @@ void PyObSpit(char *name, PyObject *var) {
}
void PyLineSpit(void) {
- char filename[512];
+ char *filename;
int lineno;
PyErr_Clear();
@@ -175,39 +175,69 @@ void PyLineSpit(void) {
void BPY_getFileAndNum(char **filename, int *lineno)
{
PyObject *getframe, *frame;
- PyObject *f_lineno, *f_code, *co_filename;
+ PyObject *f_lineno= NULL, *co_filename= NULL;
if (filename) *filename= NULL;
if (lineno) *lineno = -1;
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) {
-
- if (filename) *filename = _PyUnicode_AsString(co_filename);
- if (lineno) *lineno = (int)PyLong_AsSsize_t(f_lineno);
-
- Py_DECREF(f_lineno);
- Py_DECREF(f_code);
- Py_DECREF(co_filename);
- Py_DECREF(frame);
-
- return;
- }
- }
+ if (getframe==NULL) {
+ return;
+ }
+
+ frame = PyObject_CallObject(getframe, NULL);
+ if (frame==NULL)
+ return;
+
+ if (filename) {
+ co_filename= PyObject_GetAttrStringArgs(frame, 1, "f_code", "co_filename");
+ if (co_filename==NULL) {
+ PyErr_SetString(PyExc_SystemError, "Could not access sys._getframe().f_code.co_filename");
+ Py_DECREF(frame);
+ return;
+ }
+
+ *filename = _PyUnicode_AsString(co_filename);
+ Py_DECREF(co_filename);
+ }
+
+ if (lineno) {
+ f_lineno= PyObject_GetAttrString(frame, "f_lineno");
+ if (f_lineno==NULL) {
+ PyErr_SetString(PyExc_SystemError, "Could not access sys._getframe().f_lineno");
+ Py_DECREF(frame);
+ return;
}
+
+ *lineno = (int)PyLong_AsSsize_t(f_lineno);
+ Py_DECREF(f_lineno);
}
+
+ Py_DECREF(frame);
+}
+
+/* Would be nice if python had this built in */
+PyObject *PyObject_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
+{
+ Py_ssize_t i;
+ PyObject *item= o;
+ char *attr;
- Py_XDECREF(co_filename);
- Py_XDECREF(f_lineno);
- Py_XDECREF(f_code);
- Py_XDECREF(frame);
+ va_list vargs;
+
+ va_start(vargs, n);
+ for (i=0; i<n; i++) {
+ attr = va_arg(vargs, char *);
+ item = PyObject_GetAttrString(item, attr);
+
+ if (item)
+ Py_DECREF(item);
+ else /* python will set the error value here */
+ break;
+
+ }
+ va_end(vargs);
- PyErr_SetString(PyExc_SystemError, "Could not access sys._getframe().f_code.co_filename");
+ Py_XINCREF(item); /* final value has is increfed, to match PyObject_GetAttrString */
+ return item;
}
diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h
index 4d4d552af4e..51e13f98a35 100644
--- a/source/blender/python/intern/bpy_util.h
+++ b/source/blender/python/intern/bpy_util.h
@@ -24,6 +24,11 @@
#include <Python.h>
+#ifndef BPY_UTIL_H
+#define BPY_UTIL_H
+
+#include "bpy_compat.h"
+
/* for internal use only, so python can interchange a sequence of strings with flags */
typedef struct BPY_flag_def {
const char *name;
@@ -37,3 +42,8 @@ int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag);
void PyObSpit(char *name, PyObject *var);
void PyLineSpit(void);
void BPY_getFileAndNum(char **filename, int *lineno);
+
+/* own python like utility function */
+PyObject *PyObject_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...);
+
+#endif
diff --git a/source/blender/python/rna_dump.py b/source/blender/python/rna_dump.py
new file mode 100644
index 00000000000..66fb76c35aa
--- /dev/null
+++ b/source/blender/python/rna_dump.py
@@ -0,0 +1,136 @@
+ # ***** 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.
+ #
+ # Contributor(s): Campbell Barton
+ #
+ # #**** END GPL LICENSE BLOCK #****
+
+if 1:
+ # Print once every 1000
+ GEN_PATH = True
+ PRINT_DATA = False
+ PRINT_DATA_INT = 1000
+ VERBOSE = False
+ VERBOSE_TYPE = False
+ MAX_RECURSIVE = 8
+else:
+ # Print everything
+ GEN_PATH = True
+ PRINT_DATA = True
+ PRINT_DATA_INT = 0
+ VERBOSE = False
+ VERBOSE_TYPE = False
+ MAX_RECURSIVE = 8
+
+seek_count = [0]
+
+def seek(r, txt, recurs):
+
+ seek_count[0] += 1
+
+ if PRINT_DATA_INT:
+ if not (seek_count[0] % PRINT_DATA_INT):
+ print(seek_count[0], txt)
+
+ if PRINT_DATA:
+ print(txt)
+
+ newtxt = ''
+
+ if recurs > MAX_RECURSIVE:
+ #print ("Recursion is over max")
+ #print (txt)
+ return
+
+ type_r = type(r)
+
+ # print(type_r)
+ # print(dir(r))
+
+ # basic types
+ if type_r in (float, int, bool, type(None)):
+ if PRINT_DATA:
+ print(txt + ' -> ' + str(r))
+ return
+
+ if type_r == str:
+ if PRINT_DATA:
+ print(txt + ' -> "' + str(r) + '"')
+ return
+
+ try: keys = r.keys()
+ except: keys = None
+
+ if keys != None:
+ if PRINT_DATA:
+ print(txt + '.keys() - ' + str(r.keys()))
+
+ try: __members__ = dir(r)
+ except: __members__ = []
+
+ for item in __members__:
+ if item.startswith('__'):
+ continue
+
+ if GEN_PATH: newtxt = txt + '.' + item
+
+ if item == 'rna_type' and VERBOSE_TYPE==False: # just avoid because it spits out loads of data
+ continue
+
+ try: value = getattr(r, item)
+ except: value = None
+
+ seek( value, newtxt, recurs + 1)
+
+
+ if keys:
+ for k in keys:
+ if GEN_PATH: newtxt = txt + '["' + k + '"]'
+ seek(r.__getitem__(k), newtxt, recurs+1)
+
+ else:
+ try: length = len( r )
+ except: length = 0
+
+ if VERBOSE==False and length >= 4:
+ for i in (0, length-1):
+ if i>0:
+ if PRINT_DATA:
+ print((' '*len(txt)) + ' ... skipping '+str(length-2)+' items ...')
+
+ if GEN_PATH: newtxt = txt + '[' + str(i) + ']'
+ seek(r[i], newtxt, recurs+1)
+ else:
+ for i in range(length):
+ if GEN_PATH: newtxt = txt + '[' + str(i) + ']'
+ seek(r[i], newtxt, recurs+1)
+
+seek(bpy.data, 'bpy.data', 0)
+# seek(bpy.types, 'bpy.types', 0)
+'''
+for d in dir(bpy.types):
+ t = getattr(bpy.types, d)
+ try: r = t.__rna__
+ except: r = None
+ if r:
+ seek(r, 'bpy.types.' + d + '.__rna__', 0)
+'''
+
+#print dir(bpy)
+#import sys
+#sys.exit()
+
+print("iter over ", seek_count, "rna items")
diff --git a/source/blender/python/simple_enum_gen.py b/source/blender/python/simple_enum_gen.py
new file mode 100644
index 00000000000..59f048c2842
--- /dev/null
+++ b/source/blender/python/simple_enum_gen.py
@@ -0,0 +1,65 @@
+ # ***** 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.
+ #
+ # Contributor(s): Campbell Barton
+ #
+ # #**** END GPL LICENSE BLOCK #****
+
+defs = """
+ SPACE_EMPTY,
+ SPACE_VIEW3D,
+ SPACE_IPO,
+ SPACE_OUTLINER,
+ SPACE_BUTS,
+ SPACE_FILE,
+ SPACE_IMAGE,
+ SPACE_INFO,
+ SPACE_SEQ,
+ SPACE_TEXT,
+ SPACE_IMASEL,
+ SPACE_SOUND,
+ SPACE_ACTION,
+ SPACE_NLA,
+ SPACE_SCRIPT,
+ SPACE_TIME,
+ SPACE_NODE,
+ SPACEICONMAX
+"""
+
+print '\tmod = PyModule_New("dummy");'
+print '\tPyModule_AddObject( submodule, "key", mod );'
+
+for d in defs.split('\n'):
+
+ d = d.replace(',', ' ')
+ w = d.split()
+
+ if not w:
+ continue
+
+ try: w.remove("#define")
+ except: pass
+
+ # print w
+
+ val = w[0]
+ py_val = w[0]
+
+ print '\tPyModule_AddObject( mod, "%s", PyLong_FromSize_t(%s) );' % (val, py_val)
+
+
+
+
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/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index d1c268a1189..2c7493a51ab 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -935,6 +935,38 @@ BlenderCursor[BC_EYEDROPPER_CURSOR]=&EyedropperCursor;
END_CURSOR_BLOCK
+/********************** Swap Area Cursor ***********************/
+BEGIN_CURSOR_BLOCK
+static char swap_sbm[]={
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0xff, 0x07,
+ 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07,
+ 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07,
+};
+
+static char swap_smsk[]={
+ 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xff,
+ 0xc0, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0x07,
+ 0xff, 0x07, 0xff, 0x07, 0xff, 0x07, 0xff, 0x07,
+};
+
+static BCursor SwapCursor = {
+ /*small*/
+ swap_sbm, swap_smsk,
+ 16, 16,
+ 8, 8,
+ /*big*/
+ NULL, NULL,
+ 32,32,
+ 15, 15,
+ /*color*/
+ BC_YELLOW, BC_BLUE
+};
+
+BlenderCursor[BC_SWAPAREA_CURSOR]=&SwapCursor;
+
+END_CURSOR_BLOCK
/********************** Put the cursors in the array ***********************/
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 7dc30695862..ef89b2b35ad 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -111,9 +111,9 @@ static void wm_method_draw_full(bContext *C, wmWindow *win)
/* draw overlapping regions */
for(ar=screen->regionbase.first; ar; ar= ar->next) {
if(ar->swinid) {
- CTX_wm_region_set(C, ar);
+ CTX_wm_menu_set(C, ar);
ED_region_do_draw(C, ar);
- CTX_wm_region_set(C, NULL);
+ CTX_wm_menu_set(C, NULL);
}
}
@@ -245,9 +245,9 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win)
/* draw marked overlapping regions */
for(ar=screen->regionbase.first; ar; ar= ar->next) {
if(ar->swinid && ar->do_draw) {
- CTX_wm_region_set(C, ar);
+ CTX_wm_menu_set(C, ar);
ED_region_do_draw(C, ar);
- CTX_wm_region_set(C, NULL);
+ CTX_wm_menu_set(C, NULL);
}
}
@@ -558,9 +558,9 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win)
/* draw overlapping regions */
for(ar=screen->regionbase.first; ar; ar= ar->next) {
if(ar->swinid) {
- CTX_wm_region_set(C, ar);
+ CTX_wm_menu_set(C, ar);
ED_region_do_draw(C, ar);
- CTX_wm_region_set(C, NULL);
+ CTX_wm_menu_set(C, NULL);
}
}
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 8c06be7a37e..283f0819996 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -469,7 +469,12 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, PointerRNA *properties,
{
wmWindowManager *wm= CTX_wm_manager(C);
wmOperator *op= wm_operator_create(wm, ot, properties, reports);
- int retval= op->type->exec(C, op);
+ int retval= OPERATOR_CANCELLED;
+
+ if (op->type->exec)
+ retval= op->type->exec(C, op);
+ else
+ printf("error \"%s\" operator has no exec function, python cannot call it\n", op->type->name);
if (reports)
op->reports= NULL; /* dont let the operator free reports passed to this function */
@@ -544,14 +549,17 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
else if(handler->ui_remove) {
ScrArea *area= CTX_wm_area(C);
ARegion *region= CTX_wm_region(C);
+ ARegion *menu= CTX_wm_menu(C);
if(handler->ui_area) CTX_wm_area_set(C, handler->ui_area);
if(handler->ui_region) CTX_wm_region_set(C, handler->ui_region);
+ if(handler->ui_menu) CTX_wm_menu_set(C, handler->ui_menu);
handler->ui_remove(C, handler->ui_userdata);
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
+ CTX_wm_menu_set(C, menu);
}
wm_event_free_handler(handler);
@@ -721,11 +729,13 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
{
ScrArea *area= CTX_wm_area(C);
ARegion *region= CTX_wm_region(C);
+ ARegion *menu= CTX_wm_menu(C);
int retval;
/* we set context to where ui handler came from */
if(handler->ui_area) CTX_wm_area_set(C, handler->ui_area);
if(handler->ui_region) CTX_wm_region_set(C, handler->ui_region);
+ if(handler->ui_menu) CTX_wm_menu_set(C, handler->ui_menu);
retval= handler->ui_handle(C, event, handler->ui_userdata);
@@ -733,11 +743,13 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
if((retval != WM_UI_HANDLER_BREAK) || wm_event_always_pass(event)) {
CTX_wm_area_set(C, area);
CTX_wm_region_set(C, region);
+ CTX_wm_menu_set(C, menu);
}
else {
/* this special cases is for areas and regions that get removed */
CTX_wm_area_set(C, NULL);
CTX_wm_region_set(C, NULL);
+ CTX_wm_menu_set(C, NULL);
}
if(retval == WM_UI_HANDLER_BREAK)
@@ -776,7 +788,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
sfile= (SpaceFile*)CTX_wm_space_data(C);
sfile->op= handler->op;
- ED_fileselect_set_params(sfile, filetype, handler->op->type->name, path, 0, 0, 0);
+ ED_fileselect_set_params(sfile, filetype, handler->op->type->name, path, 0, FILE_SHORTDISPLAY, 0);
MEM_freeN(path);
action= WM_HANDLER_BREAK;
@@ -1192,6 +1204,7 @@ wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers, wmUIHan
handler->ui_userdata= userdata;
handler->ui_area= (C)? CTX_wm_area(C): NULL;
handler->ui_region= (C)? CTX_wm_region(C): NULL;
+ handler->ui_menu= (C)? CTX_wm_menu(C): NULL;
BLI_addhead(handlers, handler);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 01e959715d3..a0d170cc0f0 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -82,6 +82,7 @@
#include "wm_files.h"
#include "wm_window.h"
+#include "ED_armature.h"
#include "ED_node.h"
#include "ED_previewrender.h"
#include "ED_space_api.h"
@@ -196,7 +197,13 @@ void WM_exit(bContext *C)
/* all non-screen and non-space stuff editors did, like editmode */
if(C)
ED_editors_exit(C);
-
+
+// XXX
+// BIF_GlobalReebFree();
+// BIF_freeRetarget();
+ BIF_freeTemplates(C);
+ BIF_freeSketch(C);
+
/* Context should still working here. but radio tool needs cleaning... */
freeAllRad(CTX_data_scene(C));
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 255d22191e2..54074ec8f07 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -209,10 +209,10 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct)
* fixed it). - zr (2001!)
*/
- if (swin->winrct.xmax >= win->sizex)
- swin->winrct.xmax= win->sizex-1;
- if (swin->winrct.ymax >= win->sizey)
- swin->winrct.ymax= win->sizey-1;
+ if (swin->winrct.xmax > win->sizex)
+ swin->winrct.xmax= win->sizex;
+ if (swin->winrct.ymax > win->sizey)
+ swin->winrct.ymax= win->sizey;
/* extra service */
wmSubWindowSet(win, swinid);
diff --git a/source/blender/windowmanager/wm_cursors.h b/source/blender/windowmanager/wm_cursors.h
index 096e1916fa9..1a1a0d0b71d 100644
--- a/source/blender/windowmanager/wm_cursors.h
+++ b/source/blender/windowmanager/wm_cursors.h
@@ -92,6 +92,7 @@ enum {
BC_NS_SCROLLCURSOR,
BC_EW_SCROLLCURSOR,
BC_EYEDROPPER_CURSOR,
+ BC_SWAPAREA_CURSOR,
/* --- ALWAYS LAST ----- */
BC_NUMCURSORS,
};
diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h
index 930f20dfa63..99853c77a55 100644
--- a/source/blender/windowmanager/wm_event_system.h
+++ b/source/blender/windowmanager/wm_event_system.h
@@ -58,6 +58,7 @@ typedef struct wmEventHandler {
void *ui_userdata; /* user data pointer */
struct ScrArea *ui_area; /* for derived/modal handlers */
struct ARegion *ui_region; /* for derived/modal handlers */
+ struct ARegion *ui_menu; /* for derived/modal handlers */
/* fileselect handler re-uses modal operator data */
struct bScreen *filescreen; /* screen it started in, to validate exec */
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index f386510a2eb..7bf08617fb6 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -52,13 +52,11 @@ void wm_window_set_title (wmWindow *win, char *title);
void wm_window_swap_buffers (wmWindow *win);
wmWindow *wm_window_copy (bContext *C, wmWindow *winorig);
-wmWindow *wm_window_rip (bContext *C, wmWindow *winorig);
void wm_window_testbreak (void);
/* *************** window operators ************** */
int wm_window_duplicate_op (bContext *C, wmOperator *op);
-int wm_window_rip_op (bContext *C, wmOperator *op, struct wmEvent *event);
int wm_window_fullscreen_toggle_op(bContext *C, wmOperator *op);
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..3de46a68276 100644
--- a/source/creator/Makefile
+++ b/source/creator/Makefile
@@ -43,6 +43,7 @@ CPPFLAGS += -I../blender/radiosity/extern/include
# two needed for the kernel
CPPFLAGS += -I../blender/imbuf
CPPFLAGS += -I../blender/makesdna
+CPPFLAGS += -I../blender/makesrna
CPPFLAGS += -I../blender/blenlib
CPPFLAGS += -I../blender/editors/include
CPPFLAGS += -I../blender/renderconverter
@@ -59,6 +60,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/SConscript b/source/creator/SConscript
index 6c36a8f5b41..27cfc161c42 100644
--- a/source/creator/SConscript
+++ b/source/creator/SConscript
@@ -6,7 +6,7 @@ sources = 'creator.c'
incs = '#/intern/guardedalloc ../blender/blenlib ../blender/blenkernel'
incs += ' ../blender/editors/include ../blender/blenloader ../blender/imbuf'
incs += ' ../blender/renderconverter ../blender/render/extern/include ../blender/windowmanager'
-incs += ' ../blender/makesdna ../kernel/gen_messaging'
+incs += ' ../blender/makesdna ../blender/makesrna ../kernel/gen_messaging'
incs += ' ../kernel/gen_system #/extern/glew/include ../blender/gpu'
incs += ' ' + env['BF_OPENGL_INC']
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 f15d4c7249f..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();
}
@@ -158,6 +158,7 @@ PyParentObject SCA_DelaySensor::Parents[] = {
};
PyMethodDef SCA_DelaySensor::Methods[] = {
+ //Deprecated functions ------>
/* setProperty */
{"setDelay", (PyCFunction) SCA_DelaySensor::sPySetDelay, METH_VARARGS, (PY_METHODCHAR)SetDelay_doc},
{"setDuration", (PyCFunction) SCA_DelaySensor::sPySetDuration, METH_VARARGS, (PY_METHODCHAR)SetDuration_doc},
@@ -166,13 +167,32 @@ PyMethodDef SCA_DelaySensor::Methods[] = {
{"getDelay", (PyCFunction) SCA_DelaySensor::sPyGetDelay, METH_NOARGS, (PY_METHODCHAR)GetDelay_doc},
{"getDuration", (PyCFunction) SCA_DelaySensor::sPyGetDuration, METH_NOARGS, (PY_METHODCHAR)GetDuration_doc},
{"getRepeat", (PyCFunction) SCA_DelaySensor::sPyGetRepeat, METH_NOARGS, (PY_METHODCHAR)GetRepeat_doc},
+ //<----- Deprecated
{NULL,NULL} //Sentinel
};
-PyObject* SCA_DelaySensor::_getattr(const STR_String& attr) {
+PyAttributeDef SCA_DelaySensor::Attributes[] = {
+ KX_PYATTRIBUTE_INT_RW("delay",0,100000,true,SCA_DelaySensor,m_delay),
+ KX_PYATTRIBUTE_INT_RW("duration",0,100000,true,SCA_DelaySensor,m_duration),
+ KX_PYATTRIBUTE_BOOL_RW("repeat",SCA_DelaySensor,m_repeat),
+ { NULL } //Sentinel
+};
+
+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 char *attr, PyObject *value) {
+ int ret = _setattr_self(Attributes, this, attr, value);
+ if (ret >= 0)
+ return ret;
+ return SCA_ISensor::_setattr(attr, value);
+}
+
+
const char SCA_DelaySensor::SetDelay_doc[] =
"setDelay(delay)\n"
"\t- delay: length of the initial OFF period as number of frame\n"
@@ -180,6 +200,7 @@ const char SCA_DelaySensor::SetDelay_doc[] =
"\tSet the initial delay before the positive trigger\n";
PyObject* SCA_DelaySensor::PySetDelay(PyObject* self, PyObject* args, PyObject* kwds)
{
+ ShowDeprecationWarning("setDelay()", "the delay property");
int delay;
if(!PyArg_ParseTuple(args, "i", &delay)) {
@@ -190,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[] =
@@ -201,6 +222,7 @@ const char SCA_DelaySensor::SetDuration_doc[] =
"\tIf > 0, a negative trigger is fired at the end of the ON pulse.\n";
PyObject* SCA_DelaySensor::PySetDuration(PyObject* self, PyObject* args, PyObject* kwds)
{
+ ShowDeprecationWarning("setDuration()", "the duration property");
int duration;
if(!PyArg_ParseTuple(args, "i", &duration)) {
@@ -211,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[] =
@@ -221,13 +243,14 @@ const char SCA_DelaySensor::SetRepeat_doc[] =
"\tSet the sensor repeat mode\n";
PyObject* SCA_DelaySensor::PySetRepeat(PyObject* self, PyObject* args, PyObject* kwds)
{
+ ShowDeprecationWarning("setRepeat()", "the repeat property");
int repeat;
if(!PyArg_ParseTuple(args, "i", &repeat)) {
return NULL;
}
m_repeat = (repeat != 0);
- Py_Return;
+ Py_RETURN_NONE;
}
const char SCA_DelaySensor::GetDelay_doc[] =
@@ -235,6 +258,7 @@ const char SCA_DelaySensor::GetDelay_doc[] =
"\tReturn the delay parameter value\n";
PyObject* SCA_DelaySensor::PyGetDelay(PyObject* self)
{
+ ShowDeprecationWarning("getDelay()", "the delay property");
return PyInt_FromLong(m_delay);
}
@@ -243,6 +267,7 @@ const char SCA_DelaySensor::GetDuration_doc[] =
"\tReturn the duration parameter value\n";
PyObject* SCA_DelaySensor::PyGetDuration(PyObject* self)
{
+ ShowDeprecationWarning("getDuration()", "the duration property");
return PyInt_FromLong(m_duration);
}
@@ -251,6 +276,7 @@ const char SCA_DelaySensor::GetRepeat_doc[] =
"\tReturn the repeat parameter value\n";
PyObject* SCA_DelaySensor::PyGetRepeat(PyObject* self)
{
+ ShowDeprecationWarning("getRepeat()", "the repeat property");
return BoolToPyArg(m_repeat);
}
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_compile.mk b/source/nan_compile.mk
index 0ac712b3a18..a2fcfad3a9e 100644
--- a/source/nan_compile.mk
+++ b/source/nan_compile.mk
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
#
diff --git a/source/nan_definitions.mk b/source/nan_definitions.mk
index 495eb60a7f8..60fc56408b2 100644
--- a/source/nan_definitions.mk
+++ b/source/nan_definitions.mk
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
#
@@ -31,14 +33,25 @@
sinclude ../user-def.mk
+# This warning only takes place once in source/
+ifeq (debug, $(findstring debug, $(MAKECMDGOALS)))
+ ifeq (all, $(findstring all, $(MAKECMDGOALS)))
+ export ERRTXT = "ERROR: all and debug targets cannot be used together anymore"
+ export ERRTXT += "Use something like ..make all && make debug.. instead"
+ endif
+endif
+
+ifdef ERRTXT
+$(error $(ERRTXT))
+endif
+
ifndef CONFIG_GUESS
ifeq (debug, $(findstring debug, $(MAKECMDGOALS)))
- ifeq (all, $(findstring all, $(MAKECMDGOALS)))
-all debug::
- ERRTXT = "ERROR: all and debug targets cannot be used together anymore"
- ERRTXT += "Use something like ..make all && make debug.. instead"
- $(error $(ERRTXT))
- endif
+ export DEBUG_DIR = debug/
+ export ALL_OR_DEBUG = debug
+ endif
+ ifeq (all, $(findstring all, $(MAKECMDGOALS)))
+ export ALL_OR_DEBUG ?= all
endif
# First generic defaults for all platforms which should be constant.
@@ -111,6 +124,7 @@ endif
export WITH_OPENEXR ?= true
export WITH_DDS ?= true
+ export WITH_OPENJPEG ?= true
ifeq ($(OS),windows)
export NAN_WINTAB ?= $(LCGDIR)/wintab
@@ -135,9 +149,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)
@@ -157,9 +171,9 @@ endif
endif
endif
endif
- ifeq ($(WITH_OPENEXR), true)
- export NAN_OPENEXR_INC ?= -I$(NAN_OPENEXR)/include -I$(NAN_OPENEXR)/include/OpenEXR
- endif
+ ifeq ($(WITH_OPENEXR), true)
+ export NAN_OPENEXR_INC ?= -I$(NAN_OPENEXR)/include -I$(NAN_OPENEXR)/include/OpenEXR
+ endif
endif
# Platform Dependent settings go below:
diff --git a/source/nan_link.mk b/source/nan_link.mk
index e92103f56d9..42b17b425b3 100644
--- a/source/nan_link.mk
+++ b/source/nan_link.mk
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
#
diff --git a/source/nan_subdirs.mk b/source/nan_subdirs.mk
index 85360eab7bc..c33e0fa2ccc 100644
--- a/source/nan_subdirs.mk
+++ b/source/nan_subdirs.mk
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
#
diff --git a/source/nan_warn.mk b/source/nan_warn.mk
index 97a8bbf09e4..5841cdf5908 100644
--- a/source/nan_warn.mk
+++ b/source/nan_warn.mk
@@ -1,3 +1,5 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
#
# $Id$
#
@@ -22,7 +24,7 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): none yet.
+# Contributor(s): GSR
#
# ***** END GPL LICENSE BLOCK *****
#
diff --git a/tools/Blender.py b/tools/Blender.py
index 99c4a7753fb..ede99fb6e8b 100644
--- a/tools/Blender.py
+++ b/tools/Blender.py
@@ -434,11 +434,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', ''),