Added early triangle collisions

This commit is contained in:
Robin Engman 2014-02-26 14:06:02 +01:00
parent 2f19390cd2
commit d5cda4deaa
8 changed files with 79 additions and 42 deletions

View File

@ -142,8 +142,8 @@ void GameState::InitiatePlayer( int id, const std::string &modelName, const floa
this->privData->camera.SetPosition( p->getPos() ); this->privData->camera.SetPosition( p->getPos() );
Float3 offset = Float3( 0.0f ); Float3 offset = Float3( 0.0f );
// DEBUG position of camera so we can see the player model // DEBUG position of camera so we can see the player model
offset.y = p->getScale().y * 5.0f; //offset.y = p->getScale().y * 5.0f;
offset.z = p->getScale().z * -5.0f; //offset.z = p->getScale().z * -5.0f;
// !DEBUG // !DEBUG
this->privData->camera.SetHeadOffset( offset ); this->privData->camera.SetHeadOffset( offset );
this->privData->camera.UpdateOrientation(); this->privData->camera.UpdateOrientation();
@ -187,7 +187,7 @@ bool GameState::Render()
{ {
if(playerObject->second) if(playerObject->second)
{ {
//if( this->privData->myId != playerObject->second->GetId() ) if( this->privData->myId != playerObject->second->GetId() )
{ {
playerObject->second->Render(); playerObject->second->Render();
} }

View File

@ -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); rigidBody = API::Instance().AddCollisionSphere( rigidBodyRadius , rigidWorldRotation , rigidWorldPos , rigidBodyMass, obj->boundingVolume.sphere.restitutionCoeff , obj->boundingVolume.sphere.frictionCoeffStatic , obj->boundingVolume.sphere.frictionCoeffDynamic);
return rigidBody; 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) bool Level::InitiateLevel(std::wstring levelPath)
{ {
LevelLoader ll; LevelLoader ll;
@ -264,6 +296,11 @@ bool Level::InitiateLevel(std::wstring levelPath)
//rigidBody_Static = InitRigidBodyCylinder(staticObjData); //rigidBody_Static = InitRigidBodyCylinder(staticObjData);
} }
else if(staticObjData->boundingVolume.geoType == CollisionGeometryType_CG_MESH)
{
rigidBody_Static = InitRigidBodyMesh(staticObjData);
}
if(rigidBody_Static != NULL) if(rigidBody_Static != NULL)
{ {
// create game object // create game object

View File

@ -38,6 +38,8 @@ namespace GameLogic
bool InitiateLevel(float radius); bool InitiateLevel(float radius);
Oyster::Physics::ICustomBody* InitRigidBodyCube( const ObjectHeader* obj); Oyster::Physics::ICustomBody* InitRigidBodyCube( const ObjectHeader* obj);
Oyster::Physics::ICustomBody* InitRigidBodySphere( 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); Object* CreateGameObj(ObjectHeader* obj, Oyster::Physics::ICustomBody* rigidBody);
/******************************************************** /********************************************************

View File

@ -302,15 +302,15 @@ void Player::Jump()
bool Player::IsWalking() bool Player::IsWalking()
{ {
return (this->rigidBody->GetLambda() < 0.99f); return (this->rigidBody->GetLambdaUp() < 0.99f);
} }
bool Player::IsJumping() bool Player::IsJumping()
{ {
return (this->rigidBody->GetLambda() == 1.0f); return (this->rigidBody->GetLambdaUp() == 1.0f);
} }
bool Player::IsIdle() 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() void Player::Inactivate()

View File

@ -229,15 +229,15 @@ ICustomBody* API_Impl::AddTriangleMesh(const std::wstring fileName, ::Oyster::Ma
SimpleRigidBody* body = new SimpleRigidBody; SimpleRigidBody* body = new SimpleRigidBody;
SimpleRigidBody::State state; SimpleRigidBody::State state;
btBulletWorldImporter bulletFile; btBulletWorldImporter bulletFile(0);
typedef std::codecvt_utf8<wchar_t> convert_typeX; typedef std::codecvt_utf8<wchar_t> convert_typeX;
std::wstring_convert<convert_typeX, wchar_t> converterX; std::wstring_convert<convert_typeX, wchar_t> converterX;
std::string bulletPath = converterX.to_bytes(fileName); //std::string bulletPath = converterX.to_bytes();
// Add collision shape // 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); btCollisionShape* collisionShape = bulletFile.getCollisionShapeByIndex(0);
body->SetCollisionShape(collisionShape); body->SetCollisionShape(collisionShape);
@ -247,8 +247,8 @@ ICustomBody* API_Impl::AddTriangleMesh(const std::wstring fileName, ::Oyster::Ma
// Add rigid body // Add rigid body
btVector3 fallInertia(0, 0, 0); btVector3 fallInertia(0, 0, 0);
collisionShape->calculateLocalInertia(mass, fallInertia); //collisionShape->calculateLocalInertia(mass, fallInertia);
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, motionState, collisionShape, fallInertia); btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(0, motionState, collisionShape, fallInertia);
btRigidBody* rigidBody = new btRigidBody(rigidBodyCI); btRigidBody* rigidBody = new btRigidBody(rigidBodyCI);
rigidBody->setFriction(staticFriction); rigidBody->setFriction(staticFriction);
rigidBody->setRestitution(restitution); rigidBody->setRestitution(restitution);
@ -264,7 +264,7 @@ ICustomBody* API_Impl::AddTriangleMesh(const std::wstring fileName, ::Oyster::Ma
state.dynamicFrictionCoeff = dynamicFriction; state.dynamicFrictionCoeff = dynamicFriction;
state.staticFrictionCoeff = staticFriction; state.staticFrictionCoeff = staticFriction;
state.quaternion = Quaternion(Float3(rotation.xyz), rotation.w); state.quaternion = Quaternion(Float3(rotation.xyz), rotation.w);
state.mass = mass; state.mass = 0;
body->SetState(state); body->SetState(state);
@ -291,7 +291,7 @@ void API_Impl::UpdateWorld()
simpleBody->SetPreviousVelocity(simpleBody->GetLinearVelocity()); simpleBody->SetPreviousVelocity(simpleBody->GetLinearVelocity());
} }
this->dynamicsWorld->stepSimulation(this->timeStep, 10, this->timeStep); this->dynamicsWorld->stepSimulation(this->timeStep, 1, this->timeStep);
ICustomBody::State state; ICustomBody::State state;
@ -314,23 +314,12 @@ void API_Impl::UpdateWorld()
ICustomBody* bodyA = (ICustomBody*)obA->getUserPointer(); ICustomBody* bodyA = (ICustomBody*)obA->getUserPointer();
ICustomBody* bodyB = (ICustomBody*)obB->getUserPointer(); ICustomBody* bodyB = (ICustomBody*)obB->getUserPointer();
int numContacts = contactManifold->getNumContacts(); int numContacts = contactManifold->getNumContacts();
for (int j=0;j<numContacts;j++) for (int j=0;j<numContacts;j++)
{ {
btManifoldPoint& pt = contactManifold->getContactPoint(j); btManifoldPoint& pt = contactManifold->getContactPoint(j);
if (pt.getDistance()<0.f) 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& ptA = pt.getPositionWorldOnA();
const btVector3& ptB = pt.getPositionWorldOnB(); const btVector3& ptB = pt.getPositionWorldOnB();
const btVector3& normalOnB = pt.m_normalWorldOnB; const btVector3& normalOnB = pt.m_normalWorldOnB;

View File

@ -63,7 +63,8 @@ void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
this->rigidBody->setFriction(state.staticFrictionCoeff); this->rigidBody->setFriction(state.staticFrictionCoeff);
this->rigidBody->setRestitution(state.restitutionCoeff); this->rigidBody->setRestitution(state.restitutionCoeff);
btVector3 fallInertia(0, 0, 0); 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->rigidBody->setMassProps(state.mass, fallInertia);
this->state = state; this->state = state;
@ -185,7 +186,8 @@ void SimpleRigidBody::SetAngularFactor(Float factor)
void SimpleRigidBody::SetMass(Float mass) void SimpleRigidBody::SetMass(Float mass)
{ {
btVector3 fallInertia(0, 0, 0); btVector3 fallInertia(0, 0, 0);
collisionShape->calculateLocalInertia(mass, fallInertia); if(mass != 0)
collisionShape->calculateLocalInertia(mass, fallInertia);
this->rigidBody->setMassProps(mass, fallInertia); this->rigidBody->setMassProps(mass, fallInertia);
this->state.mass = mass; this->state.mass = mass;
} }
@ -362,29 +364,25 @@ void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld)
{ {
btTransform xform; btTransform xform;
xform = this->rigidBody->getWorldTransform (); xform = this->rigidBody->getWorldTransform ();
Float3 normalDown = -this->state.centerPos.GetNormalized(); //Float3 normalDown = -xform.getBasis().getColumn(1);
btVector3 down(normalDown.x, normalDown.y, normalDown.z); btVector3 down(-xform.getBasis().getColumn(1));
btVector3 forward = xform.getBasis()[2]; btVector3 forward(xform.getBasis().getColumn(2));
down.normalize (); down.normalize();
forward.normalize(); forward.normalize();
this->raySource[0] = xform.getOrigin(); this->raySource[0] = xform.getOrigin();
this->raySource[1] = 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) 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[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 class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback
{ {
@ -415,6 +413,10 @@ void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld)
if (rayCallback.hasHit()) if (rayCallback.hasHit())
{ {
this->rayLambda[i] = rayCallback.m_closestHitFraction; this->rayLambda[i] = rayCallback.m_closestHitFraction;
if(i == 1 && this->state.mass == 40)
{
btVector3 hitNormal = rayCallback.m_hitNormalWorld;
}
} }
else else
{ {
@ -423,11 +425,16 @@ void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld)
} }
} }
float SimpleRigidBody::GetLambda() const float SimpleRigidBody::GetLambdaUp() const
{ {
return this->rayLambda[0]; return this->rayLambda[0];
} }
float SimpleRigidBody::GetLambdaForward() const
{
return this->rayLambda[1];
}
void SimpleRigidBody::MoveToLimbo() void SimpleRigidBody::MoveToLimbo()
{ {
this->rigidBody->setCollisionFlags(this->rigidBody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); this->rigidBody->setCollisionFlags(this->rigidBody->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);

View File

@ -68,7 +68,8 @@ namespace Oyster
void PreStep(const btCollisionWorld* collisionWorld); void PreStep(const btCollisionWorld* collisionWorld);
float GetLambda() const; float GetLambdaUp() const;
float GetLambdaForward() const;
void MoveToLimbo(); void MoveToLimbo();
void ReleaseFromLimbo(); void ReleaseFromLimbo();

View File

@ -185,7 +185,8 @@ namespace Oyster
********************************************************/ ********************************************************/
virtual void SetCustomTag( void *ref ) = 0; virtual void SetCustomTag( void *ref ) = 0;
virtual float GetLambda() const = 0; virtual float GetLambdaUp() const = 0;
virtual float GetLambdaForward() const = 0;
}; };
} }
} }