From d5cda4deaa652945b3996236702cc8c517e92556 Mon Sep 17 00:00:00 2001 From: Robin Engman Date: Wed, 26 Feb 2014 14:06:02 +0100 Subject: [PATCH] Added early triangle collisions --- .../GameClient/GameClientState/GameState.cpp | 6 +-- Code/Game/GameLogic/Level.cpp | 37 ++++++++++++++++++ Code/Game/GameLogic/Level.h | 2 + Code/Game/GameLogic/Player.cpp | 6 +-- .../Implementation/PhysicsAPI_Impl.cpp | 25 ++++-------- .../Implementation/SimpleRigidBody.cpp | 39 +++++++++++-------- .../Implementation/SimpleRigidBody.h | 3 +- Code/Physics/GamePhysics/PhysicsAPI.h | 3 +- 8 files changed, 79 insertions(+), 42 deletions(-) diff --git a/Code/Game/GameClient/GameClientState/GameState.cpp b/Code/Game/GameClient/GameClientState/GameState.cpp index 7e8a0ee7..fc6f2b2f 100644 --- a/Code/Game/GameClient/GameClientState/GameState.cpp +++ b/Code/Game/GameClient/GameClientState/GameState.cpp @@ -142,8 +142,8 @@ void GameState::InitiatePlayer( int id, const std::string &modelName, const floa this->privData->camera.SetPosition( p->getPos() ); Float3 offset = Float3( 0.0f ); // DEBUG position of camera so we can see the player model - offset.y = p->getScale().y * 5.0f; - offset.z = p->getScale().z * -5.0f; + //offset.y = p->getScale().y * 5.0f; + //offset.z = p->getScale().z * -5.0f; // !DEBUG this->privData->camera.SetHeadOffset( offset ); this->privData->camera.UpdateOrientation(); @@ -187,7 +187,7 @@ bool GameState::Render() { if(playerObject->second) { - //if( this->privData->myId != playerObject->second->GetId() ) + if( this->privData->myId != playerObject->second->GetId() ) { playerObject->second->Render(); } diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index 0f0ab632..446866b4 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -208,6 +208,38 @@ ICustomBody* Level::InitRigidBodySphere( const ObjectHeader* obj) rigidBody = API::Instance().AddCollisionSphere( rigidBodyRadius , rigidWorldRotation , rigidWorldPos , rigidBodyMass, obj->boundingVolume.sphere.restitutionCoeff , obj->boundingVolume.sphere.frictionCoeffStatic , obj->boundingVolume.sphere.frictionCoeffDynamic); return rigidBody; } +ICustomBody* Level::InitRigidBodyMesh( const ObjectHeader* obj) +{ + ICustomBody* rigidBody = NULL; + Oyster::Math::Float3 rigidWorldPos; + Oyster::Math::Float4 rigidWorldRotation; + float rigidBodyMass; + float rigidBodyRadius; + + //offset the rigidPosition from modelspace to worldspace; + rigidWorldPos = (Oyster::Math::Float3)obj->position + (Oyster::Math::Float3)obj->boundingVolume.cgMesh.position; + //scales the position so the collision geomentry is in the right place + rigidWorldPos = rigidWorldPos * obj->scale; + + //offset the rigidRotation from modelspace to worldspace; + Oyster::Math::Quaternion worldPosQuaternion = Oyster::Math::Quaternion(Oyster::Math::Float3(obj->rotation[0],obj->rotation[1],obj->rotation[2]), obj->rotation[3]); + Oyster::Math::Quaternion physicsPosQuaternion = Oyster::Math::Quaternion(Oyster::Math::Float3(obj->boundingVolume.cgMesh.rotation[0],obj->boundingVolume.cgMesh.rotation[1],obj->boundingVolume.cgMesh.rotation[2]), obj->boundingVolume.cgMesh.rotation[3]); + Oyster::Math::Quaternion rigidWorldQuaternion = worldPosQuaternion * physicsPosQuaternion; + + rigidWorldRotation = Oyster::Math::Float4(rigidWorldQuaternion); + + + //mass scaled + rigidBodyMass = obj->scale[0] * obj->scale[1] * obj->scale[2] * obj->boundingVolume.cgMesh.mass; + + //Radius scaled + //rigidBodyRadius = (obj->scale[0]) * obj->boundingVolume.sphere.radius; + //rigidBodyRadius = (obj->scale[0] * obj->scale[1] * obj->scale[2]) * obj->boundingVolume.sphere.radius; + + //create the rigid body + rigidBody = API::Instance().AddTriangleMesh(obj->boundingVolume.cgMesh.filename, rigidWorldRotation , rigidWorldPos , rigidBodyMass, obj->boundingVolume.cgMesh.restitutionCoeff , obj->boundingVolume.cgMesh.frictionCoeffStatic , obj->boundingVolume.cgMesh.frictionCoeffDynamic); + return rigidBody; +} bool Level::InitiateLevel(std::wstring levelPath) { LevelLoader ll; @@ -264,6 +296,11 @@ bool Level::InitiateLevel(std::wstring levelPath) //rigidBody_Static = InitRigidBodyCylinder(staticObjData); } + else if(staticObjData->boundingVolume.geoType == CollisionGeometryType_CG_MESH) + { + rigidBody_Static = InitRigidBodyMesh(staticObjData); + } + if(rigidBody_Static != NULL) { // create game object diff --git a/Code/Game/GameLogic/Level.h b/Code/Game/GameLogic/Level.h index 7d6c25c9..ecd51018 100644 --- a/Code/Game/GameLogic/Level.h +++ b/Code/Game/GameLogic/Level.h @@ -38,6 +38,8 @@ namespace GameLogic bool InitiateLevel(float radius); Oyster::Physics::ICustomBody* InitRigidBodyCube( const ObjectHeader* obj); Oyster::Physics::ICustomBody* InitRigidBodySphere( const ObjectHeader* obj); + Oyster::Physics::ICustomBody* InitRigidBodyMesh( const ObjectHeader* obj); + Object* CreateGameObj(ObjectHeader* obj, Oyster::Physics::ICustomBody* rigidBody); /******************************************************** diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 68bac4e2..49babcc3 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -302,15 +302,15 @@ void Player::Jump() bool Player::IsWalking() { - return (this->rigidBody->GetLambda() < 0.99f); + return (this->rigidBody->GetLambdaUp() < 0.99f); } bool Player::IsJumping() { - return (this->rigidBody->GetLambda() == 1.0f); + return (this->rigidBody->GetLambdaUp() == 1.0f); } bool Player::IsIdle() { - return (this->rigidBody->GetLambda() == 1.0f && this->rigidBody->GetLinearVelocity().GetMagnitude() < 0.0001f); + return (this->rigidBody->GetLambdaUp() == 1.0f && this->rigidBody->GetLinearVelocity().GetMagnitude() < 0.0001f); } void Player::Inactivate() diff --git a/Code/Physics/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/Physics/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index b86f3821..27cd8ba5 100644 --- a/Code/Physics/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/Physics/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -229,15 +229,15 @@ ICustomBody* API_Impl::AddTriangleMesh(const std::wstring fileName, ::Oyster::Ma SimpleRigidBody* body = new SimpleRigidBody; SimpleRigidBody::State state; - btBulletWorldImporter bulletFile; + btBulletWorldImporter bulletFile(0); typedef std::codecvt_utf8 convert_typeX; std::wstring_convert converterX; - std::string bulletPath = converterX.to_bytes(fileName); + //std::string bulletPath = converterX.to_bytes(); // Add collision shape - bulletFile.loadFile(bulletPath.c_str()); + bulletFile.loadFile("C:\\DV1477\\Git Repository\\Danbias\\Bin\\Content\\Worlds\\cgf\\structure_corporation.bullet"); btCollisionShape* collisionShape = bulletFile.getCollisionShapeByIndex(0); body->SetCollisionShape(collisionShape); @@ -247,8 +247,8 @@ ICustomBody* API_Impl::AddTriangleMesh(const std::wstring fileName, ::Oyster::Ma // Add rigid body btVector3 fallInertia(0, 0, 0); - collisionShape->calculateLocalInertia(mass, fallInertia); - btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, motionState, collisionShape, fallInertia); + //collisionShape->calculateLocalInertia(mass, fallInertia); + btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(0, motionState, collisionShape, fallInertia); btRigidBody* rigidBody = new btRigidBody(rigidBodyCI); rigidBody->setFriction(staticFriction); rigidBody->setRestitution(restitution); @@ -264,7 +264,7 @@ ICustomBody* API_Impl::AddTriangleMesh(const std::wstring fileName, ::Oyster::Ma state.dynamicFrictionCoeff = dynamicFriction; state.staticFrictionCoeff = staticFriction; state.quaternion = Quaternion(Float3(rotation.xyz), rotation.w); - state.mass = mass; + state.mass = 0; body->SetState(state); @@ -291,7 +291,7 @@ void API_Impl::UpdateWorld() simpleBody->SetPreviousVelocity(simpleBody->GetLinearVelocity()); } - this->dynamicsWorld->stepSimulation(this->timeStep, 10, this->timeStep); + this->dynamicsWorld->stepSimulation(this->timeStep, 1, this->timeStep); ICustomBody::State state; @@ -314,23 +314,12 @@ void API_Impl::UpdateWorld() ICustomBody* bodyA = (ICustomBody*)obA->getUserPointer(); ICustomBody* bodyB = (ICustomBody*)obB->getUserPointer(); - - int numContacts = contactManifold->getNumContacts(); for (int j=0;jgetContactPoint(j); if (pt.getDistance()<0.f) { - if(bodyA->GetState().mass == 40 && bodyB->GetState().centerPos == Float3::null) - { - const char* breakPoint = "STOP"; - } - if(bodyB->GetState().mass == 40 && bodyA->GetState().centerPos == Float3::null) - { - const char* breakPoint = "STOP"; - } - const btVector3& ptA = pt.getPositionWorldOnA(); const btVector3& ptB = pt.getPositionWorldOnB(); const btVector3& normalOnB = pt.m_normalWorldOnB; diff --git a/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.cpp index 9b9c7739..7fbd44e8 100644 --- a/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -63,7 +63,8 @@ void SimpleRigidBody::SetState( const SimpleRigidBody::State &state ) this->rigidBody->setFriction(state.staticFrictionCoeff); this->rigidBody->setRestitution(state.restitutionCoeff); btVector3 fallInertia(0, 0, 0); - collisionShape->calculateLocalInertia(state.mass, fallInertia); + if(state.mass != 0) + collisionShape->calculateLocalInertia(state.mass, fallInertia); this->rigidBody->setMassProps(state.mass, fallInertia); this->state = state; @@ -185,7 +186,8 @@ void SimpleRigidBody::SetAngularFactor(Float factor) void SimpleRigidBody::SetMass(Float mass) { btVector3 fallInertia(0, 0, 0); - collisionShape->calculateLocalInertia(mass, fallInertia); + if(mass != 0) + collisionShape->calculateLocalInertia(mass, fallInertia); this->rigidBody->setMassProps(mass, fallInertia); this->state.mass = mass; } @@ -362,29 +364,25 @@ void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld) { btTransform xform; xform = this->rigidBody->getWorldTransform (); - Float3 normalDown = -this->state.centerPos.GetNormalized(); - btVector3 down(normalDown.x, normalDown.y, normalDown.z); - btVector3 forward = xform.getBasis()[2]; - down.normalize (); + //Float3 normalDown = -xform.getBasis().getColumn(1); + btVector3 down(-xform.getBasis().getColumn(1)); + btVector3 forward(xform.getBasis().getColumn(2)); + down.normalize(); forward.normalize(); this->raySource[0] = xform.getOrigin(); this->raySource[1] = xform.getOrigin(); - if(this->state.reach.y < 1.0f) - - - Float angle = acos(Float3(0, 1, 0).Dot(this->state.centerPos.GetNormalized())); - //down.setZ(-down.z()); - btVector3 targetPlus = down * this->state.reach.y * btScalar(1.1); - if(this->state.mass == 40) { - const char* breakpoint = "STOP"; + const char* breakPoint = "STOP!"; } + btVector3 targetPlus = down*this->state.reach.y*btScalar(1.1); + this->rayTarget[0] = this->raySource[0] + targetPlus; - this->rayTarget[1] = this->raySource[1] + forward * this->state.reach.y * btScalar(1.1); + targetPlus = this->raySource[1] + forward*this->state.reach.z*btScalar(1.1); + this->rayTarget[1] = btVector3(targetPlus.x(), targetPlus.y(), targetPlus.z()); class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback { @@ -415,6 +413,10 @@ void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld) if (rayCallback.hasHit()) { this->rayLambda[i] = rayCallback.m_closestHitFraction; + if(i == 1 && this->state.mass == 40) + { + btVector3 hitNormal = rayCallback.m_hitNormalWorld; + } } else { @@ -423,11 +425,16 @@ void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld) } } -float SimpleRigidBody::GetLambda() const +float SimpleRigidBody::GetLambdaUp() const { return this->rayLambda[0]; } +float SimpleRigidBody::GetLambdaForward() const +{ + return this->rayLambda[1]; +} + void SimpleRigidBody::MoveToLimbo() { this->rigidBody->setCollisionFlags(this->rigidBody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); diff --git a/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.h b/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.h index 65c59820..dc1158d7 100644 --- a/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/Physics/GamePhysics/Implementation/SimpleRigidBody.h @@ -68,7 +68,8 @@ namespace Oyster void PreStep(const btCollisionWorld* collisionWorld); - float GetLambda() const; + float GetLambdaUp() const; + float GetLambdaForward() const; void MoveToLimbo(); void ReleaseFromLimbo(); diff --git a/Code/Physics/GamePhysics/PhysicsAPI.h b/Code/Physics/GamePhysics/PhysicsAPI.h index a536bdce..3c2ef879 100644 --- a/Code/Physics/GamePhysics/PhysicsAPI.h +++ b/Code/Physics/GamePhysics/PhysicsAPI.h @@ -185,7 +185,8 @@ namespace Oyster ********************************************************/ virtual void SetCustomTag( void *ref ) = 0; - virtual float GetLambda() const = 0; + virtual float GetLambdaUp() const = 0; + virtual float GetLambdaForward() const = 0; }; } }