void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo) { m_internalType=CO_RIGID_BODY; m_linearVelocity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); 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)), setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping); m_linearSleepingThreshold = constructionInfo.m_linearSleepingThreshold; m_angularSleepingThreshold = constructionInfo.m_angularSleepingThreshold; m_optionalMotionState = constructionInfo.m_motionState; m_contactSolverType = 0; m_frictionSolverType = 0; m_additionalDamping = constructionInfo.m_additionalDamping; m_additionalDampingFactor = constructionInfo.m_additionalDampingFactor; m_additionalLinearDampingThresholdSqr = constructionInfo.m_additionalLinearDampingThresholdSqr; m_additionalAngularDampingThresholdSqr = constructionInfo.m_additionalAngularDampingThresholdSqr; m_additionalAngularDampingFactor = constructionInfo.m_additionalAngularDampingFactor; if (m_optionalMotionState) { m_optionalMotionState->getWorldTransform(m_worldTransform); } else { m_worldTransform = constructionInfo.m_startWorldTransform; } m_interpolationWorldTransform = m_worldTransform; m_interpolationLinearVelocity.setValue(0,0,0); m_interpolationAngularVelocity.setValue(0,0,0); //moved to btCollisionObject m_friction = constructionInfo.m_friction; m_restitution = constructionInfo.m_restitution; setCollisionShape( constructionInfo.m_collisionShape ); m_debugBodyId = uniqueId++; setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia); updateInertiaTensor(); m_rigidbodyFlags = 0; m_deltaLinearVelocity.setZero(); m_deltaAngularVelocity.setZero(); m_invMass = m_inverseMass*m_linearFactor; m_pushVelocity.setZero(); m_turnVelocity.setZero(); }
bool ExplosionSpherePhysicsObject::subClassSpecificInitHook() { //Get information from Attribute_ExplosionSphere and MutatorSettings and store in class variables accessible from "onUpdate()" MutatorSettings mutatorSettings; Ammunition ammunition; AttributePtr<Attribute_ExplosionSphere> ptr_explosionSphere; std::vector<int> explosionSphereEntityId = itrPhysics.ownerAt(attributeIndex_)->getAttributes(ATTRIBUTE_EXPLOSIONSPHERE); for(unsigned int i = 0; i < explosionSphereEntityId.size(); i++) { ptr_explosionSphere = itrExplosionSphere.at(explosionSphereEntityId.at(i)); ammunition = mutatorSettings.getStandardAmmunition(ptr_explosionSphere->ammunitionType); FiringMode firingMode = mutatorSettings.getStandardFiringMode(ptr_explosionSphere->firingModeType); float initialRadius = ammunition.explosionSphereInitialRadius * firingMode.explosionSphereModifier; float finalRadius = ammunition.explosionSphereFinalRadius * firingMode.explosionSphereModifier; if(initialRadius > ptr_explosionSphere->currentRadius) { ptr_explosionSphere->currentRadius = initialRadius; } if(finalRadius > explosionSphereFinalRadius_) { explosionSphereFinalRadius_ = finalRadius; } explosionSphereExpansionRate_ = (finalRadius-initialRadius)/ammunition.explosionSphereExplosionDuration; } //Create local collision shape localCollisionShape_ = new btSphereShape(1.0f); setCollisionShape(localCollisionShape_); return true; }
void GOGround::makeCollisionShape() { switch (getCollisionShapeType()) { case CST_AUTOMATIC: { GOCompoundCollisionShape* s = new GOCompoundCollisionShape(); GOBoxCollisionShape* b1 = new GOBoxCollisionShape(CVector(size.x * OBJ_MAP_CELL_SIZE * 2 + OBJ_MAP_CELL_SIZE * 4, OBJ_MAP_CELL_SIZE * 4, size.z * OBJ_MAP_CELL_SIZE * 2 + OBJ_MAP_CELL_SIZE * 4)); b1->setOffset(CVector(0, -(OBJ_MAP_CELL_SIZE * 1), 0)); s->addChild(b1); GOBoxCollisionShape* b2 = new GOBoxCollisionShape(CVector(size.x * OBJ_MAP_CELL_SIZE * 2, size.y * OBJ_MAP_CELL_SIZE * 2, size.z * OBJ_MAP_CELL_SIZE * 2)); b2->setOffset(CVector(0, -(size.y * OBJ_MAP_CELL_SIZE + OBJ_MAP_CELL_SIZE * 2), 0)); s->addChild(b2); setCollisionShape(s); } break; case CST_AUTOMATIC_BOX: makeBoxShape(size * OBJ_MAP_CELL_SIZE * 2); break; case CST_AUTOMATIC_SPHERE: { float radius = size.x; if (radius < size.y) radius = size.y; if (radius < size.z) radius = size.z; makeSphereShape(radius); } break; case CST_AUTOMATIC_CYLINDER: { float diameter = sqrt(size.x * size.x + size.z * size.z); makeCylinderShape(CVector(diameter, size.y)); } break; default: break; } PhysicObject::makeCollisionShape(); }
void updateComponent(Entity &entity, SmartPointer<Component::SpaceshipController> c, double time) { c->resetControls(); auto &inputs = _scene->getEngine().getInstance<Input>(); auto &controls = c->getControls(); auto &keys = c->getKeys(); float yAngle = inputs.getMouseDelta().y * 0.3f; float xAngle = - inputs.getMouseDelta().x * 0.3f; entity->setLocalTransform() = glm::rotate(entity->getLocalTransform(), yAngle, glm::vec3(1, 0, 0)); entity->setLocalTransform() = glm::rotate(entity->getLocalTransform(), xAngle, glm::vec3(0, 1, 0)); // UPDATE KEYS for (unsigned int i = 0; i < controls.size(); ++i) { controls[i] = inputs.getKey(keys[i]); } auto forwardDir = glm::vec3(0,0,1); auto upDir = glm::vec3(0,1,0); auto sideDir = glm::vec3(1,0,0); glm::vec3 direction = glm::vec3(0); if (controls[Component::SpaceshipController::LEFT]) direction += sideDir * (float)(10.0f * time); if (controls[Component::SpaceshipController::RIGHT]) direction -= sideDir * (float)(10.0f * time); if (controls[Component::SpaceshipController::FORWARD]) direction += forwardDir * (float)(10.0f * time); if (controls[Component::SpaceshipController::BACKWARD]) direction -= forwardDir * (float)(10.0f * time); static std::vector<Entity> balls; if (controls[Component::SpaceshipController::SHOOT]) { Entity b = _scene->createEntity(); b->setLocalTransform() = entity->getLocalTransform(); b->addComponent<Component::GraphNode>(); auto rigidBody = b->addComponent<Component::RigidBody>(); rigidBody->setMass(1.0f); rigidBody->setCollisionShape(Component::RigidBody::SPHERE); // rigidBody->getBody().applyCentralImpulse(btVector3(0, 0, 1000)); auto mesh = b->addComponent<Component::MeshRenderer>("model:ball"); mesh->setShader("MaterialBasic"); // _scene->destroy(b); balls.push_back(b); } if (inputs.getKey(SDLK_p)) { for (auto e : balls) _scene->destroy(e); balls.clear(); } entity->setLocalTransform() = glm::translate(entity->getLocalTransform(), direction); }
bool FrustumPhysicsObject::frustumInit(unsigned int attributeIndex,short collisionFilterGroup) { if(attributeIndex < 0) { return false; } attributeIndex_ = attributeIndex; collisionFilterGroup_ = collisionFilterGroup; AttributePtr<Attribute_Camera> ptr_camera = itrCamera_3.at(attributeIndex); btVector3 localInertia; localInertia.setZero(); btCollisionShape* collisionShape = CollisionShapes::Instance()->getFrustumShape(attributeIndex_); btScalar mass = static_cast<btScalar>(1); setMassProps(mass, localInertia); setCollisionShape(collisionShape); btTransform world; AttributePtr<Attribute_Spatial> ptr_spatial = itrCamera_3.at(attributeIndex_)->ptr_spatial; AttributePtr<Attribute_Position> ptr_position = ptr_spatial->ptr_position; world.setOrigin(convert(ptr_position->position)); world.setRotation(convert(ptr_spatial->rotation)); setWorldTransform(world); setCollisionFlags(getCollisionFlags() | CF_NO_CONTACT_RESPONSE); forceActivationState(DISABLE_DEACTIVATION); return true; }
void FrustumPhysicsObject::onUpdate(float delta) { btMatrix3x3 view = convert(itrCamera_3.at(attributeIndex_)->mat_view); btVector3 pos = convert(itrCamera_3.at(attributeIndex_)->ptr_spatial->ptr_position->position); btQuaternion q; view.getRotation(q); btTransform world = getWorldTransform(); world.setRotation(q); world.setOrigin(pos); setWorldTransform(world); setCollisionShape(CollisionShapes::Instance()->getFrustumShape(attributeIndex_)); }
PhysicsInterface::CharacterControllerObject Bullet::createCharacterController(float height, float radius, const Entity* entity) { auto ghostObject = new btPairCachingGhostObject; auto cylinder = new btCylinderShape({radius, height * 0.5f, radius}); ghostObject->setCollisionShape(cylinder); ghostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT); ghostObject->setRestitution(0.0f); auto stepHeight = btScalar(5.0); auto controller = new KinematicCharacterController(ghostObject, cylinder, stepHeight); dynamicsWorld_->addCollisionObject(ghostObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter); dynamicsWorld_->addAction(controller); return new CharacterController(controller, ghostObject, entity); }
bool PhysicsObject::init(unsigned int attributeIndex, short collisionFilterGroup) { if(attributeIndex < 0) { return false; } attributeIndex_ = attributeIndex; collisionFilterGroup_ = collisionFilterGroup; //Get the init data from a physics attribute AttributePtr<Attribute_Physics> ptr_physics = itrPhysics_.at(attributeIndex); btScalar mass = static_cast<btScalar>(ptr_physics->mass); //Resolve mass, local inertia of the collision shape, and also the collision shape itself. btCollisionShape* collisionShape = subClassSpecificCollisionShape(); if(collisionShape != nullptr) { setCollisionShape(collisionShape); } else { ERROR_MESSAGEBOX("Error in PhysicsObject::init. Expected collision shape pointer unexpectedly set to nullptr. Using default shape instead."); setCollisionShape(CollisionShapes::Instance()->getDefaultShape()); } btVector3 localInertia = subClassCalculateLocalInertiaHook(mass); setMassProps(mass, localInertia); //Set inverse mass and inverse local inertia updateInertiaTensor(); if((getCollisionFlags() & btCollisionObject::CF_STATIC_OBJECT)) { btTransform world; AttributePtr<Attribute_Spatial> ptr_spatial = itrPhysics_.at(attributeIndex_)->ptr_spatial; AttributePtr<Attribute_Position> ptr_position = ptr_spatial->ptr_position; world.setOrigin(convert(ptr_position->position)); world.setRotation(convert(ptr_spatial->rotation)); setWorldTransform(world); //Static physics objects: transform once } else { //Non-static physics objects: let a derived btMotionState handle transforms. MotionState* customMotionState = new MotionState(attributeIndex); setMotionState(customMotionState); setAngularVelocity(btVector3(ptr_physics->angularVelocity.x, ptr_physics->angularVelocity.y, ptr_physics->angularVelocity.z)); setLinearVelocity(btVector3(ptr_physics->linearVelocity.x, ptr_physics->linearVelocity.y, ptr_physics->linearVelocity.z)); //Gravity is set after "addRigidBody" for non-static physics objects } if(ptr_physics->collisionResponse) { setCollisionFlags(getCollisionFlags() & ~CF_NO_CONTACT_RESPONSE); //Activate collision response } else { setCollisionFlags(getCollisionFlags() | CF_NO_CONTACT_RESPONSE); //Deactivate collision response } return subClassSpecificInitHook(); }
void PhysicObject::loadPhysProperties(FILE* f) { enablePhysics(readChar(f)); if (!isEnabledPhysics()) return; setMass(readFloat(f)); setAngularFactor(readVector(f)); setLinearFactor(readVector(f)); //writeVector(getLinearVelocity(), f); setTrigger(readChar(f)); setCollisionShapeType((CollisionShapeType)readChar(f)); setEnableDeactivation(readChar(f)); setFriction(readFloat(f)); setRestitution(readFloat(f)); setLinearDumping(readFloat(f)); setAngularDumping(readFloat(f)); // load custom collision shape if (getCollisionShapeType() == CST_CUSTOM) { switch ((GOCollisionShapeType)readChar(f)) { case GOCST_COMPOUND_SHAPE: setCollisionShape(new GOCompoundCollisionShape(f)); break; case GOCST_BOX: setCollisionShape(new GOBoxCollisionShape(f)); break; case GOCST_SPHERE: setCollisionShape(new GOSphereCollisionShape(f)); break; case GOCST_CYLINDER: setCollisionShape(new GOCylinderCollisionShape(f)); break; case GOCST_UNDEFINED: setCollisionShape(new GOUndefinedCollisionShape(f)); break; case GOCST_CAPSULE: setCollisionShape(new GOCapsuleCollisionShape(f)); break; case GOCST_CONE: setCollisionShape(new GOConeCollisionShape(f)); break; case GOCST_MESH: setCollisionShape(new GOMeshCollisionShape(f)); break; default: Log::error("PhysicObject::loadPhysProperties(FILE* f): Undefined custom shape type."); } } // load constraints int c_count = readChar(f); for (int i = 0; i < c_count; i++) { GOConstraint* cs; unsigned char type = readChar(f); switch (type) { case GO_P2P_CONSTRAINT: cs = new GOP2PConstraint(f); break; case GO_HINGE_CONSTRAINT: cs = new GOHingeConstraint(f); break; case GO_SLIDER_CONSTRAINT: cs = new GOSliderConstraint(f); break; default: Log::error("PhysicObject::loadPhysProperties(FILE* f): Undefined constraint type."); } addConstraint(cs); } }
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); }
void PhysicObject::makeCylinderShape(CVector size) { setCollisionShape(new GOCylinderCollisionShape(size)); }
void PhysicObject::makeSphereShape(float radius) { setCollisionShape(new GOSphereCollisionShape(radius)); }
void PhysicObject::makeBoxShape(CVector size) { setCollisionShape(new GOBoxCollisionShape(size)); }