static duk_ret_t RigidBody_IsActive(duk_context* ctx) { RigidBody* thisObj = GetThisWeakObject<RigidBody>(ctx); bool ret = thisObj->IsActive(); duk_push_boolean(ctx, ret); return 1; }
void CollisionShape::DrawDebugGeometry(DebugRenderer* debug, bool depthTest) { if (debug && physicsWorld_ && shape_ && node_ && IsEnabledEffective()) { physicsWorld_->SetDebugRenderer(debug); physicsWorld_->SetDebugDepthTest(depthTest); // Use the rigid body's world transform if possible, as it may be different from the rendering transform Matrix3x4 worldTransform; RigidBody* body = GetComponent<RigidBody>(); bool bodyActive = false; if (body) { worldTransform = Matrix3x4(body->GetPosition(), body->GetRotation(), node_->GetWorldScale()); bodyActive = body->IsActive(); } else worldTransform = node_->GetWorldTransform(); Vector3 position = position_; // For terrains, undo the height centering performed automatically by Bullet if (shapeType_ == SHAPE_TERRAIN && geometry_) { HeightfieldData* heightfield = static_cast<HeightfieldData*>(geometry_.Get()); position.y_ += (heightfield->minHeight_ + heightfield->maxHeight_) * 0.5f; } Vector3 worldPosition(worldTransform * position); Quaternion worldRotation(worldTransform.Rotation() * rotation_); btDiscreteDynamicsWorld* world = physicsWorld_->GetWorld(); world->debugDrawObject(btTransform(ToBtQuaternion(worldRotation), ToBtVector3(worldPosition)), shape_, bodyActive ? WHITE : GREEN); physicsWorld_->SetDebugRenderer(0); } }
bool SimulationIsland::Simulate(IDebugDraw* debugDrawer,int numSolverIterations,TypedConstraint** constraintsBaseAddress,BroadphasePair* overlappingPairBaseAddress, Dispatcher* dispatcher,BroadphaseInterface* broadphase,class ConstraintSolver* solver,float timeStep) { #ifdef USE_QUICKPROF Profiler::beginBlock("predictIntegratedTransform"); #endif //USE_QUICKPROF { // std::vector<CcdPhysicsController*>::iterator i; int k; for (k=0;k<GetNumControllers();k++) { CcdPhysicsController* ctrl = m_controllers[k]; // SimdTransform predictedTrans; RigidBody* body = ctrl->GetRigidBody(); //todo: only do this when necessary, it's used for contact points body->m_cachedInvertedWorldTransform = body->m_worldTransform.inverse(); if (body->IsActive()) { if (!body->IsStatic()) { body->applyForces( timeStep); body->integrateVelocities( timeStep); body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform); } } } } #ifdef USE_QUICKPROF Profiler::endBlock("predictIntegratedTransform"); #endif //USE_QUICKPROF //BroadphaseInterface* scene = GetBroadphase(); // // collision detection (?) // #ifdef USE_QUICKPROF Profiler::beginBlock("DispatchAllCollisionPairs"); #endif //USE_QUICKPROF // int numsubstep = m_numIterations; DispatcherInfo dispatchInfo; dispatchInfo.m_timeStep = timeStep; dispatchInfo.m_stepCount = 0; dispatchInfo.m_enableSatConvex = false;//m_enableSatCollisionDetection; dispatchInfo.m_debugDraw = debugDrawer; std::vector<BroadphasePair> overlappingPairs; overlappingPairs.resize(this->m_overlappingPairIndices.size()); //gather overlapping pair info int i; for (i=0;i<m_overlappingPairIndices.size();i++) { overlappingPairs[i] = overlappingPairBaseAddress[m_overlappingPairIndices[i]]; } //pairCache->RefreshOverlappingPairs(); if (overlappingPairs.size()) { dispatcher->DispatchAllCollisionPairs(&overlappingPairs[0],overlappingPairs.size(),dispatchInfo);///numsubstep,g); } //scatter overlapping pair info, mainly the created algorithms/contact caches for (i=0;i<m_overlappingPairIndices.size();i++) { overlappingPairBaseAddress[m_overlappingPairIndices[i]] = overlappingPairs[i]; } #ifdef USE_QUICKPROF Profiler::endBlock("DispatchAllCollisionPairs"); #endif //USE_QUICKPROF int numRigidBodies = m_controllers.size(); //contacts #ifdef USE_QUICKPROF Profiler::beginBlock("SolveConstraint"); #endif //USE_QUICKPROF //solve the regular constraints (point 2 point, hinge, etc) for (int g=0;g<numSolverIterations;g++) { // // constraint solving // int i; int numConstraints = m_constraintIndices.size(); //point to point constraints for (i=0;i< numConstraints ; i++ ) { TypedConstraint* constraint = constraintsBaseAddress[m_constraintIndices[i]]; constraint->BuildJacobian(); constraint->SolveConstraint( timeStep ); } } #ifdef USE_QUICKPROF Profiler::endBlock("SolveConstraint"); #endif //USE_QUICKPROF /* //solve the vehicles #ifdef NEW_BULLET_VEHICLE_SUPPORT //vehicles int numVehicles = m_wrapperVehicles.size(); for (int i=0;i<numVehicles;i++) { WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i]; RaycastVehicle* vehicle = wrapperVehicle->GetVehicle(); vehicle->UpdateVehicle( timeStep); } #endif //NEW_BULLET_VEHICLE_SUPPORT */ /* Profiler::beginBlock("CallbackTriggers"); #endif //USE_QUICKPROF CallbackTriggers(); #ifdef USE_QUICKPROF Profiler::endBlock("CallbackTriggers"); } */ //OverlappingPairCache* scene = GetCollisionWorld()->GetPairCache(); ContactSolverInfo solverInfo; solverInfo.m_friction = 0.9f; solverInfo.m_numIterations = numSolverIterations; solverInfo.m_timeStep = timeStep; solverInfo.m_restitution = 0.f;//m_restitution; if (m_manifolds.size()) { solver->SolveGroup( &m_manifolds[0],m_manifolds.size(),solverInfo,0); } #ifdef USE_QUICKPROF Profiler::beginBlock("proceedToTransform"); #endif //USE_QUICKPROF { { UpdateAabbs(debugDrawer,broadphase,timeStep); float toi = 1.f; //experimental continuous collision detection /* if (m_ccdMode == 3) { DispatcherInfo dispatchInfo; dispatchInfo.m_timeStep = timeStep; dispatchInfo.m_stepCount = 0; dispatchInfo.m_dispatchFunc = DispatcherInfo::DISPATCH_CONTINUOUS; // GetCollisionWorld()->GetDispatcher()->DispatchAllCollisionPairs(scene,dispatchInfo); toi = dispatchInfo.m_timeOfImpact; } */ // // integrating solution // { std::vector<CcdPhysicsController*>::iterator i; for (i=m_controllers.begin(); !(i==m_controllers.end()); i++) { CcdPhysicsController* ctrl = *i; SimdTransform predictedTrans; RigidBody* body = ctrl->GetRigidBody(); if (body->IsActive()) { if (!body->IsStatic()) { body->predictIntegratedTransform(timeStep* toi, predictedTrans); body->proceedToTransform( predictedTrans); } } } } // // disable sleeping physics objects // std::vector<CcdPhysicsController*> m_sleepingControllers; std::vector<CcdPhysicsController*>::iterator i; for (i=m_controllers.begin(); !(i==m_controllers.end()); i++) { CcdPhysicsController* ctrl = (*i); RigidBody* body = ctrl->GetRigidBody(); ctrl->UpdateDeactivation(timeStep); if (ctrl->wantsSleeping()) { if (body->GetActivationState() == ACTIVE_TAG) body->SetActivationState( WANTS_DEACTIVATION ); } else { if (body->GetActivationState() != DISABLE_DEACTIVATION) body->SetActivationState( ACTIVE_TAG ); } if (true) { if (body->GetActivationState() == ISLAND_SLEEPING) { m_sleepingControllers.push_back(ctrl); } } else { if (ctrl->wantsSleeping()) { m_sleepingControllers.push_back(ctrl); } } } } #ifdef USE_QUICKPROF Profiler::endBlock("proceedToTransform"); Profiler::beginBlock("SyncMotionStates"); #endif //USE_QUICKPROF SyncMotionStates(timeStep); #ifdef USE_QUICKPROF Profiler::endBlock("SyncMotionStates"); #endif //USE_QUICKPROF #ifdef NEW_BULLET_VEHICLE_SUPPORT //sync wheels for vehicles int numVehicles = m_wrapperVehicles.size(); for (int i=0;i<numVehicles;i++) { WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i]; wrapperVehicle->SyncWheels(); } #endif //NEW_BULLET_VEHICLE_SUPPORT return true; } }
void PhysicsWorld::SendCollisionEvents() { ATOMIC_PROFILE(SendCollisionEvents); currentCollisions_.Clear(); physicsCollisionData_.Clear(); nodeCollisionData_.Clear(); int numManifolds = collisionDispatcher_->getNumManifolds(); if (numManifolds) { physicsCollisionData_[PhysicsCollision::P_WORLD] = this; for (int i = 0; i < numManifolds; ++i) { btPersistentManifold* contactManifold = collisionDispatcher_->getManifoldByIndexInternal(i); // First check that there are actual contacts, as the manifold exists also when objects are close but not touching if (!contactManifold->getNumContacts()) continue; const btCollisionObject* objectA = contactManifold->getBody0(); const btCollisionObject* objectB = contactManifold->getBody1(); RigidBody* bodyA = static_cast<RigidBody*>(objectA->getUserPointer()); RigidBody* bodyB = static_cast<RigidBody*>(objectB->getUserPointer()); // If it's not a rigidbody, maybe a ghost object if (!bodyA || !bodyB) continue; // Skip collision event signaling if both objects are static, or if collision event mode does not match if (bodyA->GetMass() == 0.0f && bodyB->GetMass() == 0.0f) continue; if (bodyA->GetCollisionEventMode() == COLLISION_NEVER || bodyB->GetCollisionEventMode() == COLLISION_NEVER) continue; if (bodyA->GetCollisionEventMode() == COLLISION_ACTIVE && bodyB->GetCollisionEventMode() == COLLISION_ACTIVE && !bodyA->IsActive() && !bodyB->IsActive()) continue; WeakPtr<RigidBody> bodyWeakA(bodyA); WeakPtr<RigidBody> bodyWeakB(bodyB); // First only store the collision pair as weak pointers and the manifold pointer, so user code can safely destroy // objects during collision event handling Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> > bodyPair; if (bodyA < bodyB) { bodyPair = MakePair(bodyWeakA, bodyWeakB); currentCollisions_[bodyPair].manifold_ = contactManifold; } else { bodyPair = MakePair(bodyWeakB, bodyWeakA); currentCollisions_[bodyPair].flippedManifold_ = contactManifold; } } for (HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, ManifoldPair>::Iterator i = currentCollisions_.Begin(); i != currentCollisions_.End(); ++i) { RigidBody* bodyA = i->first_.first_; RigidBody* bodyB = i->first_.second_; if (!bodyA || !bodyB) continue; Node* nodeA = bodyA->GetNode(); Node* nodeB = bodyB->GetNode(); WeakPtr<Node> nodeWeakA(nodeA); WeakPtr<Node> nodeWeakB(nodeB); bool trigger = bodyA->IsTrigger() || bodyB->IsTrigger(); bool newCollision = !previousCollisions_.Contains(i->first_); physicsCollisionData_[PhysicsCollision::P_NODEA] = nodeA; physicsCollisionData_[PhysicsCollision::P_NODEB] = nodeB; physicsCollisionData_[PhysicsCollision::P_BODYA] = bodyA; physicsCollisionData_[PhysicsCollision::P_BODYB] = bodyB; physicsCollisionData_[PhysicsCollision::P_TRIGGER] = trigger; contacts_.Clear(); // "Pointers not flipped"-manifold, send unmodified normals btPersistentManifold* contactManifold = i->second_.manifold_; if (contactManifold) { for (int j = 0; j < contactManifold->getNumContacts(); ++j) { btManifoldPoint& point = contactManifold->getContactPoint(j); contacts_.WriteVector3(ToVector3(point.m_positionWorldOnB)); contacts_.WriteVector3(ToVector3(point.m_normalWorldOnB)); contacts_.WriteFloat(point.m_distance1); contacts_.WriteFloat(point.m_appliedImpulse); } } // "Pointers flipped"-manifold, flip normals also contactManifold = i->second_.flippedManifold_; if (contactManifold) { for (int j = 0; j < contactManifold->getNumContacts(); ++j) { btManifoldPoint& point = contactManifold->getContactPoint(j); contacts_.WriteVector3(ToVector3(point.m_positionWorldOnB)); contacts_.WriteVector3(-ToVector3(point.m_normalWorldOnB)); contacts_.WriteFloat(point.m_distance1); contacts_.WriteFloat(point.m_appliedImpulse); } } physicsCollisionData_[PhysicsCollision::P_CONTACTS] = contacts_.GetBuffer(); // Send separate collision start event if collision is new if (newCollision) { SendEvent(E_PHYSICSCOLLISIONSTART, physicsCollisionData_); // Skip rest of processing if either of the nodes or bodies is removed as a response to the event if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; } // Then send the ongoing collision event SendEvent(E_PHYSICSCOLLISION, physicsCollisionData_); if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; nodeCollisionData_[NodeCollision::P_BODY] = bodyA; nodeCollisionData_[NodeCollision::P_OTHERNODE] = nodeB; nodeCollisionData_[NodeCollision::P_OTHERBODY] = bodyB; nodeCollisionData_[NodeCollision::P_TRIGGER] = trigger; nodeCollisionData_[NodeCollision::P_CONTACTS] = contacts_.GetBuffer(); if (newCollision) { nodeA->SendEvent(E_NODECOLLISIONSTART, nodeCollisionData_); if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; } nodeA->SendEvent(E_NODECOLLISION, nodeCollisionData_); if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; // Flip perspective to body B contacts_.Clear(); contactManifold = i->second_.manifold_; if (contactManifold) { for (int j = 0; j < contactManifold->getNumContacts(); ++j) { btManifoldPoint& point = contactManifold->getContactPoint(j); contacts_.WriteVector3(ToVector3(point.m_positionWorldOnB)); contacts_.WriteVector3(-ToVector3(point.m_normalWorldOnB)); contacts_.WriteFloat(point.m_distance1); contacts_.WriteFloat(point.m_appliedImpulse); } } contactManifold = i->second_.flippedManifold_; if (contactManifold) { for (int j = 0; j < contactManifold->getNumContacts(); ++j) { btManifoldPoint& point = contactManifold->getContactPoint(j); contacts_.WriteVector3(ToVector3(point.m_positionWorldOnB)); contacts_.WriteVector3(ToVector3(point.m_normalWorldOnB)); contacts_.WriteFloat(point.m_distance1); contacts_.WriteFloat(point.m_appliedImpulse); } } nodeCollisionData_[NodeCollision::P_BODY] = bodyB; nodeCollisionData_[NodeCollision::P_OTHERNODE] = nodeA; nodeCollisionData_[NodeCollision::P_OTHERBODY] = bodyA; nodeCollisionData_[NodeCollision::P_CONTACTS] = contacts_.GetBuffer(); if (newCollision) { nodeB->SendEvent(E_NODECOLLISIONSTART, nodeCollisionData_); if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; } nodeB->SendEvent(E_NODECOLLISION, nodeCollisionData_); } } // Send collision end events as applicable { physicsCollisionData_[PhysicsCollisionEnd::P_WORLD] = this; for (HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, ManifoldPair>::Iterator i = previousCollisions_.Begin(); i != previousCollisions_.End(); ++i) { if (!currentCollisions_.Contains(i->first_)) { RigidBody* bodyA = i->first_.first_; RigidBody* bodyB = i->first_.second_; if (!bodyA || !bodyB) continue; bool trigger = bodyA->IsTrigger() || bodyB->IsTrigger(); // Skip collision event signaling if both objects are static, or if collision event mode does not match if (bodyA->GetMass() == 0.0f && bodyB->GetMass() == 0.0f) continue; if (bodyA->GetCollisionEventMode() == COLLISION_NEVER || bodyB->GetCollisionEventMode() == COLLISION_NEVER) continue; if (bodyA->GetCollisionEventMode() == COLLISION_ACTIVE && bodyB->GetCollisionEventMode() == COLLISION_ACTIVE && !bodyA->IsActive() && !bodyB->IsActive()) continue; Node* nodeA = bodyA->GetNode(); Node* nodeB = bodyB->GetNode(); WeakPtr<Node> nodeWeakA(nodeA); WeakPtr<Node> nodeWeakB(nodeB); physicsCollisionData_[PhysicsCollisionEnd::P_BODYA] = bodyA; physicsCollisionData_[PhysicsCollisionEnd::P_BODYB] = bodyB; physicsCollisionData_[PhysicsCollisionEnd::P_NODEA] = nodeA; physicsCollisionData_[PhysicsCollisionEnd::P_NODEB] = nodeB; physicsCollisionData_[PhysicsCollisionEnd::P_TRIGGER] = trigger; SendEvent(E_PHYSICSCOLLISIONEND, physicsCollisionData_); // Skip rest of processing if either of the nodes or bodies is removed as a response to the event if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; nodeCollisionData_[NodeCollisionEnd::P_BODY] = bodyA; nodeCollisionData_[NodeCollisionEnd::P_OTHERNODE] = nodeB; nodeCollisionData_[NodeCollisionEnd::P_OTHERBODY] = bodyB; nodeCollisionData_[NodeCollisionEnd::P_TRIGGER] = trigger; nodeA->SendEvent(E_NODECOLLISIONEND, nodeCollisionData_); if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; nodeCollisionData_[NodeCollisionEnd::P_BODY] = bodyB; nodeCollisionData_[NodeCollisionEnd::P_OTHERNODE] = nodeA; nodeCollisionData_[NodeCollisionEnd::P_OTHERBODY] = bodyA; nodeB->SendEvent(E_NODECOLLISIONEND, nodeCollisionData_); } } } previousCollisions_ = currentCollisions_; }
/// Perform an integration step of duration 'timeStep'. bool CcdPhysicsEnvironment::proceedDeltaTimeOneStep(float timeStep) { //printf("CcdPhysicsEnvironment::proceedDeltaTime\n"); if (SimdFuzzyZero(timeStep)) return true; if (m_debugDrawer) { gDisableDeactivation = (m_debugDrawer->GetDebugMode() & IDebugDraw::DBG_NoDeactivation); } #ifdef USE_QUICKPROF Profiler::beginBlock("SyncMotionStates"); #endif //USE_QUICKPROF //this is needed because scaling is not known in advance, and scaling has to propagate to the shape if (!m_scalingPropagated) { SyncMotionStates(timeStep); m_scalingPropagated = true; } #ifdef USE_QUICKPROF Profiler::endBlock("SyncMotionStates"); Profiler::beginBlock("predictIntegratedTransform"); #endif //USE_QUICKPROF { // std::vector<CcdPhysicsController*>::iterator i; int k; for (k=0;k<GetNumControllers();k++) { CcdPhysicsController* ctrl = m_controllers[k]; // SimdTransform predictedTrans; RigidBody* body = ctrl->GetRigidBody(); body->m_cachedInvertedWorldTransform = body->m_worldTransform.inverse(); if (body->IsActive()) { if (!body->IsStatic()) { body->applyForces( timeStep); body->integrateVelocities( timeStep); body->predictIntegratedTransform(timeStep,body->m_interpolationWorldTransform); } } } } #ifdef USE_QUICKPROF Profiler::endBlock("predictIntegratedTransform"); #endif //USE_QUICKPROF OverlappingPairCache* scene = m_collisionWorld->GetPairCache(); // // collision detection (?) // #ifdef USE_QUICKPROF Profiler::beginBlock("DispatchAllCollisionPairs"); #endif //USE_QUICKPROF int numsubstep = m_numIterations; DispatcherInfo dispatchInfo; dispatchInfo.m_timeStep = timeStep; dispatchInfo.m_stepCount = 0; dispatchInfo.m_enableSatConvex = m_enableSatCollisionDetection; dispatchInfo.m_debugDraw = this->m_debugDrawer; scene->RefreshOverlappingPairs(); GetCollisionWorld()->GetDispatcher()->DispatchAllCollisionPairs(&scene->GetOverlappingPair(0),scene->GetNumOverlappingPairs(),dispatchInfo); #ifdef USE_QUICKPROF Profiler::endBlock("DispatchAllCollisionPairs"); #endif //USE_QUICKPROF int numRigidBodies = m_controllers.size(); m_islandManager->UpdateActivationState(GetCollisionWorld(),GetCollisionWorld()->GetDispatcher()); { int i; int numConstraints = m_constraints.size(); for (i=0;i< numConstraints ; i++ ) { TypedConstraint* constraint = m_constraints[i]; const RigidBody* colObj0 = &constraint->GetRigidBodyA(); const RigidBody* colObj1 = &constraint->GetRigidBodyB(); if (((colObj0) && ((colObj0)->mergesSimulationIslands())) && ((colObj1) && ((colObj1)->mergesSimulationIslands()))) { if (colObj0->IsActive() || colObj1->IsActive()) { m_islandManager->GetUnionFind().unite((colObj0)->m_islandTag1, (colObj1)->m_islandTag1); } } } } m_islandManager->StoreIslandActivationState(GetCollisionWorld()); //contacts #ifdef USE_QUICKPROF Profiler::beginBlock("SolveConstraint"); #endif //USE_QUICKPROF //solve the regular constraints (point 2 point, hinge, etc) for (int g=0;g<numsubstep;g++) { // // constraint solving // int i; int numConstraints = m_constraints.size(); //point to point constraints for (i=0;i< numConstraints ; i++ ) { TypedConstraint* constraint = m_constraints[i]; constraint->BuildJacobian(); constraint->SolveConstraint( timeStep ); } } #ifdef USE_QUICKPROF Profiler::endBlock("SolveConstraint"); #endif //USE_QUICKPROF //solve the vehicles #ifdef NEW_BULLET_VEHICLE_SUPPORT //vehicles int numVehicles = m_wrapperVehicles.size(); for (int i=0;i<numVehicles;i++) { WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i]; RaycastVehicle* vehicle = wrapperVehicle->GetVehicle(); vehicle->UpdateVehicle( timeStep); } #endif //NEW_BULLET_VEHICLE_SUPPORT struct InplaceSolverIslandCallback : public SimulationIslandManager::IslandCallback { ContactSolverInfo& m_solverInfo; ConstraintSolver* m_solver; IDebugDraw* m_debugDrawer; InplaceSolverIslandCallback( ContactSolverInfo& solverInfo, ConstraintSolver* solver, IDebugDraw* debugDrawer) :m_solverInfo(solverInfo), m_solver(solver), m_debugDrawer(debugDrawer) { } virtual void ProcessIsland(PersistentManifold** manifolds,int numManifolds) { m_solver->SolveGroup( manifolds, numManifolds,m_solverInfo,m_debugDrawer); } }; m_solverInfo.m_friction = 0.9f; m_solverInfo.m_numIterations = m_numIterations; m_solverInfo.m_timeStep = timeStep; m_solverInfo.m_restitution = 0.f;//m_restitution; InplaceSolverIslandCallback solverCallback( m_solverInfo, m_solver, m_debugDrawer); #ifdef USE_QUICKPROF Profiler::beginBlock("BuildAndProcessIslands"); #endif //USE_QUICKPROF /// solve all the contact points and contact friction m_islandManager->BuildAndProcessIslands(GetCollisionWorld()->GetDispatcher(),m_collisionWorld->GetCollisionObjectArray(),&solverCallback); #ifdef USE_QUICKPROF Profiler::endBlock("BuildAndProcessIslands"); Profiler::beginBlock("CallbackTriggers"); #endif //USE_QUICKPROF CallbackTriggers(); #ifdef USE_QUICKPROF Profiler::endBlock("CallbackTriggers"); Profiler::beginBlock("proceedToTransform"); #endif //USE_QUICKPROF { { UpdateAabbs(timeStep); float toi = 1.f; if (m_ccdMode == 3) { DispatcherInfo dispatchInfo; dispatchInfo.m_timeStep = timeStep; dispatchInfo.m_stepCount = 0; dispatchInfo.m_dispatchFunc = DispatcherInfo::DISPATCH_CONTINUOUS; //pairCache->RefreshOverlappingPairs();//?? GetCollisionWorld()->GetDispatcher()->DispatchAllCollisionPairs(&scene->GetOverlappingPair(0),scene->GetNumOverlappingPairs(),dispatchInfo); toi = dispatchInfo.m_timeOfImpact; } // // integrating solution // { std::vector<CcdPhysicsController*>::iterator i; for (i=m_controllers.begin(); !(i==m_controllers.end()); i++) { CcdPhysicsController* ctrl = *i; SimdTransform predictedTrans; RigidBody* body = ctrl->GetRigidBody(); if (body->IsActive()) { if (!body->IsStatic()) { body->predictIntegratedTransform(timeStep* toi, predictedTrans); body->proceedToTransform( predictedTrans); } } } } // // disable sleeping physics objects // std::vector<CcdPhysicsController*> m_sleepingControllers; std::vector<CcdPhysicsController*>::iterator i; for (i=m_controllers.begin(); !(i==m_controllers.end()); i++) { CcdPhysicsController* ctrl = (*i); RigidBody* body = ctrl->GetRigidBody(); ctrl->UpdateDeactivation(timeStep); if (ctrl->wantsSleeping()) { if (body->GetActivationState() == ACTIVE_TAG) body->SetActivationState( WANTS_DEACTIVATION ); } else { if (body->GetActivationState() != DISABLE_DEACTIVATION) body->SetActivationState( ACTIVE_TAG ); } if (useIslands) { if (body->GetActivationState() == ISLAND_SLEEPING) { m_sleepingControllers.push_back(ctrl); } } else { if (ctrl->wantsSleeping()) { m_sleepingControllers.push_back(ctrl); } } } } #ifdef USE_QUICKPROF Profiler::endBlock("proceedToTransform"); Profiler::beginBlock("SyncMotionStates"); #endif //USE_QUICKPROF SyncMotionStates(timeStep); #ifdef USE_QUICKPROF Profiler::endBlock("SyncMotionStates"); Profiler::endProfilingCycle(); #endif //USE_QUICKPROF #ifdef NEW_BULLET_VEHICLE_SUPPORT //sync wheels for vehicles int numVehicles = m_wrapperVehicles.size(); for (int i=0;i<numVehicles;i++) { WrapperVehicle* wrapperVehicle = m_wrapperVehicles[i]; wrapperVehicle->SyncWheels(); } #endif //NEW_BULLET_VEHICLE_SUPPORT } return true; }