//------------------------------------------- void BlockBehaviourAir::update(float dt) { //simply negate sideways movement and allow gravity to do its thing auto vel = getVelocity(); vel.x *= getFriction(); setVelocity(vel); sf::Int32 cat = getParentCategory(); if (cat & (Category::CarriedOne | Category::CarriedTwo)) { //can't carry blocks which are in the air Event e; e.type = Event::Player; e.player.action = Event::PlayerEvent::Dropped; e.player.playerId = (cat & (Category::CarriedOne)) ? Category::PlayerOne : Category::PlayerTwo; e.player.positionX = 0.f; e.player.positionY = 0.f; raiseEvent(e); } if (getFootSenseMask() == CollisionWorld::Body::Type::Water) //touches water only { setBehaviour<BlockBehaviourWater>(); Event e; e.type = Event::Block; e.block.action = Event::BlockEvent::HitWater; auto pos = getBody()->getCentre(); e.block.positionX = pos.x; e.block.positionY = pos.y; raiseEvent(e); } }
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 Joint::applyPassiveInternalWrenches() { double f = getFriction(); DBGP("Friction coeffs: " << f0 << " " << f1); DBGP("Friction force: " << f); if (f != 0.0) applyInternalWrench(f); f = getSpringForce(); DBGP("Spring force: " << f); applyInternalWrench(-f); }
//------------------------------------------- void PlayerBehaviourGround::update(float dt) { auto vel = getVelocity(); if(vel.y > 0.f) vel.y = 0.f; vel.x *= getFriction(); //TODO equate dt into this setVelocity(vel); //raise start / stop events if (vel.x != 0 && m_lastVelocity.x == 0) { Event e; e.type = Event::Type::Player; e.player.action = Event::PlayerEvent::Moved; raiseEvent(e); } else if (vel.x == 0 && m_lastVelocity.x != 0) { Event e; e.type = Event::Type::Player; e.player.action = Event::PlayerEvent::Stopped; raiseEvent(e); } m_lastVelocity = vel; if ((getFootSenseMask() & (CollisionWorld::Body::Type::Block | CollisionWorld::Body::Type::Solid)) == 0) { setBehaviour<PlayerBehaviourAir>(); //let go of whatever we're holding Event e; e.type = Event::Player; e.player.action = Event::PlayerEvent::Released; e.player.playerId = getParentCategory();// (cat & Category::GrabbedOne) ? Category::PlayerOne : Category::PlayerTwo; auto pos = getBody()->getCentre(); e.player.positionX = pos.x; e.player.positionY = pos.y; raiseEvent(e); } }
void BlockBehaviourAir::resolve(const sf::Vector3f& manifold, CollisionWorld::Body* other) { switch (other->getType()) { case CollisionWorld::Body::Type::Block: //setParentCategory(Category::Block); //reset any previous owners case CollisionWorld::Body::Type::Solid: move(sf::Vector2f(manifold.x, manifold.y) * manifold.z); setVelocity({getVelocity().x, 0.f}); setBehaviour<BlockBehaviourGround>(); Event e; e.type = Event::Block; e.block.action = Event::BlockEvent::HitGround; { auto pos = getBody()->getCentre(); e.block.positionX = pos.x; e.block.positionY = pos.y; } raiseEvent(e); e.block.action = Event::BlockEvent::DragEnd; raiseEvent(e); break; case CollisionWorld::Body::FreeForm: { sf::Vector2f normal(manifold.x, manifold.y); move(normal * manifold.z); setVelocity(Util::Vector::reflect(getVelocity() * getFriction(), normal)); if (getFootSenseMask() & CollisionWorld::Body::FreeForm) setBehaviour<BlockBehaviourGround>(); } break; default: break; } }
void BlockBehaviourGround::update(float dt) { auto vel = getVelocity(); vel.y = 0.f; vel.x *= getFriction(); //TODO equate dt into this setVelocity(vel); if ((getFootSenseMask() & (CollisionWorld::Body::Type::Block | CollisionWorld::Body::Type::Solid)) == 0) { //nothing underneath so should be falling setBehaviour<BlockBehaviourAir>(); auto pos = getBody()->getCentre(); //should set this to not grabbed, but previously owned auto cat = getParentCategory(); if (cat & (Category::GrabbedOne | Category::GrabbedTwo)) { Event e; e.type = Event::Player; e.player.action = Event::PlayerEvent::Released; e.player.playerId = (cat & Category::GrabbedOne) ? Category::PlayerOne : Category::PlayerTwo; e.player.positionX = pos.x; e.player.positionY = pos.y; raiseEvent(e); } Event e; e.type = Event::Block; e.block.action = Event::BlockEvent::DragEnd; e.block.positionX = pos.x; e.block.positionY = pos.y; raiseEvent(e); } sf::Int32 cat = getParentCategory(); if (cat & (Category::CarriedOne | Category::CarriedTwo)) { setBehaviour<BlockBehaviourCarry>(); //stop drag Event e; e.type = Event::Block; e.block.action = Event::BlockEvent::DragEnd; auto pos = getBody()->getCentre(); e.block.positionX = pos.x; e.block.positionY = pos.y; raiseEvent(e); } if (Util::Vector::lengthSquared(m_lastVelocity) < minDragVelocity && Util::Vector::lengthSquared(vel) > minDragVelocity) { //start drag Event e; e.type = Event::Block; e.block.action = Event::BlockEvent::DragStart; auto pos = getBody()->getCentre(); e.block.positionX = pos.x; e.block.positionY = pos.y; raiseEvent(e); } else if (Util::Vector::lengthSquared(m_lastVelocity) > minDragVelocity && Util::Vector::lengthSquared(vel) < minDragVelocity) { //stop drag Event e; e.type = Event::Block; e.block.action = Event::BlockEvent::DragEnd; auto pos = getBody()->getCentre(); e.block.positionX = pos.x; e.block.positionY = pos.y; raiseEvent(e); } m_lastVelocity = vel; }
void PlayerBehaviourAir::resolve(const sf::Vector3f& manifold, CollisionWorld::Body* other) { switch (other->getType()) { case CollisionWorld::Body::Type::Water: setBehaviour<PlayerBehaviourWater>(); break; case CollisionWorld::Body::Type::Solid: case CollisionWorld::Body::Type::Block: move(sf::Vector2f(manifold.x, manifold.y) * manifold.z); if (manifold.y * manifold.z < 0) //contact is below so must be standing on something { setVelocity({ getVelocity().x, 0.f }); setBehaviour<PlayerBehaviourGround>(); Event playerEvent; playerEvent.type = Event::Player; playerEvent.player.playerId = Category::None; playerEvent.player.action = Event::PlayerEvent::Landed; raiseEvent(playerEvent); } break; case CollisionWorld::Body::Type::Player: { move(sf::Vector2f(manifold.x, manifold.y) * manifold.z); auto vel = getVelocity(); if (manifold.x != 0) //players colliding sideways in air { setVelocity({ -vel.x, vel.y }); } else if (manifold.y * manifold.z < 0) { //bounce off players below setVelocity({ vel.x, -vel.y * getFriction() }); } } break; case CollisionWorld::Body::Type::Npc: { //move(sf::Vector2f(manifold.x, manifold.y) * manifold.z); ////bounce off NPCs //auto vel = getVelocity(); //if (manifold.x != 0) // vel.x = -vel.x; //if (manifold.y != 0) // vel.y = -vel.y; //vel *= getFriction(); //setVelocity(vel); kill(); } break; case CollisionWorld::Body::Item: { Event e; e.node.action = Event::NodeEvent::KilledNode; e.node.type = getParentCategory(); e.node.target = Category::Item; e.type = Event::Node; raiseEvent(e); } break; case CollisionWorld::Body::FreeForm: { if (other->getParentCategory() == Category::HatCarried) break; sf::Vector2f normal(manifold.x, manifold.y); move(normal * manifold.z); setVelocity(Util::Vector::reflect(getVelocity() * getFriction(), normal)); } break; default: break; } }
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); }