/// collision callback - only for fluid triggers //------------------------------------------------------------------------------------------------------------------------------- void DynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) { btDiscreteDynamicsWorld::solveConstraints(solverInfo); int numManifolds = getDispatcher()->getNumManifolds(); for (int i=0; i < numManifolds; ++i) // pairs { btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i); btCollisionObject* bA = static_cast<btCollisionObject*>(contactManifold->getBody0()); btCollisionObject* bB = static_cast<btCollisionObject*>(contactManifold->getBody1()); void* pA = bA->getUserPointer(), *pB = bB->getUserPointer(); //if (pA && pB) { ShapeData* sdA = (ShapeData*)pA, *sdB = (ShapeData*)pB, *sdCar=0, *sdFluid=0, *sdWheel=0; if (sdA) { if (sdA->type == ST_Car) sdCar = sdA; else if (sdA->type == ST_Fluid) sdFluid = sdA; else if (sdA->type == ST_Wheel) sdWheel = sdA; } if (sdB) { if (sdB->type == ST_Car) sdCar = sdB; else if (sdB->type == ST_Fluid) sdFluid = sdB; else if (sdB->type == ST_Wheel) sdWheel = sdB; } if (sdFluid) /// wheel - fluid -----~~~------~~~----- if (sdWheel) { std::list<FluidBox*>& fl = sdWheel->pCarDyn->inFluidsWh[sdWheel->whNum]; if (fl.empty()) fl.push_back(sdFluid->pFluid); // add fluid to wheel (only 1) //LogO("Wheel+ Fluid " + toStr(sdWheel->whNum)); }else if (sdCar) /// car - fluid -----~~~------~~~----- { if (sdCar->pCarDyn->inFluids.empty()) sdCar->pCarDyn->inFluids.push_back(sdFluid->pFluid); // add fluid to car (only 1) } } } }
LRESULT CommonWid::onMax( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { if (::IsMaximized(getDispatcher()->getHwnd())) { m_pBtnMax->setText(L"¿Ú"); return ::SendMessageW(getDispatcher()->getHwnd(), WM_SYSCOMMAND, SC_RESTORE, 0); } m_pBtnMax->setText(L"ÂÀ"); return ::SendMessageW(getDispatcher()->getHwnd(), WM_SYSCOMMAND, SC_MAXIMIZE, 0); }
void DynamicsWorld::fractureCallback() { #if (BT_BULLET_VERSION < 281) m_activeConnections.resize(0); int numManifolds = getDispatcher()->getNumManifolds(); for (int i = 0; i < numManifolds; ++i) { btPersistentManifold* manifold = getDispatcher()->getManifoldByIndexInternal(i); if (!manifold->getNumContacts()) continue; FractureBody* body = static_cast<FractureBody*>(manifold->getBody0()); if (body->getInternalType() & CO_FRACTURE_TYPE) { for (int k = 0; k < manifold->getNumContacts(); ++k) { btManifoldPoint& point = manifold->getContactPoint(k); int con_id = body->getConnectionId(point.m_index0); if (point.m_appliedImpulse > 1E-3 && body->applyImpulse(con_id, point.m_appliedImpulse)) { m_activeConnections.push_back(ActiveCon(body, con_id)); } } } body = static_cast<FractureBody*>(manifold->getBody1()); if (body->getInternalType() & CO_FRACTURE_TYPE) { for (int k = 0; k < manifold->getNumContacts(); ++k) { btManifoldPoint& point = manifold->getContactPoint(k); int con_id = body->getConnectionId(point.m_index1); if (point.m_appliedImpulse > 1E-3 && body->applyImpulse(con_id, point.m_appliedImpulse)) { m_activeConnections.push_back(ActiveCon(body, con_id)); } } } } // Update active connections. for (int i = 0; i < m_activeConnections.size(); ++i) { int con_id = m_activeConnections[i].id; FractureBody* body = m_activeConnections[i].body; btRigidBody* child = body->updateConnection(con_id); if (child) addRigidBody(child); } #endif }
///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected. ///it reports one or more contact points (including the one with deepest penetration) void btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback) { btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(colObjA,colObjB); if (algorithm) { btBridgedManifoldResult contactPointResult(colObjA,colObjB, resultCallback); //discrete collision detection query algorithm->processCollision(colObjA,colObjB, getDispatchInfo(),&contactPointResult); algorithm->~btCollisionAlgorithm(); getDispatcher()->freeCollisionAlgorithm(algorithm); } }
PUBLIC int runCmd(cchar *command, char *input, char **output, char **error, MprTime timeout, int flags) { MprCmd *cmd; cmd = mprCreateCmd(getDispatcher()); return mprRunCmd(cmd, command, NULL, input, output, error, timeout, MPR_CMD_IN | MPR_CMD_OUT | MPR_CMD_ERR | flags); }
void btContinuousDynamicsWorld::calculateTimeOfImpacts(btScalar timeStep) { ///these should be 'temporal' aabbs! updateTemporalAabbs(timeStep); ///'toi' is the global smallest time of impact. However, we just calculate the time of impact for each object individually. ///so we handle the case moving versus static properly, and we cheat for moving versus moving btScalar toi = 1.f; btDispatcherInfo& dispatchInfo = getDispatchInfo(); dispatchInfo.m_timeStep = timeStep; dispatchInfo.m_timeOfImpact = 1.f; dispatchInfo.m_stepCount = 0; dispatchInfo.m_dispatchFunc = btDispatcherInfo::DISPATCH_CONTINUOUS; ///calculate time of impact for overlapping pairs btDispatcher* dispatcher = getDispatcher(); if (dispatcher) dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1); toi = dispatchInfo.m_timeOfImpact; dispatchInfo.m_dispatchFunc = btDispatcherInfo::DISPATCH_DISCRETE; }
void World::reset() { getBroadphase()->resetPool(getDispatcher()); m_nonStaticRigidBodies.resize(0); m_collisionObjects.resize(0); //rayTestProc = 0; }
void DynamicsWorld::reset() { getBroadphase()->resetPool(getDispatcher()); m_nonStaticRigidBodies.resize(0); m_collisionObjects.resize(0); track = 0; }
void btCollisionWorld::performDiscreteCollisionDetection() { btDispatcherInfo& dispatchInfo = getDispatchInfo(); BEGIN_PROFILE("perform Broadphase Collision Detection"); //update aabb (of all moved objects) btVector3 aabbMin,aabbMax; for (int i=0;i<m_collisionObjects.size();i++) { m_collisionObjects[i]->getCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),aabbMin,aabbMax); m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax); } m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1); END_PROFILE("perform Broadphase Collision Detection"); BEGIN_PROFILE("performDiscreteCollisionDetection"); btDispatcher* dispatcher = getDispatcher(); if (dispatcher) dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1); END_PROFILE("performDiscreteCollisionDetection"); }
int PushCliConn::handlePush(const Json::Value& vrequest){ //PSLogTrace("PushServer") << "<action:handlePush> <conid:" << getId() << ">"; Dispatcher* d = getDispatcher(); if(!d){ PSLogError("PushServer") << "<action:handlePush> <conid:" << getId() << "> <status: Dispatcher:NULL>"; return -1; } if(!pushRequestJsonCheck(vrequest)){ PSLogError("PushServer") << "<action:handlePush> <conid:" << getId() << "> <status: pushRequestJsonCheck error>"; return PS_RESULT_ARGS_ERROR; } Message msg; messageJsonToProtobuf(vrequest,msg); const std::string& to = msg.to(); const std::string& sn = msg.sn(); std::string mkey = MSG_KEY(to); std::string idkey = LAST_MSG_ID_KEY(to); int64 msgid =-1; int ret = PushMsgDBM::MQ()->incrId(to, idkey, msgid); if(ret < 0){ PSLogError("PushServer") << "<action:handlePush> <conid:" << getId() << "> <status: incrId error:" << ret << ">"; return PS_RESULT_INCR_MSGID_ERROR; } msg.set_id(msgid); ret = sendJ2C(msg); if(msg.expire() > 0){ if(PushMsgDBM::MQ()->add(to, mkey, msg) < 0){ PSLogError("PushServer") << "<action:handlePush> <conid:" << getId() << "> <status: addMsg error:>"; } } Json::Value response; response["cmd"] = PS_CMD_CALL_PUSH_RESP; response["result"] = ret; response["sn"] = sn; response["msgid"] = ef::itostr(msgid); std::string respbuf; head rh; rh.magic = MAGIC_NUMBER; rh.cmd = SERVICE_RESP; rh.len = 0; constructPacket(rh, Json::FastWriter().write(response), respbuf); ret = sendMessage(respbuf); return 0; }
LRESULT CommonWnd::onCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { WFX_CONDITION(m_pRoot != NULL); LONG styleValue = ::GetWindowLongW(*this, GWL_STYLE); styleValue &= ~WS_CAPTION; ::SetWindowLongW(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); Rect rc; m_pRoot->create(rc, NULL, getDispatcher()); sendMessage(WUM_WIDROOT_CREATE); return 1; }
OTSYS_THREAD_RETURN Dispatcher::dispatcherThread(void* p) { #if defined __EXCEPTION_TRACER__ ExceptionHandler dispatcherExceptionHandler; dispatcherExceptionHandler.InstallHandler(); #endif srand((uint32_t)OTSYS_TIME()); OutputMessagePool* outputPool = NULL; while(Dispatcher::m_threadState != Dispatcher::STATE_TERMINATED) { Task* task = NULL; // check if there are tasks waiting OTSYS_THREAD_LOCK(getDispatcher().m_taskLock, ""); if(getDispatcher().m_taskList.empty()) //if the list is empty wait for signal OTSYS_THREAD_WAITSIGNAL(getDispatcher().m_taskSignal, getDispatcher().m_taskLock); if(!getDispatcher().m_taskList.empty() && Dispatcher::m_threadState != Dispatcher::STATE_TERMINATED) { // take the first task task = getDispatcher().m_taskList.front(); getDispatcher().m_taskList.pop_front(); } OTSYS_THREAD_UNLOCK(getDispatcher().m_taskLock, ""); // finally execute the task... if(!task) continue; if(!task->hasExpired()) { if((outputPool = OutputMessagePool::getInstance())) outputPool->startExecutionFrame(); (*task)(); if(outputPool) outputPool->sendAll(); g_game.clearSpectatorCache(); } delete task; } #if defined __EXCEPTION_TRACER__ dispatcherExceptionHandler.RemoveHandler(); #endif #if not defined(WIN32) return NULL; #endif }
void Dispatcher::flush() { Task* task = NULL; while(!m_taskList.empty()){ task = getDispatcher().m_taskList.front(); m_taskList.pop_front(); (*task)(); delete task; OutputMessagePool::getInstance()->sendAll(); g_game.clearSpectatorCache(); } }
int PushCliConn::sendJ2C(const Message& m){ Json::Value v; v["cmd"] = PS_CMD_PUSH_REQUEST; messageProtobufToJson(m, v); ServiceRequest sreq; sreq.set_payload(Json::FastWriter().write(v)); sreq.set_to_type(-1); sreq.set_sn(m.sn()); int ret = getDispatcher()->sendToClient(m.to(), sreq); PSLogTrace("PushServer") << "<action:handle push send2c> <conid:" << getId() << "><to:" << m.to() << "><result=" << ret << ">"; return ret == -20001?0:ret; }
void Dispatcher::flush() { Task* task = NULL; while(!m_taskList.empty()){ task = getDispatcher().m_taskList.front(); m_taskList.pop_front(); (*task)(); delete task; OutputMessagePool::getInstance()->sendAll(); g_game.clearSpectatorCache(); } #ifdef __DEBUG_SCHEDULER__ std::cout << "Flushing Dispatcher" << std::endl; #endif }
OTSYS_THREAD_RETURN Dispatcher::dispatcherThread(void* p) { #if defined __EXCEPTION_TRACER__ ExceptionHandler dispatcherExceptionHandler; dispatcherExceptionHandler.InstallHandler(); #endif srand((unsigned int)OTSYS_TIME()); while(!Dispatcher::m_shutdown){ Task* task = NULL; // check if there are tasks waiting OTSYS_THREAD_LOCK(getDispatcher().m_taskLock, "") if(getDispatcher().m_taskList.empty()){ //if the list is empty wait for signal OTSYS_THREAD_WAITSIGNAL(getDispatcher().m_taskSignal, getDispatcher().m_taskLock); } if(!getDispatcher().m_taskList.empty() && !Dispatcher::m_shutdown){ // take the first task task = getDispatcher().m_taskList.front(); getDispatcher().m_taskList.pop_front(); } OTSYS_THREAD_UNLOCK(getDispatcher().m_taskLock, ""); // finally execute the task... if(task){ OutputMessagePool::getInstance()->startExecutionFrame(); (*task)(); delete task; OutputMessagePool::getInstance()->sendAll(); g_game.clearSpectatorCache(); } } #if defined __EXCEPTION_TRACER__ dispatcherExceptionHandler.RemoveHandler(); #endif #if defined WIN32 || defined __WINDOWS__ // #else return 0; #endif }
void EnemyObject::update(float tick_ms, GameLevel* game_level) { getCurrentAnimation()->update(tick_ms); m_EnemyBehavior(tick_ms, game_level); // Just for demonstration, set up a behavior where the // enemy fires a projectile at the player. m_EnemyBehavior = [this](float tick_ms, GameLevel* level) { sf::Clock& clock = this->m_Clock; sf::Int32 delayBetweenBulletsInMs = 600; if( clock.getElapsedTime().asMilliseconds() > delayBetweenBulletsInMs ) { clock.restart(); } else { return; } float firingDistance = 1000; const sf::Vector2f& playerLocation = level->getPlayerLocation(); float xdiff = (this->getLocation().x - playerLocation.x); float ydiff = (this->getLocation().y - playerLocation.y); float dist = sqrt(xdiff*xdiff+ydiff*ydiff); sf::Vector2f projectileHeading(xdiff/dist, ydiff/dist); if(dist <= firingDistance) { ProjectileObject* projectile = new ProjectileObject( ProjectileType::PROJECTILE_BASIC, CollidesWith::PLAYERS, this ); projectile->init(getDispatcher(), m_GameLevel); projectile->setLocation(getLocation().x, getLocation().y); projectile->setVelocity( -projectileHeading.x * 300, -projectileHeading.y * 300); ProjectileFiredEvent e(projectile); this->getDispatcher()->dispatchEvent(&e); } }; }
void btBulletPhysicsEffectsWorld::solveConstraints(btContactSolverInfo& solverInfo) { BT_PROFILE("solveConstraints"); btCollisionDispatcher* disp = (btCollisionDispatcher*) getDispatcher(); int numBodies = getNumCollisionObjects(); btPersistentManifold** manifolds = disp->getInternalManifoldPointer(); int numManifolds = disp->getNumManifolds(); if ((getNumCollisionObjects()>0) && (numManifolds + m_constraints.size()>0)) { btCollisionObject** bodies = numBodies ? &getCollisionObjectArray()[0] : 0; btTypedConstraint** constraints = m_constraints.size() ? &m_constraints[0] : 0; getConstraintSolver()->solveGroup( bodies,numBodies, disp->getInternalManifoldPointer(),numManifolds, constraints, m_constraints.size() ,m_solverInfo,m_debugDrawer,m_stackAlloc,disp); } }
void MDIParent::create( const Seed & cs ) { CLIENTCREATESTRUCT ccs; ccs.hWindowMenu = cs.windowMenu; ccs.idFirstChild = cs.idFirstChild; HWND wnd = ::CreateWindowEx( cs.exStyle, getDispatcher().getClassName(), cs.caption.c_str(), cs.style, cs.location.x(), cs.location.y(), cs.location.width(), cs.location.height(), getParentHandle(), NULL, ::GetModuleHandle(NULL), reinterpret_cast< LPVOID >( &ccs ) ); if (wnd == NULL) { // The most common error is to forget WS_CHILD in the styles throw Win32Exception("CreateWindowEx failed"); } }
void btCollisionWorld::performDiscreteCollisionDetection() { BT_PROFILE("performDiscreteCollisionDetection"); btDispatcherInfo& dispatchInfo = getDispatchInfo(); updateAabbs(); { BT_PROFILE("calculateOverlappingPairs"); m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1); } btDispatcher* dispatcher = getDispatcher(); { BT_PROFILE("dispatchAllCollisionPairs"); if (dispatcher) dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1); } }
//#include "stdio.h" void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) { BT_PROFILE("integrateTransforms"); btTransform predictedTrans; for ( int i=0;i<m_nonStaticRigidBodies.size();i++) { btRigidBody* body = m_nonStaticRigidBodies[i]; body->setHitFraction(1.f); if (body->isActive() && (!body->isStaticOrKinematicObject())) { body->predictIntegratedTransform(timeStep, predictedTrans); btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); if (body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) { BT_PROFILE("CCD motion clamping"); if (body->getCollisionShape()->isConvex()) { gNumClampedCcdMotions++; 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)) { body->setHitFraction(sweepResults.m_closestHitFraction); body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans); body->setHitFraction(0.f); // printf("clamped integration to hit fraction = %f\n",fraction); } } } body->proceedToTransform( predictedTrans); } } }
void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) { BT_PROFILE("integrateTransforms"); btTransform predictedTrans; for ( int i=0;i<m_nonStaticRigidBodies.size();i++) { btRigidBody* body = m_nonStaticRigidBodies[i]; body->setHitFraction(1.f); if (body->isActive() && (!body->isStaticOrKinematicObject())) { body->predictIntegratedTransform(timeStep, predictedTrans); btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) { BT_PROFILE("CCD motion clamping"); if (body->getCollisionShape()->isConvex()) { gNumClampedCcdMotions++; #ifdef USE_STATIC_ONLY class StaticOnlyCallback : public btClosestNotMeConvexResultCallback { public: StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) { } virtual bool needsCollision(btBroadphaseProxy* proxy0) const { btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; if (!otherObj->isStaticOrKinematicObject()) return false; return btClosestNotMeConvexResultCallback::needsCollision(proxy0); } }; StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); #else btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); #endif //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape()); btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape()); sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration; sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; btTransform modifiedPredictedTrans = predictedTrans; modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) { //printf("clamped integration to hit fraction = %f\n",fraction); body->setHitFraction(sweepResults.m_closestHitFraction); body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans); body->setHitFraction(0.f); body->proceedToTransform( predictedTrans); #if 0 btVector3 linVel = body->getLinearVelocity(); btScalar maxSpeed = body->getCcdMotionThreshold()/getSolverInfo().m_timeStep; btScalar maxSpeedSqr = maxSpeed*maxSpeed; if (linVel.length2()>maxSpeedSqr) { linVel.normalize(); linVel*= maxSpeed; body->setLinearVelocity(linVel); btScalar ms2 = body->getLinearVelocity().length2(); body->predictIntegratedTransform(timeStep, predictedTrans); btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); btScalar smt = body->getCcdSquareMotionThreshold(); printf("sm2=%f\n",sm2); } #else //don't apply the collision response right now, it will happen next frame //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution. //btScalar appliedImpulse = 0.f; //btScalar depth = 0.f; //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth); #endif continue; } } } body->proceedToTransform( predictedTrans); } } ///this should probably be switched on by default, but it is not well tested yet if (m_applySpeculativeContactRestitution) { BT_PROFILE("apply speculative contact restitution"); for (int i=0;i<m_predictiveManifolds.size();i++) { btPersistentManifold* manifold = m_predictiveManifolds[i]; btRigidBody* body0 = btRigidBody::upcast((btCollisionObject*)manifold->getBody0()); btRigidBody* body1 = btRigidBody::upcast((btCollisionObject*)manifold->getBody1()); for (int p=0;p<manifold->getNumContacts();p++) { const btManifoldPoint& pt = manifold->getContactPoint(p); btScalar combinedRestitution = btManifoldResult::calculateCombinedRestitution(body0, body1); if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f) //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f) { btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution; const btVector3& pos1 = pt.getPositionWorldOnA(); const btVector3& pos2 = pt.getPositionWorldOnB(); btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin(); btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin(); if (body0) body0->applyImpulse(imp,rel_pos0); if (body1) body1->applyImpulse(-imp,rel_pos1); } } } } }
void btDiscreteDynamicsWorld::createPredictiveContacts(btScalar timeStep) { BT_PROFILE("createPredictiveContacts"); { BT_PROFILE("release predictive contact manifolds"); for (int i=0;i<m_predictiveManifolds.size();i++) { btPersistentManifold* manifold = m_predictiveManifolds[i]; this->m_dispatcher1->releaseManifold(manifold); } m_predictiveManifolds.clear(); } btTransform predictedTrans; for ( int i=0;i<m_nonStaticRigidBodies.size();i++) { btRigidBody* body = m_nonStaticRigidBodies[i]; body->setHitFraction(1.f); if (body->isActive() && (!body->isStaticOrKinematicObject())) { body->predictIntegratedTransform(timeStep, predictedTrans); btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) { BT_PROFILE("predictive convexSweepTest"); if (body->getCollisionShape()->isConvex()) { gNumClampedCcdMotions++; #ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY class StaticOnlyCallback : public btClosestNotMeConvexResultCallback { public: StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) { } virtual bool needsCollision(btBroadphaseProxy* proxy0) const { btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; if (!otherObj->isStaticOrKinematicObject()) return false; return btClosestNotMeConvexResultCallback::needsCollision(proxy0); } }; StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); #else btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); #endif //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape()); btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape()); sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration; sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; btTransform modifiedPredictedTrans = predictedTrans; modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) { btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction; btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld); btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject); m_predictiveManifolds.push_back(manifold); btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec; btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB; btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance); bool isPredictive = true; int index = manifold->addManifoldPoint(newPoint, isPredictive); btManifoldPoint& pt = manifold->getContactPoint(index); pt.m_combinedRestitution = 0; pt.m_combinedFriction = btManifoldResult::calculateCombinedFriction(body,sweepResults.m_hitCollisionObject); pt.m_positionWorldOnA = body->getWorldTransform().getOrigin(); pt.m_positionWorldOnB = worldPointB; } } } } } }
PUBLIC int runCmd(cchar *command, char *input, char **output, char **error, MprTime timeout, int flags) { return mprRun(getDispatcher(), command, input, output, error, timeout, MPR_CMD_IN | MPR_CMD_OUT | MPR_CMD_ERR | flags); }
void btDiscreteDynamicsWorld::addSpeculativeContacts(btScalar timeStep) { BT_PROFILE("addSpeculativeContacts"); btTransform predictedTrans; for ( int i=0;i<m_nonStaticRigidBodies.size();i++) { btRigidBody* body = m_nonStaticRigidBodies[i]; body->setHitFraction(1.f); if (body->isActive() && (!body->isStaticOrKinematicObject())) { body->predictIntegratedTransform(timeStep, predictedTrans); btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); if (body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) { BT_PROFILE("search speculative contacts"); if (body->getCollisionShape()->isConvex()) { gNumClampedCcdMotions++; 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; btTransform modifiedPredictedTrans; modifiedPredictedTrans = predictedTrans; modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) { btBroadphaseProxy* proxy0 = body->getBroadphaseHandle(); btBroadphaseProxy* proxy1 = sweepResults.m_hitCollisionObject->getBroadphaseHandle(); btBroadphasePair* pair = sweepResults.m_pairCache->findPair(proxy0,proxy1); if (pair) { if (pair->m_algorithm) { btManifoldArray contacts; pair->m_algorithm->getAllContactManifolds(contacts); if (contacts.size()) { btManifoldResult result(body,sweepResults.m_hitCollisionObject); result.setPersistentManifold(contacts[0]); btVector3 vec = (modifiedPredictedTrans.getOrigin()-body->getWorldTransform().getOrigin()); vec*=sweepResults.m_closestHitFraction; btScalar lenSqr = vec.length2(); btScalar depth = 0.f; btVector3 pointWorld = sweepResults.m_hitPointWorld; if (lenSqr>SIMD_EPSILON) { depth = btSqrt(lenSqr); pointWorld -= vec; vec /= depth; } if (contacts[0]->getBody0()==body) { result.addContactPoint(sweepResults.m_hitNormalWorld,pointWorld,depth); #if 0 debugContacts.push_back(sweepResults.m_hitPointWorld);//sweepResults.m_hitPointWorld); debugNormals.push_back(sweepResults.m_hitNormalWorld); #endif } else { //swapped result.addContactPoint(-sweepResults.m_hitNormalWorld,pointWorld,depth); //sweepResults.m_hitPointWorld,depth); #if 0 if (1)//firstHit==1) { firstHit=0; debugNormals.push_back(sweepResults.m_hitNormalWorld); debugContacts.push_back(pointWorld);//sweepResults.m_hitPointWorld); debugNormals.push_back(sweepResults.m_hitNormalWorld); debugContacts.push_back(sweepResults.m_hitPointWorld); } firstHit--; #endif } } } else { //no algorithm, use dispatcher to create one } } else { //add an overlapping pair //printf("pair missing\n"); } } } } } } }
LRESULT CommonWid::onMin( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return ::SendMessage(getDispatcher()->getHwnd(), WM_SYSCOMMAND, SC_MINIMIZE, 0); }
LRESULT CommonWid::onClose( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { return ::SendMessage(getDispatcher()->getHwnd(), WM_CLOSE, 0, 0); }
// Update //------------------------------------------------------------------------------------------------------------------------------- void DynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) { btDiscreteDynamicsWorld::solveConstraints(solverInfo); //vHits.clear(); //inFluids.clear(); //- before update /// collision callback // and bullet hit info for particles and sounds ... int numManifolds = getDispatcher()->getNumManifolds(); //LogO(toStr(numManifolds)); for (int i=0; i < numManifolds; ++i) // pairs { btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i); btCollisionObject* bA = static_cast<btCollisionObject*>(contactManifold->getBody0()); btCollisionObject* bB = static_cast<btCollisionObject*>(contactManifold->getBody1()); /*if (bA->getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE || bB->getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE) /*triggers*/ void* pA = bA->getUserPointer(), *pB = bB->getUserPointer(); //if (pA && pB) { ShapeData* sdA = (ShapeData*)pA, *sdB = (ShapeData*)pB, *sdCar=0, *sdFluid=0, *sdWheel=0; if (sdA) { if (sdA->type == ST_Car) sdCar = sdA; else if (sdA->type == ST_Fluid) sdFluid = sdA; else if (sdA->type == ST_Wheel) sdWheel = sdA; } if (sdB) { if (sdB->type == ST_Car) sdCar = sdB; else if (sdB->type == ST_Fluid) sdFluid = sdB; else if (sdB->type == ST_Wheel) sdWheel = sdB; } if (sdWheel) /// wheel - fluid -----~~~------~~~----- { if (sdFluid) { std::list<FluidBox*>& fl = sdWheel->pCarDyn->inFluidsWh[sdWheel->whNum]; if (fl.empty()) fl.push_back(sdFluid->pFluid); // add fluid to wheel (only 1) //LogO("Wheel+ Fluid " + toStr(sdWheel->whNum)); } }else if (sdCar) if (sdFluid) /// car - fluid -----~~~------~~~----- { if (sdCar->pCarDyn->inFluids.empty()) sdCar->pCarDyn->inFluids.push_back(sdFluid->pFluid); // add fluid to car (only 1) /*int numContacts = contactManifold->getNumContacts(); //if (numContacts > 0) LogO("c"+toStr(numContacts)); for (int j=0; j < numContacts; ++j) { btManifoldPoint& pt = contactManifold->getContactPoint(j); //LogO("Car-Fluid " + toStr(pt.m_index0) + " " + toStr(pt.m_index1) + " " + toStr(pt.m_partId0) + " " + toStr(pt.m_partId1)); }/**/ } else /// car hit { int numContacts = contactManifold->getNumContacts(); //if (numContacts > 0) LogO("c"+toStr(numContacts)); for (int j=0; j < numContacts; ++j) { btManifoldPoint& pt = contactManifold->getContactPoint(j); //LogO(Ogre::String("hit-")+toStr(i)+"-"+toStr(j)+" f "+toStr(f)); DynamicsWorld::Hit hit; hit.pos = pt.getPositionWorldOnA(); hit.norm = pt.m_normalWorldOnB; hit.force = pt.getAppliedImpulse(); hit.sdCar = sdCar; hit.force = std::max(0, 60 - pt.getLifeTime()); hit.vel = sdCar->pCarDyn->velPrev; vHits.push_back(hit); //sdCar->pCarDyn->hitPnts.push_back(pt); ///i } } } } }
void Dispatcher::dispatcherThread(void* p) { #if defined __EXCEPTION_TRACER__ ExceptionHandler dispatcherExceptionHandler; dispatcherExceptionHandler.InstallHandler(); #endif srand((unsigned int)OTSYS_TIME()); #ifdef __DEBUG_SCHEDULER__ std::cout << "Starting Dispatcher" << std::endl; #endif OutputMessagePool* outputPool; // NOTE: second argument defer_lock is to prevent from immediate locking boost::unique_lock<boost::mutex> taskLockUnique(getDispatcher().m_taskLock, boost::defer_lock); while(Dispatcher::m_threadState != Dispatcher::STATE_TERMINATED){ Task* task = NULL; // check if there are tasks waiting taskLockUnique.lock();//getDispatcher().m_taskLock.lock(); if(getDispatcher().m_taskList.empty()){ //if the list is empty wait for signal #ifdef __DEBUG_SCHEDULER__ std::cout << "Dispatcher: Waiting for task" << std::endl; #endif getDispatcher().m_taskSignal.wait(taskLockUnique); } #ifdef __DEBUG_SCHEDULER__ std::cout << "Dispatcher: Signalled" << std::endl; #endif if(!getDispatcher().m_taskList.empty() && (Dispatcher::m_threadState != Dispatcher::STATE_TERMINATED)){ // take the first task task = getDispatcher().m_taskList.front(); getDispatcher().m_taskList.pop_front(); } taskLockUnique.unlock(); // finally execute the task... if(task){ OutputMessagePool::getInstance()->startExecutionFrame(); (*task)(); delete task; outputPool = OutputMessagePool::getInstance(); if(outputPool){ outputPool->sendAll(); } g_game.clearSpectatorCache(); #ifdef __DEBUG_SCHEDULER__ std::cout << "Dispatcher: Executing task" << std::endl; #endif } } #if defined __EXCEPTION_TRACER__ dispatcherExceptionHandler.RemoveHandler(); #endif }
void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) { BT_PROFILE("integrateTransforms"); btTransform predictedTrans; for ( int i=0;i<m_nonStaticRigidBodies.size();i++) { btRigidBody* body = m_nonStaticRigidBodies[i]; body->setHitFraction(1.f); if (body->isActive() && (!body->isStaticOrKinematicObject())) { body->predictIntegratedTransform(timeStep, predictedTrans); btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) { BT_PROFILE("CCD motion clamping"); if (body->getCollisionShape()->isConvex()) { gNumClampedCcdMotions++; #ifdef USE_STATIC_ONLY class StaticOnlyCallback : public btClosestNotMeConvexResultCallback { public: StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) { } virtual bool needsCollision(btBroadphaseProxy* proxy0) const { btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; if (!otherObj->isStaticOrKinematicObject()) return false; return btClosestNotMeConvexResultCallback::needsCollision(proxy0); } }; StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); #else btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); #endif //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape()); btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape()); sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration; sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; btTransform modifiedPredictedTrans = predictedTrans; modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) { //printf("clamped integration to hit fraction = %f\n",fraction); body->setHitFraction(sweepResults.m_closestHitFraction); body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans); body->setHitFraction(0.f); body->proceedToTransform( predictedTrans); #if 0 btVector3 linVel = body->getLinearVelocity(); btScalar maxSpeed = body->getCcdMotionThreshold()/getSolverInfo().m_timeStep; btScalar maxSpeedSqr = maxSpeed*maxSpeed; if (linVel.length2()>maxSpeedSqr) { linVel.normalize(); linVel*= maxSpeed; body->setLinearVelocity(linVel); btScalar ms2 = body->getLinearVelocity().length2(); body->predictIntegratedTransform(timeStep, predictedTrans); btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); btScalar smt = body->getCcdSquareMotionThreshold(); printf("sm2=%f\n",sm2); } #else //response between two dynamic objects without friction, assuming 0 penetration depth btScalar appliedImpulse = 0.f; btScalar depth = 0.f; appliedImpulse = resolveSingleCollision(body,sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth); #endif continue; } } } body->proceedToTransform( predictedTrans); } } }