bool PhysicsManager::update(float interval) { if (_dynamicsWorld) { _dynamicsWorld->stepSimulation(interval); //optional but useful: debug drawing //m_dynamicsWorld->debugDrawWorld(); int numManifolds = _dynamicsWorld->getDispatcher()->getNumManifolds(); for (int i=0;i<numManifolds;i++) { btPersistentManifold* contactManifold = _dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i); btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0()); btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1()); void* gcA = obA->getUserPointer(); void* gcB = obB->getUserPointer(); if(gcA!= NULL) { PhysicsBody* body = static_cast<PhysicsBody*>(gcA); // optimize for runtime update if(body->needCallBack()) { int numContacts = contactManifold->getNumContacts(); // hack: we know that one body collide with others,the count of contaced point could be more than 1 // but in this system, we just need invoke the registered callbcak function once! so we modify it manually if(numContacts > 1) numContacts = 1; for (int j=0;j<numContacts;j++) { btManifoldPoint& pt = contactManifold->getContactPoint(j); if (pt.getDistance()<0.f) { const btVector3& ptA = pt.getPositionWorldOnA(); const btVector3& ptB = pt.getPositionWorldOnB(); const btVector3& normalOnB = pt.m_normalWorldOnB; int lifeTime = pt.getLifeTime(); void* gcOther = obB->getUserPointer(); // we need convert btVector3 to Ogre::Vecntor3 because we don't need to expose bullet type to lua and we have exposed Ogre type to it Ogre::Vector3 posA(ptA.getX(), ptA.getY(), ptA.getZ()); Ogre::Vector3 posB(ptB.getX(), ptB.getY(), ptB.getZ()); Ogre::Vector3 normal(normalOnB.getX(), normalOnB.getY(), normalOnB.getZ()); // convert the type of parameters if(lifeTime == 1) daisy_object_call_lua(_L, gcA, "startContacted", 10, gcA, "PhysicsBody", gcOther, "PhysicsBody", (void*)&posA, "Ogre::Vector3", (void*)&posB, "Ogre::Vector3", (void*)&normal, "Ogre::Vector3"); else if(lifeTime > 1 ) daisy_object_call_lua(_L, gcA, "contacting", 10, gcA, "PhysicsBody", gcOther, "PhysicsBody", (void*)&posA, "Ogre::Vector3", (void*)&posB, "Ogre::Vector3", (void*)&normal, "Ogre::Vector3"); } } } } if(gcB!= NULL) { PhysicsBody* body = static_cast<PhysicsBody*>(gcB); // optimize for runtime update if(body->needCallBack()) { int numContacts = contactManifold->getNumContacts(); // hack: we know that one body collide with others,the count of contaced point could be more than 1 // but in this system, we just need invoke the registered callbcak function once! so we modify it manually if(numContacts > 1) numContacts = 1; for (int j=0;j<numContacts;j++) { btManifoldPoint& pt = contactManifold->getContactPoint(j); if (pt.getDistance()<0.f) { const btVector3& ptA = pt.getPositionWorldOnA(); const btVector3& ptB = pt.getPositionWorldOnB(); const btVector3& normalOnA = pt.m_positionWorldOnA; int lifeTime = pt.getLifeTime(); void* gcOther = obA->getUserPointer(); // we need convert btVector3 to Ogre::Vecntor3 because we don't need to expose bullet type to lua and we have exposed Ogre type to it Ogre::Vector3 posA(ptA.getX(), ptA.getY(), ptA.getZ()); Ogre::Vector3 posB(ptB.getX(), ptB.getY(), ptB.getZ()); Ogre::Vector3 normal(normalOnA.getX(), normalOnA.getY(), normalOnA.getZ()); if(lifeTime == 1) daisy_object_call_lua(_L, gcB, "startContacted", 10, gcB, "PhysicsBody", gcOther, "PhysicsBody", (void*)(&posB), "Ogre::Vector3", (void*)(&posA), "Ogre::Vector3", (void*)(&normal), "Ogre::Vector3"); else if(lifeTime > 1 ) daisy_object_call_lua(_L, gcB, "contacting", 10, gcB, "PhysicsBody", gcOther, "PhysicsBody", (void*)(&posB), "Ogre::Vector3", (void*)(&posA), "Ogre::Vector3", (void*)(&normal), "Ogre::Vector3"); } } } } } } return true; }