void PhysicObject::savePhysProperties(FILE* f) { writeChar(isEnabledPhysics(), f); if (!isEnabledPhysics()) return; writeFloat(getMass(), f); writeVector(getAngularFactor(), f); writeVector(getLinearFactor(), f); //writeVector(getLinearVelocity(), f); writeChar(isTrigger(), f); writeChar(getCollisionShapeType(), f); writeChar(isEnableDeactivation(), f); writeFloat(getFriction(), f); writeFloat(getRestitution(), f); writeFloat(getLinearDumping(), f); writeFloat(getAngularDumping(), f); // save custom collision shape if (getCollisionShapeType() == CST_CUSTOM) { if (getCollisionShape() == NULL) Log::error("Can't save custom col. shape. (shape is NULL) id=%s", objectID.c_str()); writeChar(getCollisionShape()->getCollisionShapeType() , f); getCollisionShape()->save(f); } // save constraints writeChar(getConstrains().size(), f); for (unsigned int i = 0; i < getConstrains().size(); i++) { writeChar(getConstrains().at(i)->getType(), f); getConstrains().at(i)->save(f); } }
void btFractureBody::recomputeConnectivity(btCollisionWorld* world) { m_connections.clear(); //@todo use the AABB tree to avoid N^2 checks if (getCollisionShape()->isCompound()) { btCompoundShape* compound = (btCompoundShape*)getCollisionShape(); for (int i=0;i<compound->getNumChildShapes();i++) { for (int j=i+1;j<compound->getNumChildShapes();j++) { struct MyContactResultCallback : public btCollisionWorld::ContactResultCallback { bool m_connected; btScalar m_margin; MyContactResultCallback() :m_connected(false),m_margin(0.05) { } virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) { if (cp.getDistance()<=m_margin) m_connected = true; return 1.f; } }; MyContactResultCallback result; btCollisionObject obA; obA.setWorldTransform(compound->getChildTransform(i)); obA.setCollisionShape(compound->getChildShape(i)); btCollisionObject obB; obB.setWorldTransform(compound->getChildTransform(j)); obB.setCollisionShape(compound->getChildShape(j)); world->contactPairTest(&obA,&obB,result); if (result.m_connected) { btConnection tmp; tmp.m_childIndex0 = i; tmp.m_childIndex1 = j; tmp.m_childShape0 = compound->getChildShape(i); tmp.m_childShape1 = compound->getChildShape(j); tmp.m_strength = 1.f;//?? m_connections.push_back(tmp); } } } } }
float* PhysicObject::getTransformMatrix() { if (rigidBody == NULL) return NULL; GOCollisionShape* cs = getCollisionShape(); btTransform trans = rigidBody->getWorldTransform(); if (cs != NULL) { CVector orient = cs->getOrientation(); if (orient.x != 0.0f || orient.y != 0.0f || orient.z != 0.0f) trans.setRotation(trans.getRotation() * btQuaternion((orient.y*GRAD_TO_RAD_COEF), (orient.x*GRAD_TO_RAD_COEF), (orient.z*GRAD_TO_RAD_COEF))); } trans.getOpenGLMatrix(transformMatrix); transformMatrix[12] = transformMatrix[12] * 100.0f; transformMatrix[13] = transformMatrix[13] * 100.0f; transformMatrix[14] = transformMatrix[14] * 100.0f; if (cs != NULL) { transformMatrix[12] = transformMatrix[12] + cs->getOffset().x; transformMatrix[13] = transformMatrix[13] + cs->getOffset().y; transformMatrix[14] = transformMatrix[14] + cs->getOffset().z; } return transformMatrix; }
btVector3 PhysicsObject::localInertiaBasedOnCollisionShapeAndMass(btScalar mass) { btCollisionShape* collisionShape = getCollisionShape(); btVector3 localInertia; collisionShape->calculateLocalInertia(mass, localInertia); return localInertia; }
btVector3 PhysicsShape::calculateLocalInertia(btScalar mass)const { btVector3 localInertia(0,0,0); if(mass > 0.0f) { getCollisionShape()->calculateLocalInertia(mass, localInertia); } return localInertia; }
btVector3 PhysicsObject::localInertiaBasedOnFirstChildShapeOfCompoundCollisionShapeAndMass(btScalar mass) { btCollisionShape* collisionShape = getCollisionShape(); btCompoundShape* compoundShape = static_cast<btCompoundShape*>(collisionShape); //check error check here btCollisionShape* childCollisionShape = compoundShape->getChildShape(0); btVector3 localInertia; childCollisionShape->calculateLocalInertia(mass, localInertia); return localInertia; }
// 从一个Mesh创建碰撞模型 ICollisionShapePtr OpcodeCollisionSystem::createSubMeshCollisionShape(const String &meshName , const String &subMeshName , const Vector3& position, const Quaternion& orient, const Vector3 &scale) { //check if a shape with this name already exists ICollisionShapePtr shape = getCollisionShape(OpcodeCollisionSubMeshShape::SHAPE_TYPE , meshName + "_" + subMeshName); if(shape.isNull()) { shape.bind(new OpcodeCollisionSubMeshShape()); if(!static_cast<OpcodeCollisionSubMeshShape*>(shape.getPointer())->init(meshName , subMeshName , position , orient , scale)) { shape.setNull(); return ICollisionShapePtr(); } addCollisionShape(shape); } return shape; }
// 从一个顶点和索引缓冲区创建碰撞模型 ICollisionShapePtr OpcodeCollisionSystem::createVertexCollisionShape(const String &name , const Vector3 *vertexBuffer , size_t vertexCount , bool autoDeleteVertex , const uint16 *indexBuffer , size_t indexCount , bool autoDeleteIndex) { //check if a shape with this name already exists ICollisionShapePtr shape = getCollisionShape(OpcodeCollisionVertexShape::SHAPE_TYPE , name); if(shape.isNull()) { shape.bind(new OpcodeCollisionVertexShape()); if(!static_cast<OpcodeCollisionVertexShape*>(shape.getPointer())->init(name , vertexBuffer , vertexCount , autoDeleteVertex , indexBuffer , indexCount , autoDeleteVertex)) { shape.setNull(); return ICollisionShapePtr(); } addCollisionShape(shape); } return shape; }
void PhysicsBodyComponent::_buildRigibody() noexcept { _body->close(); auto collisionShape = this->getComponent<PhysicsShapeComponent>(); if (!collisionShape) return; auto shape = collisionShape->getCollisionShape(); if (!shape) return; auto gameObject = this->getGameObject(); _body->setLayer(gameObject->getLayer()); _body->setWorldTransform(gameObject->getWorldTransform()); _body->setup(shape); }
CsRigidBody* CsRigidBody::Clone() { btScalar cloneMass = btScalar(1.0) / getInvMass(); btVector3 cloneInertia(btScalar(1.0)/getInvInertiaDiagLocal().x(), btScalar(1.0)/getInvInertiaDiagLocal().y(), btScalar(1.0) / getInvInertiaDiagLocal().z()); CsMotionState *motionState = NULL; if (getMotionState()) { CsMotionState *oldState = (CsMotionState*) getMotionState(); motionState = new CsMotionState(*oldState); // set this from outer scope motionState->mObj = NULL; } CsRigidBody *cloneBody = new CsRigidBody(cloneMass, motionState, getCollisionShape(), cloneInertia); return cloneBody; // see test CCDphysics project }
void btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const { getCollisionShape()->getAabb(m_worldTransform,aabbMin,aabbMax); }
PhysicsCollisionShape::Type PhysicsCollisionObject::getShapeType() const { GP_ASSERT(getCollisionShape()); return getCollisionShape()->getType(); }
void PhysicsShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const { getCollisionShape()->getAabb(t, aabbMin, aabbMax); }
void PhysicsShape::setLocalScaling(const btVector3& scaling) { getCollisionShape()->setLocalScaling(scaling); }
btRigidBody *PhysicsShape::createRigidBodyWithShape(float mass, btMotionState* motionState, const btVector3& localInertia) { btRigidBody *rb = new btRigidBody(mass, motionState, getCollisionShape(), localInertia); return rb; }
int PhysicObject::methodsBridge(lua_State* luaVM) { if (isCurrentMethod("applyImpulse")) { applyImpulse(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3)), CVector(lua_tonumber(luaVM, 4), lua_tonumber(luaVM, 5), lua_tonumber(luaVM, 6))); return 0; } if (isCurrentMethod("applyForce")) { applyForce(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3)), CVector(lua_tonumber(luaVM, 4), lua_tonumber(luaVM, 5), lua_tonumber(luaVM, 6))); return 0; } if (isCurrentMethod("setLinearVelocity")) { setLinearVelocity(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3))); return 0; } if (isCurrentMethod("getLinearVelocity")) { luaPushVector(luaVM, getLinearVelocity().x, getLinearVelocity().y, getLinearVelocity().z); return 1; } if (isCurrentMethod("setMass")) { setMass(lua_tonumber(luaVM, 1)); return 0; } if (isCurrentMethod("getMass")) { lua_pushnumber(luaVM, getMass()); return 1; } if (isCurrentMethod("setCollisionShapeType")) { setCollisionShapeType((CollisionShapeType)lua_tointeger(luaVM, 1)); return 0; } if (isCurrentMethod("getCollisionShapeType")) { lua_pushinteger(luaVM, getCollisionShapeType()); return 1; } if (isCurrentMethod("enablePhysics")) { enablePhysics(lua_toboolean(luaVM, 1)); return 0; } if (isCurrentMethod("isEnabledPhysics")) { lua_pushboolean(luaVM, isEnabledPhysics()); return 1; } if (isCurrentMethod("setAngularFactor")) { setAngularFactor(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3))); return 0; } if (isCurrentMethod("getAngularFactor")) { luaPushVector(luaVM, getAngularFactor().x, getAngularFactor().y, getAngularFactor().z); return 1; } if (isCurrentMethod("setLinearFactor")) { setLinearFactor(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3))); return 0; } if (isCurrentMethod("getLinearFactor")) { luaPushVector(luaVM, getLinearFactor().x, getLinearFactor().y, getLinearFactor().z); return 1; } if (isCurrentMethod("setTrigger")) { setTrigger(lua_toboolean(luaVM, 1)); return 0; } if (isCurrentMethod("isTrigger")) { lua_pushboolean(luaVM, isTrigger()); return 1; } if (isCurrentMethod("getCollisionShape")) { if (getCollisionShape() == NULL) { lua_pushnil(luaVM); } else { lua_getglobal(luaVM, getCollisionShape()->getGOID().c_str()); } return 1; } if (isCurrentMethod("setCollisionShape")) { if (lua_isnil(luaVM, 1)) { setCollisionShape(NULL); return 0; } lua_pushstring(luaVM, "cpointer"); lua_gettable(luaVM, -2); GOCollisionShape* o = (GOCollisionShape*)lua_tointeger(luaVM, -1); setCollisionShape(o); lua_pop(luaVM, -1); return 0; } if (isCurrentMethod("setEnableDeactivation")) { setEnableDeactivation(lua_toboolean(luaVM, 1)); return 0; } if (isCurrentMethod("isEnableDeactivation")) { lua_pushboolean(luaVM, isEnableDeactivation()); return 1; } if (isCurrentMethod("setFriction")) { setFriction(lua_tonumber(luaVM, 1)); return 0; } if (isCurrentMethod("getFriction")) { lua_pushnumber(luaVM, getFriction()); return 1; } if (isCurrentMethod("setRestitution")) { setRestitution(lua_tonumber(luaVM, 1)); return 0; } if (isCurrentMethod("getRestitution")) { lua_pushnumber(luaVM, getRestitution()); return 1; } if (isCurrentMethod("setLinearDumping")) { setLinearDumping(lua_tonumber(luaVM, 1)); return 0; } if (isCurrentMethod("getLinearDumping")) { lua_pushnumber(luaVM, getLinearDumping()); return 1; } if (isCurrentMethod("setAngularDumping")) { setAngularDumping(lua_tonumber(luaVM, 1)); return 0; } if (isCurrentMethod("getAngularDumping")) { lua_pushnumber(luaVM, getAngularDumping()); return 1; } if (isCurrentMethod("setAngularVelocity")) { setAngularVelocity(CVector(lua_tonumber(luaVM, 1), lua_tonumber(luaVM, 2), lua_tonumber(luaVM, 3))); return 0; } if (isCurrentMethod("getAngularVelocity")) { CVector av = getAngularVelocity(); luaPushVector(luaVM, av.x, av.y, av.z); return 1; } if (isCurrentMethod("addConstraint")) { if (lua_isnil(luaVM, 1)) { return 0; } lua_pushstring(luaVM, "cpointer"); lua_gettable(luaVM, -2); GOConstraint* o = (GOConstraint*)lua_tointeger(luaVM, -1); addConstraint(o); lua_pop(luaVM, -1); return 0; } if (isCurrentMethod("getConstraints")) { lua_newtable(luaVM); int tableIndex = lua_gettop(luaVM); vector<GOConstraint*> objs; for (unsigned int i = 0; i < constraints.size(); ++i) { if (constraints.at(i)->id == "undefined" || constraints.at(i)->id == "") continue; objs.push_back(constraints.at(i)); } for (unsigned int i = 0; i < objs.size(); ++i) { lua_pushinteger(luaVM, i+1); lua_getglobal(luaVM, objs.at(i)->id.c_str()); lua_settable (luaVM, tableIndex); } return 1; } if (isCurrentMethod("removeConstraint")) { if (lua_isnil(luaVM, 1)) { return 0; } lua_pushstring(luaVM, "cpointer"); lua_gettable(luaVM, -2); GOConstraint* o = (GOConstraint*)lua_tointeger(luaVM, -1); removeConstraint(o); lua_pop(luaVM, -1); return 0; } if (isCurrentMethod("removeAllConstrains")) { removeAllConstraints(); return 0; } if (isCurrentMethod("secondObjectForConstraint")) { if (lua_isnil(luaVM, 1)) { return 0; } lua_pushstring(luaVM, "cpointer"); lua_gettable(luaVM, -2); GOConstraint* o = (GOConstraint*)lua_tointeger(luaVM, -1); secondObjectForConstraint(o); lua_pop(luaVM, -1); return 0; } if (isCurrentMethod("isSecondObjectForConstraints")) { lua_newtable(luaVM); int tableIndex = lua_gettop(luaVM); vector<GOConstraint*> objs; for (unsigned int i = 0; i < secondObjectForConstraints.size(); ++i) { if (secondObjectForConstraints.at(i)->id == "undefined" || secondObjectForConstraints.at(i)->id == "") continue; objs.push_back(secondObjectForConstraints.at(i)); } for (unsigned int i = 0; i < objs.size(); ++i) { lua_pushinteger(luaVM, i+1); lua_getglobal(luaVM, objs.at(i)->id.c_str()); lua_settable (luaVM, tableIndex); } return 1; } if (isCurrentMethod("notUseAsSecondObjectForConstraint")) { if (lua_isnil(luaVM, 1)) { return 0; } lua_pushstring(luaVM, "cpointer"); lua_gettable(luaVM, -2); GOConstraint* o = (GOConstraint*)lua_tointeger(luaVM, -1); notUseAsSecondObjectForConstraint(o); lua_pop(luaVM, -1); return 0; } return LuaBridge::methodsBridge(luaVM); }