GL - merge with new physics movement

This commit is contained in:
lindaandersson 2014-02-14 13:54:28 +01:00
commit bab3af787c
20 changed files with 335 additions and 512 deletions

View File

@ -17,7 +17,7 @@ Game::PlayerData::PlayerData()
//sbDesc.quaternion = Oyster::Math::Float3(0, Oyster::Math::pi, 0); //sbDesc.quaternion = Oyster::Math::Float3(0, Oyster::Math::pi, 0);
//create rigid body //create rigid body
Oyster::Physics::ICustomBody* rigidBody = Oyster::Physics::API::Instance().AddCollisionBox(size, Oyster::Math::Float4(0, 0, 0, 1), centerPosition, mass, 0.5f, 0.8f, 0.6f ); Oyster::Physics::ICustomBody* rigidBody = Oyster::Physics::API::Instance().AddCharacter(2.0f, 0.5f, Oyster::Math::Float4(0, 0, 0, 1), centerPosition, mass, 0.5f, 0.8f, 0.6f );
rigidBody->SetAngularFactor(0.0f); rigidBody->SetAngularFactor(0.0f);
//create player with this rigid body //create player with this rigid body
this->player = new Player(rigidBody, Player::PlayerCollision, ObjectSpecialType_Player,0,0); this->player = new Player(rigidBody, Player::PlayerCollision, ObjectSpecialType_Player,0,0);

View File

@ -57,7 +57,11 @@ Object* Level::createGameObj(ObjectHeader* obj, ICustomBody* rigidBody)
break; break;
case ObjectSpecialType_StandardBox: case ObjectSpecialType_StandardBox:
{ {
gameObj = new DynamicObject(rigidBody, Object::DefaultCollisionAfter, (ObjectSpecialType)obj->specialTypeID, objID++); int dmg = 50;
Oyster::Math::Float force = 50;
int radie = 10;
gameObj = new ExplosiveCrate(rigidBody, (ObjectSpecialType)obj->specialTypeID, objID++, dmg, force, radie);
//gameObj = new DynamicObject(rigidBody, Object::DefaultCollisionAfter, (ObjectSpecialType)obj->specialTypeID, objID++);
} }
break; break;
case ObjectSpecialType_RedExplosiveBox: case ObjectSpecialType_RedExplosiveBox:
@ -96,7 +100,7 @@ Object* Level::createGameObj(ObjectHeader* obj, ICustomBody* rigidBody)
break; break;
case ObjectSpecialType_JumpPad: case ObjectSpecialType_JumpPad:
{ {
float power = ((JumpPadAttributes*)obj)->power; float power = 500; //((JumpPadAttributes*)obj)->power;
Oyster::Math::Float3 dir = ((JumpPadAttributes*)obj)->direction; Oyster::Math::Float3 dir = ((JumpPadAttributes*)obj)->direction;
Oyster::Math::Float3 pushForce = dir * power; Oyster::Math::Float3 pushForce = dir * power;
gameObj = new JumpPad(rigidBody, (ObjectSpecialType)obj->specialTypeID, objID++ , pushForce); gameObj = new JumpPad(rigidBody, (ObjectSpecialType)obj->specialTypeID, objID++ , pushForce);
@ -354,9 +358,9 @@ void Level::InitiateLevel(float radius)
this->staticObjects.Push(new StaticObject(rigidBody_House, Object::DefaultCollisionAfter, ObjectSpecialType_Generic, idCount++)); this->staticObjects.Push(new StaticObject(rigidBody_House, Object::DefaultCollisionAfter, ObjectSpecialType_Generic, idCount++));
// add jumppad // add jumppad
ICustomBody* rigidBody_Jumppad = API::Instance().AddCollisionBox(Oyster::Math::Float3(1, 1, 1), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(4, 600.3, 0), 5, 0.5f, 0.8f, 0.6f); ICustomBody* rigidBody_Jumppad = API::Instance().AddCollisionBox(Oyster::Math::Float3(1, 1, 1), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(4, 600.3, 0), 5, 0.5f, 0.8f, 0.6f);
this->staticObjects.Push(new JumpPad(rigidBody_Jumppad, ObjectSpecialType_JumpPad,idCount++ ,Oyster::Math::Float3(0,2000,0))); this->staticObjects.Push(new JumpPad(rigidBody_Jumppad, ObjectSpecialType_JumpPad,idCount++ ,Oyster::Math::Float3(0,2000,0)));
rigidBody_Jumppad->SetCustomTag(this->staticObjects[1]);
} }
void Level::AddPlayerToTeam(Player *player, int teamID) void Level::AddPlayerToTeam(Player *player, int teamID)

View File

@ -17,17 +17,36 @@ Player::Player()
Player::Player(Oyster::Physics::ICustomBody *rigidBody, void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID) Player::Player(Oyster::Physics::ICustomBody *rigidBody, void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID)
:DynamicObject(rigidBody, EventOnCollision, type, objectID) :DynamicObject(rigidBody, EventOnCollision, type, objectID)
{ {
this->rigidBody = rigidBody;
Oyster::Math::Float3 centerPosition = Oyster::Math::Float3(0,400,0);
Oyster::Math::Float3 size = Oyster::Math::Float3(0.25f,1.0f,0.5f);
Oyster::Math::Float mass = 60;
Oyster::Math::Float restitutionCoeff = 0.5;
Oyster::Math::Float frictionCoeff_Static = 0.4;
Oyster::Math::Float frictionCoeff_Dynamic = 0.3;
this->rigidBody = Oyster::Physics::API::Instance().AddCollisionBox(size, Oyster::Math::Float4(0, 0, 0, 1), centerPosition, mass, 0.5f, 0.8f, 0.6f );
this->rigidBody->SetAngularFactor(0.0f);
weapon = new Weapon(2,this); weapon = new Weapon(2,this);
this->life = 100; this->life = 100;
this->teamID = -1; this->teamID = teamID;
this->playerState = PLAYER_STATE_IDLE; this->playerState = PLAYER_STATE_IDLE;
this->lookDir = Oyster::Math::Float3(0,0,-1); this->lookDir = Oyster::Math::Float3(0,0,-1);
this->moveDir = Oyster::Math::Float3(0,0,0);
key_forward = 0; key_forward = 0;
key_backward = 0; key_backward = 0;
key_strafeRight = 0; key_strafeRight = 0;
key_strafeLeft = 0; key_strafeLeft = 0;
this->previousPosition = Oyster::Math::Float3(0,0,0);
this->moveDir = Oyster::Math::Float3(0,0,0);
this->moveSpeed = 100;
this->previousMoveSpeed = Oyster::Math::Float3(0,0,0);
} }
Player::Player(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID) Player::Player(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID)
@ -53,11 +72,16 @@ Player::Player(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustom
this->teamID = teamID; this->teamID = teamID;
this->playerState = PLAYER_STATE_IDLE; this->playerState = PLAYER_STATE_IDLE;
this->lookDir = Oyster::Math::Float3(0,0,-1); this->lookDir = Oyster::Math::Float3(0,0,-1);
this->moveDir = Oyster::Math::Float3(0,0,0);
key_forward = 0; key_forward = 0;
key_backward = 0; key_backward = 0;
key_strafeRight = 0; key_strafeRight = 0;
key_strafeLeft = 0; key_strafeLeft = 0;
this->previousPosition = Oyster::Math::Float3(0,0,0);
this->moveDir = Oyster::Math::Float3(0,0,0);
this->moveSpeed = 100;
this->previousMoveSpeed = Oyster::Math::Float3(0,0,0);
} }
Player::~Player(void) Player::~Player(void)
@ -73,48 +97,79 @@ void Player::BeginFrame()
{ {
//weapon->Update(0.002f); //weapon->Update(0.002f);
Object::BeginFrame(); Object::BeginFrame();
Oyster::Math::Float3 forward(0,0,0);
Oyster::Math::Float3 back(0,0,0); //Oyster::Math::Float3 previousFall = this->previousMoveSpeed*-this->rigidBody->GetState().centerPos.GetNormalized();
Oyster::Math::Float3 right(0,0,0); //Oyster::Math::Float3 currentFall = this->rigidBody->GetLinearVelocity()*-this->rigidBody->GetState().centerPos.GetNormalized();
Oyster::Math::Float3 left(0,0,0);
Oyster::Math::Float3 moveDirection(0,0,0); if(this->moveDir != Oyster::Math::Float3::null && this->playerState != PLAYER_STATE_JUMPING)
{
Oyster::Math::Float3 velocity = this->rigidBody->GetLinearVelocity();
Oyster::Math::Float3 lostVelocity = (this->previousMoveSpeed - velocity).GetMagnitude()*this->moveDir;
this->rigidBody->SetLinearVelocity(velocity + lostVelocity - this->moveDir*this->moveSpeed );
}
else
{
if(this->rigidBody->GetLamda() == 1.0f)
{
this->playerState = PLAYER_STATE_WALKING;
}
if(this->moveDir != Oyster::Math::Float3::null)
{
Oyster::Math::Float3 velocity = this->rigidBody->GetLinearVelocity();
this->rigidBody->SetLinearVelocity(velocity - this->moveDir*this->moveSpeed );
}
}
this->moveDir = Oyster::Math::Float3::null;
if (key_forward > 0.001) if (key_forward > 0.001)
{ {
key_forward -= gameInstance->GetFrameTime(); // fixed timer key_forward -= gameInstance->GetFrameTime(); // fixed timer
forward = this->rigidBody->GetState().GetOrientation().v[2].GetNormalized(); this->moveDir += this->rigidBody->GetState().GetOrientation().v[2].GetNormalized().xyz;
} }
if (key_backward > 0.001) if (key_backward > 0.001)
{ {
key_backward -= gameInstance->GetFrameTime(); key_backward -= gameInstance->GetFrameTime();
back = -this->rigidBody->GetState().GetOrientation().v[2].GetNormalized(); this->moveDir -= this->rigidBody->GetState().GetOrientation().v[2].GetNormalized().xyz;
} }
if (key_strafeRight > 0.001) if (key_strafeRight > 0.001)
{ {
key_strafeRight -= gameInstance->GetFrameTime(); key_strafeRight -= gameInstance->GetFrameTime();
Oyster::Math::Float3 forward = this->rigidBody->GetState().GetOrientation().v[2].GetNormalized(); Oyster::Math::Float3 forward = this->rigidBody->GetState().GetOrientation().v[2];
Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.Normalize(); Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos;
right = -((up).Cross(forward).Normalize()); this->moveDir -= (up).Cross(forward).GetNormalized();
right.Normalize();
} }
if (key_strafeLeft > 0.001) if (key_strafeLeft > 0.001)
{ {
key_strafeLeft -= gameInstance->GetFrameTime(); key_strafeLeft -= gameInstance->GetFrameTime();
Oyster::Math::Float3 forward = this->rigidBody->GetState().GetOrientation().v[2].GetNormalized(); Oyster::Math::Float3 forward = this->rigidBody->GetState().GetOrientation().v[2];
Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.Normalize(); Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos;
left = (up).Cross(forward).Normalize(); this->moveDir += (up).Cross(forward).GetNormalized();
left.Normalize();
} }
moveDirection = forward + back + left + right;
//moveDirection.Normalize();
rigidBody->SetLinearVelocity( MOVE_FORCE * moveDirection );
weapon->Update(0.01f); if(this->moveDir != Oyster::Math::Float3::null)
{
this->moveDir.Normalize();
this->rigidBody->SetLinearVelocity(this->moveDir*this->moveSpeed + this->rigidBody->GetLinearVelocity());
}
this->previousMoveSpeed = this->rigidBody->GetLinearVelocity();
this->previousPosition = this->rigidBody->GetState().centerPos;
this->weapon->Update(0.01f);
} }
void Player::EndFrame() void Player::EndFrame()
{ {
// snap to axis // snap to axis
Oyster::Math::Float4 rotation;
this->rigidBody->SetUp(this->rigidBody->GetState().centerPos.GetNormalized());
Object::EndFrame(); Object::EndFrame();
} }
@ -179,16 +234,18 @@ void Player::Rotate(const Oyster::Math3D::Float3 lookDir, const Oyster::Math3D::
// this is the camera right vector // this is the camera right vector
this->lookDir = lookDir; this->lookDir = lookDir;
Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1]; //Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1];
this->rigidBody->SetUpAndRight(up, right); //this->rigidBody->SetUpAndRight(up, right);
this->rigidBody->SetUpAndRight(this->rigidBody->GetState().centerPos.GetNormalized(), this->rigidBody->GetState().GetOrientation().v[0].xyz.GetNormalized());
} }
void Player::Jump() void Player::Jump()
{ {
Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1].GetNormalized(); if(this->rigidBody->GetLamda() < 1.0f)
this->rigidBody->ApplyImpulse(up *1500); {
this->playerState = PLAYER_STATE::PLAYER_STATE_JUMPING; Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1].GetNormalized();
this->rigidBody->ApplyImpulse(up *1500);
this->playerState = PLAYER_STATE::PLAYER_STATE_JUMPING;
}
} }
bool Player::IsWalking() bool Player::IsWalking()
@ -237,4 +294,3 @@ void Player::DamageLife(int damage)
this->gameInstance->onDisableFnc(this, 0.0f); this->gameInstance->onDisableFnc(this, 0.0f);
} }
} }

View File

@ -73,7 +73,6 @@ namespace GameLogic
void EndFrame(); void EndFrame();
static Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); static Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
private: private:
void Jump(); void Jump();
@ -82,7 +81,6 @@ namespace GameLogic
int teamID; int teamID;
Weapon *weapon; Weapon *weapon;
PLAYER_STATE playerState; PLAYER_STATE playerState;
Oyster::Math::Float3 moveDir;
Oyster::Math::Float3 lookDir; Oyster::Math::Float3 lookDir;
float key_forward; float key_forward;
float key_backward; float key_backward;
@ -90,9 +88,15 @@ namespace GameLogic
float key_strafeLeft; float key_strafeLeft;
float key_jump; float key_jump;
Oyster::Math::Float3 previousPosition;
Oyster::Math::Float3 moveDir;
Oyster::Math::Float moveSpeed;
Oyster::Math::Float3 previousMoveSpeed;
bool hasTakenDamage; bool hasTakenDamage;
float invincibleCooldown; float invincibleCooldown;
}; };
} }
#endif #endif

View File

@ -14,25 +14,25 @@ StaticObject::StaticObject()
StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID) StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID)
:Object(rigidBody, EventOnCollision, type, objectID) :Object(rigidBody, EventOnCollision, type, objectID)
{ {
//use setMass(when it is made) and set the mass to 0 in order to ensure that the object is static rigidBody->SetMass(0);
} }
StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID) StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID)
:Object(rigidBody, EventOnCollision, type, objectID) :Object(rigidBody, EventOnCollision, type, objectID)
{ {
//use setMass(when it is made) and set the mass to 0 in order to ensure that the object is static rigidBody->SetMass(0);
} }
StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision) StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision)
{ {
this->extraDamageOnCollision = extraDamageOnCollision; this->extraDamageOnCollision = extraDamageOnCollision;
//use setMass(when it is made) and set the mass to 0 in order to ensure that the object is static rigidBody->SetMass(0);
} }
StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision) StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision)
{ {
this->extraDamageOnCollision = extraDamageOnCollision; this->extraDamageOnCollision = extraDamageOnCollision;
//use setMass(when it is made) and set the mass to 0 in order to ensure that the object is static rigidBody->SetMass(0);
} }
StaticObject::~StaticObject(void) StaticObject::~StaticObject(void)
{ {

View File

@ -165,22 +165,16 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Implementation\Octree.h" />
<ClInclude Include="Implementation\PhysicsAPI_Impl.h" /> <ClInclude Include="Implementation\PhysicsAPI_Impl.h" />
<ClInclude Include="Implementation\SimpleRigidBody.h" /> <ClInclude Include="Implementation\SimpleRigidBody.h" />
<ClInclude Include="Implementation\SphericalRigidBody.h" />
<ClInclude Include="PhysicsAPI.h" /> <ClInclude Include="PhysicsAPI.h" />
<ClInclude Include="PhysicsFormula-Impl.h" />
<ClInclude Include="PhysicsFormula.h" />
<ClInclude Include="PhysicsStructs-Impl.h" /> <ClInclude Include="PhysicsStructs-Impl.h" />
<ClInclude Include="PhysicsStructs.h" /> <ClInclude Include="PhysicsStructs.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Implementation\Octree.cpp" />
<ClCompile Include="Implementation\DLLMain.cpp" /> <ClCompile Include="Implementation\DLLMain.cpp" />
<ClCompile Include="Implementation\PhysicsAPI_Impl.cpp" /> <ClCompile Include="Implementation\PhysicsAPI_Impl.cpp" />
<ClCompile Include="Implementation\SimpleRigidBody.cpp" /> <ClCompile Include="Implementation\SimpleRigidBody.cpp" />
<ClCompile Include="Implementation\SphericalRigidBody.cpp" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -30,24 +30,12 @@
<ClInclude Include="Implementation\SimpleRigidBody.h"> <ClInclude Include="Implementation\SimpleRigidBody.h">
<Filter>Header Files\Implementation</Filter> <Filter>Header Files\Implementation</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Implementation\SphericalRigidBody.h">
<Filter>Header Files\Implementation</Filter>
</ClInclude>
<ClInclude Include="Implementation\Octree.h">
<Filter>Header Files\Implementation</Filter>
</ClInclude>
<ClInclude Include="PhysicsStructs.h"> <ClInclude Include="PhysicsStructs.h">
<Filter>Header Files\Include</Filter> <Filter>Header Files\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="PhysicsStructs-Impl.h"> <ClInclude Include="PhysicsStructs-Impl.h">
<Filter>Header Files\Include</Filter> <Filter>Header Files\Include</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="PhysicsFormula.h">
<Filter>Header Files\Include</Filter>
</ClInclude>
<ClInclude Include="PhysicsFormula-Impl.h">
<Filter>Header Files\Include</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Implementation\PhysicsAPI_Impl.cpp"> <ClCompile Include="Implementation\PhysicsAPI_Impl.cpp">
@ -59,11 +47,5 @@
<ClCompile Include="Implementation\DLLMain.cpp"> <ClCompile Include="Implementation\DLLMain.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Implementation\SphericalRigidBody.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Implementation\Octree.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,226 +0,0 @@
#include "Octree.h"
using namespace Oyster;
using namespace Physics;
using namespace ::Utility::DynamicMemory;
const unsigned int Octree::invalid_ref = ::Utility::Value::numeric_limits<unsigned int>::max();
Octree::Octree(unsigned int bufferSize, unsigned char numLayers, Math::Float3 worldSize)
{
this->worldNode.dataPtr = NULL;
this->worldNode.container.maxVertex = worldSize*0.5f;
this->worldNode.container.minVertex = -worldSize*0.5f;
}
Octree::~Octree()
{
}
Octree& Octree::operator=(const Octree& orig)
{
this->leafData = orig.leafData;
this->updateQueue = orig.updateQueue;
this->worldNode = orig.worldNode;
this->mapReferences = orig.mapReferences;
return *this;
}
void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef)
{
//customBodyRef->SetScene( this );
Data data;
//Data* tempPtr = this->worldNode.dataPtr;
//data.container = customBodyRef->GetBoundingSphere();
data.queueRef = -1;
data.next = NULL;
data.prev = NULL;
data.customBodyRef = customBodyRef;
data.limbo = false;
this->mapReferences.insert(std::pair <ICustomBody*, unsigned int> (data.customBodyRef, this->leafData.size()));
this->leafData.push_back(data);
/*if(tempPtr != NULL)
{
tempPtr->prev->next = &this->leafData[this->leafData.size() - 1];
this->leafData[this->leafData.size() - 1].prev = tempPtr->prev;
tempPtr->prev = &this->leafData[this->leafData.size() - 1];
this->leafData[this->leafData.size() - 1].next = tempPtr;
}
else
{
this->worldNode.dataPtr = &this->leafData[this->leafData.size() - 1];
this->worldNode.dataPtr->next = this->worldNode.dataPtr;
this->worldNode.dataPtr->prev = this->worldNode.dataPtr;
}*/
}
void Octree::MoveToUpdateQueue(UniquePointer< ICustomBody > customBodyRef)
{
/*this->leafData[this->mapReferences[customBodyRef]].queueRef = this->updateQueue.size();
this->updateQueue.push_back(&this->leafData[this->mapReferences[customBodyRef]]);*/
}
void Octree::MoveToLimbo(const ICustomBody* customBodyRef)
{
auto object = this->mapReferences.find(customBodyRef);
unsigned int tempRef = object->second;
this->leafData[tempRef].limbo = true;
}
bool Octree::IsInLimbo(const ICustomBody* customBodyRef)
{
auto object = this->mapReferences.find(customBodyRef);
unsigned int tempRef = object->second;
return this->leafData[tempRef].limbo;
}
void Octree::ReleaseFromLimbo(const ICustomBody* customBodyRef)
{
auto object = this->mapReferences.find(customBodyRef);
unsigned int tempRef = object->second;
this->leafData[tempRef].limbo = false;
}
void Octree::DestroyObject(UniquePointer< ICustomBody > customBodyRef)
{
std::map<const ICustomBody*, unsigned int>::iterator it = this->mapReferences.find(customBodyRef);
this->mapReferences.erase(it);
this->leafData.erase(this->leafData.begin() + this->leafData[this->mapReferences[customBodyRef]].queueRef);
}
std::vector<ICustomBody*>& Octree::Sample(ICustomBody* customBodyRef, std::vector<ICustomBody*>& updateList)
{
auto object = this->mapReferences.find(customBodyRef);
if(object == this->mapReferences.end())
{
return updateList;
}
unsigned int tempRef = object->second;
for(unsigned int i = 0; i<this->leafData.size(); i++)
{
if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
{
updateList.push_back(this->leafData[i].customBodyRef);
}
}
return updateList;
}
std::vector<ICustomBody*>& Octree::Sample(const Oyster::Collision3D::ICollideable& collideable, std::vector<ICustomBody*>& updateList)
{
for(unsigned int i = 0; i<this->leafData.size(); i++)
{
if(!this->leafData[i].limbo && this->leafData[i].container.Intersects(collideable))
{
updateList.push_back(this->leafData[i].customBodyRef);
}
}
return updateList;
}
void Octree::Visit(ICustomBody* customBodyRef, VisitorAction hitAction )
{
auto object = this->mapReferences.find(customBodyRef);
// If rigid body is not found
if(object == this->mapReferences.end())
{
return;
}
unsigned int tempRef = object->second;
// Go through all object and test for intersection
for(unsigned int i = 0; i<this->leafData.size(); i++)
{
// If objects intersect call collision response function
if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
{
hitAction(*this, tempRef, i);
}
}
}
void Octree::Visit(const Oyster::Collision3D::ICollideable& collideable, void* args, VisitorActionCollideable hitAction)
{
for(unsigned int i = 0; i<this->leafData.size(); i++)
{
if(!this->leafData[i].limbo && collideable.Intersects(this->leafData[i].container))
{
hitAction( this->GetCustomBody(i), args );
}
}
}
ICustomBody* Octree::GetCustomBody(const unsigned int tempRef)
{
return this->leafData[tempRef].customBodyRef;
}
UniquePointer<ICustomBody> Octree::Extract( const ICustomBody* objRef )
{ // Dan Andersson
auto iter = this->mapReferences.find( objRef );
if( iter != this->mapReferences.end() )
{
return this->Extract( iter->second );
}
else
{
return NULL;
}
}
UniquePointer<ICustomBody> Octree::Extract( unsigned int tempRef )
{
if( tempRef != Octree::invalid_ref )
{
//! @todo TODO: implement stub
return NULL;
}
else
{
return NULL;
}
}
unsigned int Octree::GetTemporaryReferenceOf( const ICustomBody* objRef ) const
{ // Dan Andersson
auto iter = this->mapReferences.find( objRef );
if( iter != this->mapReferences.end() )
{
return iter->second;
}
else
{
return Octree::invalid_ref;
}
}
void Octree::SetAsAltered( unsigned int tempRef )
{
//this->leafData[tempRef].container = this->leafData[tempRef].customBodyRef->GetBoundingSphere();
//! @todo TODO: implement stub
}
void Octree::EvaluatePosition( unsigned int tempRef )
{
//! @todo TODO: implement stub
}

View File

@ -1,85 +0,0 @@
#ifndef OCTREE_H
#define OCTREE_H
#include <vector>
#include <map>
#include "Sphere.h"
#include "BoxAxisAligned.h"
#include "Utilities.h"
#include "../PhysicsAPI.h"
namespace Oyster
{
namespace Physics
{
class Octree
{
public:
static const unsigned int invalid_ref;
typedef void(*VisitorAction)(Octree&, unsigned int, unsigned int);
typedef void(*VisitorActionCollideable)(ICustomBody*, void*);
struct Data
{
Data* prev;
Data* next;
Collision3D::Sphere container;
::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef;
bool limbo;
unsigned int queueRef;
};
struct OctreeNode
{
OctreeNode* children[8];
Data* dataPtr;
Collision3D::BoxAxisAligned container;
};
Octree(unsigned int bufferSize = 0, unsigned char numLayers = 0, Math::Float3 worldSize = Math::Float3::null);
virtual ~Octree();
Octree& operator=(const Octree& orig);
void AddObject(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
void MoveToUpdateQueue(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
void MoveToLimbo(const ICustomBody* customBodyRef);
bool IsInLimbo(const ICustomBody* customBodyRef);
void ReleaseFromLimbo(const ICustomBody* customBodyRef);
void DestroyObject(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
std::vector<ICustomBody*>& Sample(ICustomBody* customBodyRef, std::vector<ICustomBody*>& updateList);
std::vector<ICustomBody*>& Sample(const Oyster::Collision3D::ICollideable& collideable, std::vector<ICustomBody*>& updateList);
void Visit(ICustomBody* customBodyRef, VisitorAction hitAction );
void Visit(const Oyster::Collision3D::ICollideable& collideable, void* args, VisitorActionCollideable hitAction );
ICustomBody* GetCustomBody(const unsigned int tempRef);
::Utility::DynamicMemory::UniquePointer<ICustomBody> Extract( const ICustomBody* objRef );
::Utility::DynamicMemory::UniquePointer<ICustomBody> Extract( unsigned int tempRef ); // Dan vill ha
unsigned int GetTemporaryReferenceOf( const ICustomBody* objRef ) const; // Dan vill ha
void SetAsAltered( unsigned int tempRef ); // Dan vill ha
void EvaluatePosition( unsigned int tempRef ); // Dan vill ha
private:
std::vector < Data > leafData;
std::vector < Data* > updateQueue;
std::vector < Data* > limbo;
std::map< const ICustomBody*, unsigned int > mapReferences;
OctreeNode worldNode;
};
}
}
#endif

View File

@ -1,7 +1,6 @@
#include "PhysicsAPI_Impl.h" #include "PhysicsAPI_Impl.h"
#include "OysterPhysics3D.h" #include "OysterPhysics3D.h"
#include "SimpleRigidBody.h" #include "SimpleRigidBody.h"
#include "SphericalRigidBody.h"
using namespace ::Oyster; using namespace ::Oyster;
using namespace ::Oyster::Physics; using namespace ::Oyster::Physics;
@ -181,6 +180,47 @@ ICustomBody* API_Impl::AddCollisionCylinder(::Oyster::Math::Float3 halfSize, ::O
return body; return body;
} }
ICustomBody* API_Impl::AddCharacter(::Oyster::Math::Float height, ::Oyster::Math::Float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction)
{
SimpleRigidBody* body = new SimpleRigidBody;
SimpleRigidBody::State state;
// Add collision shape
btCapsuleShape* collisionShape = new btCapsuleShape(radius, height);
body->SetCollisionShape(collisionShape);
// Add motion state
btDefaultMotionState* motionState = new btDefaultMotionState(btTransform(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w),btVector3(position.x, position.y, position.z)));
body->SetMotionState(motionState);
// Add rigid body
btVector3 fallInertia(0, 0, 0);
collisionShape->calculateLocalInertia(mass, fallInertia);
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, motionState, collisionShape, fallInertia);
btRigidBody* rigidBody = new btRigidBody(rigidBodyCI);
rigidBody->setFriction(staticFriction);
rigidBody->setRestitution(restitution);
rigidBody->setUserPointer(body);
rigidBody->setAngularFactor(0);
rigidBody->setSleepingThresholds(0, 0);
body->SetRigidBody(rigidBody);
// Add rigid body to world
this->dynamicsWorld->addRigidBody(rigidBody);
this->customBodies.push_back(body);
state.centerPos = position;
state.reach = Float3(radius, height, radius);
state.dynamicFrictionCoeff = 0.5f;
state.staticFrictionCoeff = 0.5f;
state.quaternion = Quaternion(Float3(rotation.xyz), rotation.w);
state.mass = mass;
body->SetState(state);
return body;
}
void API_Impl::SetTimeStep(float timeStep) void API_Impl::SetTimeStep(float timeStep)
{ {
this->timeStep = timeStep; this->timeStep = timeStep;
@ -190,7 +230,9 @@ void API_Impl::UpdateWorld()
{ {
for(unsigned int i = 0; i < this->customBodies.size(); i++ ) for(unsigned int i = 0; i < this->customBodies.size(); i++ )
{ {
this->customBodies[i]->SetGravity(-(this->customBodies[i]->GetState().centerPos - this->gravityPoint).GetNormalized()*this->gravity); SimpleRigidBody* simpleBody = dynamic_cast<SimpleRigidBody*>(this->customBodies[i]);
this->customBodies[i]->SetGravity(-(this->customBodies[i]->GetState().centerPos - this->gravityPoint).GetNormalized()*this->gravity);
simpleBody->PreStep(this->dynamicsWorld);
} }
this->dynamicsWorld->stepSimulation(this->timeStep, 1, this->timeStep); this->dynamicsWorld->stepSimulation(this->timeStep, 1, this->timeStep);
@ -204,11 +246,11 @@ void API_Impl::UpdateWorld()
trans = simpleBody->GetRigidBody()->getWorldTransform(); trans = simpleBody->GetRigidBody()->getWorldTransform();
this->customBodies[i]->SetPosition(Float3(trans.getOrigin().x(), trans.getOrigin().y(), trans.getOrigin().z())); this->customBodies[i]->SetPosition(Float3(trans.getOrigin().x(), trans.getOrigin().y(), trans.getOrigin().z()));
this->customBodies[i]->SetRotation(Quaternion(Float3(trans.getRotation().x(), trans.getRotation().y(), trans.getRotation().z()), trans.getRotation().w())); this->customBodies[i]->SetRotation(Quaternion(Float3(trans.getRotation().x(), trans.getRotation().y(), trans.getRotation().z()), trans.getRotation().w()));
if(simpleBody->GetRigidBody()->getActivationState() == ACTIVE_TAG) if(simpleBody->GetRigidBody()->getActivationState() == ACTIVE_TAG)
{ {
simpleBody->CallSubscription_Move(); this->customBodies[i]->CallSubscription_Move();
} }
} }
int numManifolds = this->dynamicsWorld->getDispatcher()->getNumManifolds(); int numManifolds = this->dynamicsWorld->getDispatcher()->getNumManifolds();
@ -221,8 +263,8 @@ void API_Impl::UpdateWorld()
ICustomBody* bodyA = (ICustomBody*)obA->getUserPointer(); ICustomBody* bodyA = (ICustomBody*)obA->getUserPointer();
ICustomBody* bodyB = (ICustomBody*)obB->getUserPointer(); ICustomBody* bodyB = (ICustomBody*)obB->getUserPointer();
dynamic_cast<SimpleRigidBody*>(bodyA)->CallSubscription_AfterCollisionResponse(bodyA, bodyB, 0.0f); bodyA->CallSubscription_AfterCollisionResponse(bodyA, bodyB, 0.0f);
dynamic_cast<SimpleRigidBody*>(bodyB)->CallSubscription_AfterCollisionResponse(bodyB, bodyA, 0.0f); bodyB->CallSubscription_AfterCollisionResponse(bodyB, bodyA, 0.0f);
} }
} }

View File

@ -2,7 +2,6 @@
#define PHYSICS_API_IMPL_H #define PHYSICS_API_IMPL_H
#include "../PhysicsAPI.h" #include "../PhysicsAPI.h"
#include "Octree.h"
#include <btBulletDynamicsCommon.h> #include <btBulletDynamicsCommon.h>
namespace Oyster namespace Oyster
@ -65,6 +64,8 @@ namespace Oyster
ICustomBody* AddCollisionBox(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction); ICustomBody* AddCollisionBox(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction);
ICustomBody* AddCollisionCylinder(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction); ICustomBody* AddCollisionCylinder(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction);
ICustomBody* AddCharacter(::Oyster::Math::Float height, ::Oyster::Math::Float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction);
void SetTimeStep(float timeStep); void SetTimeStep(float timeStep);
void UpdateWorld(); void UpdateWorld();

View File

@ -139,11 +139,59 @@ void SimpleRigidBody::SetRotation(Float3 eulerAngles)
this->state.quaternion = Quaternion(Float3(trans.getRotation().x(), trans.getRotation().y(), trans.getRotation().z()), trans.getRotation().w()); this->state.quaternion = Quaternion(Float3(trans.getRotation().x(), trans.getRotation().y(), trans.getRotation().z()), trans.getRotation().w());
} }
void SimpleRigidBody::SetRotation(::Oyster::Math::Float4x4 rotation)
{
btTransform trans;
btMatrix3x3 newRotation;
btVector3 rightVector(rotation.v[0].x, rotation.v[0].y, rotation.v[0].z);
btVector3 upVector(rotation.v[1].x, rotation.v[1].y, rotation.v[1].z);
btVector3 forwardVector(rotation.v[2].x, rotation.v[2].y, rotation.v[2].z);
newRotation[0] = rightVector;
newRotation[1] = upVector;
newRotation[2] = forwardVector;
trans = this->rigidBody->getWorldTransform();
trans.setBasis(newRotation);
this->rigidBody->setWorldTransform(trans);
btQuaternion quaternion;
quaternion = trans.getRotation();
this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w());
}
void SimpleRigidBody::SetRotationAsAngularAxis(::Oyster::Math::Float4 angularAxis)
{
if(angularAxis.xyz.GetMagnitude() == 0)
{
return;
}
btTransform trans;
btVector3 vector(angularAxis.x, angularAxis.y, angularAxis.z);
btQuaternion quaternion(vector, angularAxis.w);
trans = this->rigidBody->getWorldTransform();
trans.setRotation(quaternion);
this->rigidBody->setWorldTransform(trans);
this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w());
}
void SimpleRigidBody::SetAngularFactor(Float factor) void SimpleRigidBody::SetAngularFactor(Float factor)
{ {
this->rigidBody->setAngularFactor(factor); this->rigidBody->setAngularFactor(factor);
} }
void SimpleRigidBody::SetMass(Float mass)
{
btVector3 fallInertia(0, 0, 0);
collisionShape->calculateLocalInertia(mass, fallInertia);
this->rigidBody->setMassProps(mass, fallInertia);
this->state.mass = mass;
}
void SimpleRigidBody::SetGravity(Float3 gravity) void SimpleRigidBody::SetGravity(Float3 gravity)
{ {
this->rigidBody->setGravity(btVector3(gravity.x, gravity.y, gravity.z)); this->rigidBody->setGravity(btVector3(gravity.x, gravity.y, gravity.z));
@ -177,7 +225,7 @@ void SimpleRigidBody::SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math:
btVector3 forwardVector(forward.x, forward.y, forward.z); btVector3 forwardVector(forward.x, forward.y, forward.z);
rotation[1] = upVector.normalized(); rotation[1] = upVector.normalized();
rotation[2] = forwardVector.normalized(); rotation[2] = forwardVector.normalized();
rotation[0] = forwardVector.cross(upVector).normalized(); rotation[0] = upVector.cross(forwardVector).normalized();
trans = this->rigidBody->getWorldTransform(); trans = this->rigidBody->getWorldTransform();
trans.setBasis(rotation); trans.setBasis(rotation);
this->rigidBody->setWorldTransform(trans); this->rigidBody->setWorldTransform(trans);
@ -187,6 +235,27 @@ void SimpleRigidBody::SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math:
this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w()); this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w());
} }
void SimpleRigidBody::SetUp(::Oyster::Math::Float3 up)
{
Float3 vector = Float3(0, 1, 0).Cross(up);
if(vector == Float3::null)
{
return;
}
Float sine = vector.GetLength();
Float cosine = acos(Float3(0, 1, 0).Dot(up));
btQuaternion quaternion(btVector3(vector.x, vector.y, vector.z),cosine);
btTransform trans;
trans = this->rigidBody->getWorldTransform();
trans.setRotation(quaternion);
this->rigidBody->setWorldTransform(trans);
this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w());
}
Float4x4 SimpleRigidBody::GetRotation() const Float4x4 SimpleRigidBody::GetRotation() const
{ {
return this->state.GetRotation(); return this->state.GetRotation();
@ -229,6 +298,16 @@ Float4x4 SimpleRigidBody::GetView( const ::Oyster::Math::Float3 &offset ) const
return this->state.GetView(offset); return this->state.GetView(offset);
} }
Float3 SimpleRigidBody::GetGravity() const
{
return this->rigidBody->getGravity();
}
Float3 SimpleRigidBody::GetLinearVelocity() const
{
return this->rigidBody->getLinearVelocity();
}
void SimpleRigidBody::CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Oyster::Math::Float kineticEnergyLoss) void SimpleRigidBody::CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Oyster::Math::Float kineticEnergyLoss)
{ {
if(this->afterCollision) if(this->afterCollision)
@ -268,3 +347,58 @@ void SimpleRigidBody::SetCustomTag( void *ref )
} }
void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld)
{
btTransform xform;
this->rigidBody->getMotionState()->getWorldTransform (xform);
btVector3 down = -xform.getBasis()[1];
btVector3 forward = xform.getBasis()[2];
down.normalize ();
forward.normalize();
this->raySource[0] = xform.getOrigin();
this->raySource[1] = xform.getOrigin();
this->rayTarget[0] = this->raySource[0] + down * this->state.reach.y * btScalar(1.1);
this->rayTarget[1] = this->raySource[1] + forward * this->state.reach.y * btScalar(1.1);
class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback
{
public:
ClosestNotMe (btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
{
m_me = me;
}
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
{
if (rayResult.m_collisionObject == m_me)
return 1.0;
return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace);
}
protected:
btRigidBody* m_me;
};
ClosestNotMe rayCallback(this->rigidBody);
int i = 0;
for (i = 0; i < 2; i++)
{
rayCallback.m_closestHitFraction = 1.0;
if((this->raySource[i] - this->rayTarget[i]).length() != 0)
collisionWorld->rayTest (this->raySource[i], this->rayTarget[i], rayCallback);
if (rayCallback.hasHit())
{
this->rayLambda[i] = rayCallback.m_closestHitFraction;
} else {
this->rayLambda[i] = 1.0;
}
}
}
float SimpleRigidBody::GetLamda() const
{
return this->rayLambda[0];
}

View File

@ -19,10 +19,6 @@ namespace Oyster
void SetState( const State &state ); void SetState( const State &state );
void ApplyImpulse(Math::Float3 impulse); void ApplyImpulse(Math::Float3 impulse);
void SetCollisionShape(btCollisionShape* shape);
void SetMotionState(btDefaultMotionState* motionState);
void SetRigidBody(btRigidBody* rigidBody);
void SetSubscription(EventAction_AfterCollisionResponse function); void SetSubscription(EventAction_AfterCollisionResponse function);
void SetSubscription(EventAction_Move function); void SetSubscription(EventAction_Move function);
@ -32,18 +28,25 @@ namespace Oyster
void SetRotation(Math::Float4 quaternion); void SetRotation(Math::Float4 quaternion);
void SetRotation(Math::Quaternion quaternion); void SetRotation(Math::Quaternion quaternion);
void SetRotation(Math::Float3 eulerAngles); void SetRotation(Math::Float3 eulerAngles);
void SetRotation(::Oyster::Math::Float4x4 rotation);
void SetRotationAsAngularAxis(Math::Float4 angularAxis);
void SetAngularFactor(Math::Float factor); void SetAngularFactor(Math::Float factor);
void SetMass(Math::Float mass);
void SetGravity(Math::Float3 gravity); void SetGravity(Math::Float3 gravity);
void SetUpAndRight(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 right); void SetUpAndRight(Math::Float3 up, Math::Float3 right);
void SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 forward); void SetUpAndForward(Math::Float3 up, Math::Float3 forward);
void SetUp(Math::Float3 up);
Math::Float4x4 GetRotation() const; Math::Float4x4 GetRotation() const;
Math::Float4 GetRotationAsAngularAxis(); Math::Float4 GetRotationAsAngularAxis();
Math::Float4x4 GetOrientation() const; Math::Float4x4 GetOrientation() const;
Math::Float4x4 GetView() const; Math::Float4x4 GetView() const;
Math::Float4x4 GetView( const ::Oyster::Math::Float3 &offset ) const; Math::Float4x4 GetView( const Math::Float3 &offset ) const;
Math::Float3 GetGravity() const;
::Oyster::Math::Float3 GetLinearVelocity() const;
void CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Math::Float kineticEnergyLoss); void CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Math::Float kineticEnergyLoss);
void CallSubscription_Move(); void CallSubscription_Move();
@ -55,6 +58,17 @@ namespace Oyster
void SetCustomTag( void *ref ); void SetCustomTag( void *ref );
void* GetCustomTag() const; void* GetCustomTag() const;
// Class specific
void SetCollisionShape(btCollisionShape* shape);
void SetMotionState(btDefaultMotionState* motionState);
void SetRigidBody(btRigidBody* rigidBody);
void PreStep(const btCollisionWorld* collisionWorld);
float GetLamda() const;
private: private:
btCollisionShape* collisionShape; btCollisionShape* collisionShape;
@ -68,7 +82,11 @@ namespace Oyster
void *customTag; void *customTag;
::Oyster::Math::Float3 gravity; Math::Float3 gravity;
btVector3 raySource[2];
btVector3 rayTarget[2];
btScalar rayLambda[2];
}; };
} }
} }

View File

@ -87,6 +87,8 @@ namespace Oyster
virtual ICustomBody* AddCollisionBox(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0; virtual ICustomBody* AddCollisionBox(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0;
virtual ICustomBody* AddCollisionCylinder(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0; virtual ICustomBody* AddCollisionCylinder(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0;
virtual ICustomBody* AddCharacter(::Oyster::Math::Float height, ::Oyster::Math::Float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0;
virtual void SetTimeStep(float timeStep) = 0; virtual void SetTimeStep(float timeStep) = 0;
virtual void UpdateWorld() = 0; virtual void UpdateWorld() = 0;
@ -142,12 +144,16 @@ namespace Oyster
virtual void SetRotation(::Oyster::Math::Float4 quaternion) = 0; virtual void SetRotation(::Oyster::Math::Float4 quaternion) = 0;
virtual void SetRotation(::Oyster::Math::Quaternion quaternion) = 0; virtual void SetRotation(::Oyster::Math::Quaternion quaternion) = 0;
virtual void SetRotation(::Oyster::Math::Float3 eulerAngles) = 0; virtual void SetRotation(::Oyster::Math::Float3 eulerAngles) = 0;
virtual void SetRotation(::Oyster::Math::Float4x4 rotation) = 0;
virtual void SetRotationAsAngularAxis(::Oyster::Math::Float4 angularAxis) = 0;
virtual void SetAngularFactor(::Oyster::Math::Float factor) = 0; virtual void SetAngularFactor(::Oyster::Math::Float factor) = 0;
virtual void SetMass(::Oyster::Math::Float mass) = 0;
virtual void SetGravity(::Oyster::Math::Float3 gravity) = 0; virtual void SetGravity(::Oyster::Math::Float3 gravity) = 0;
virtual void SetUpAndRight(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 right) = 0; virtual void SetUpAndRight(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 right) = 0;
virtual void SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 forward) = 0; virtual void SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 forward) = 0;
virtual void SetUp(::Oyster::Math::Float3 up) = 0;
virtual ::Oyster::Math::Float4x4 GetRotation() const = 0; virtual ::Oyster::Math::Float4x4 GetRotation() const = 0;
virtual ::Oyster::Math::Float4 GetRotationAsAngularAxis() = 0; virtual ::Oyster::Math::Float4 GetRotationAsAngularAxis() = 0;
@ -155,6 +161,12 @@ namespace Oyster
virtual ::Oyster::Math::Float4x4 GetView() const = 0; virtual ::Oyster::Math::Float4x4 GetView() const = 0;
virtual ::Oyster::Math::Float4x4 GetView(const ::Oyster::Math::Float3 &offset) const = 0; virtual ::Oyster::Math::Float4x4 GetView(const ::Oyster::Math::Float3 &offset) const = 0;
virtual ::Oyster::Math::Float3 GetGravity() const = 0;
virtual ::Oyster::Math::Float3 GetLinearVelocity() const = 0;
virtual void CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Math::Float kineticEnergyLoss) = 0;
virtual void CallSubscription_Move() = 0;
/******************************************************** /********************************************************
* @return the void pointer set by SetCustomTag. * @return the void pointer set by SetCustomTag.
* nullptr if none is set. * nullptr if none is set.
@ -167,11 +179,12 @@ namespace Oyster
* @param ref: Anything castable to a void pointer, the engine won't care. * @param ref: Anything castable to a void pointer, the engine won't care.
********************************************************/ ********************************************************/
virtual void SetCustomTag( void *ref ) = 0; virtual void SetCustomTag( void *ref ) = 0;
virtual float GetLamda() const = 0;
}; };
} }
} }
#include "PhysicsStructs.h" #include "PhysicsStructs.h"
#include "PhysicsFormula.h"
#endif #endif

View File

@ -1,82 +0,0 @@
#ifndef PHYSICS_FORMULA_IMPL_H
#define PHYSICS_FORMULA_IMPL_H
#include "PhysicsFormula.h"
#include "OysterPhysics3D.h"
namespace Oyster { namespace Physics { namespace Formula
{
namespace MomentOfInertia
{
inline ::Oyster::Math::Float4x4 CreateSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius )
{
return ::Oyster::Physics3D::Formula::MomentOfInertia::Sphere(mass, radius);
}
inline ::Oyster::Math::Float4x4 CreateHollowSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius )
{
return ::Oyster::Physics3D::Formula::MomentOfInertia::HollowSphere(mass, radius);
}
inline ::Oyster::Math::Float4x4 CreateCuboidMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth )
{
return ::Oyster::Physics3D::Formula::MomentOfInertia::Cuboid(mass, height, width, depth);
}
inline ::Oyster::Math::Float4x4 CreateCylinderMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius )
{
return ::Oyster::Physics3D::Formula::MomentOfInertia::Cylinder(mass, height, radius);
}
inline ::Oyster::Math::Float4x4 CreateRodMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length )
{
return ::Oyster::Physics3D::Formula::MomentOfInertia::RodCenter(mass, length);
}
}
namespace CollisionResponse
{
inline ::Oyster::Math::Float Bounce( ::Oyster::Math::Float e, ::Oyster::Math::Float mA, ::Oyster::Math::Float gA, ::Oyster::Math::Float mB, ::Oyster::Math::Float gB )
{
//return (e + 1) * (mB*gA - mA*gB) / (mA + mB);
return (e + 1) * (mA*gB - mB*gA) / (mA + mB);
}
inline ::Oyster::Math::Float4 Friction( ::Oyster::Math::Float i, ::Oyster::Math::Float4 iN, ::Oyster::Math::Float4 momA, ::Oyster::Math::Float sFA, ::Oyster::Math::Float dFA, ::Oyster::Math::Float mA, ::Oyster::Math::Float4 momB, ::Oyster::Math::Float sFB, ::Oyster::Math::Float dFB, ::Oyster::Math::Float mB )
{
// FRICTION
// Relative momentum after normal impulse
::Oyster::Math::Float4 relativeMomentum = momB - momA;
::Oyster::Math::Float4 tanFriction = relativeMomentum - relativeMomentum.Dot( iN ) * iN;
if( tanFriction.Dot(tanFriction) > 0.0f )
{ // no friction if moving directly into surface, or not at all.
tanFriction.Normalize();
::Oyster::Math::Float magnitudeFriction = -relativeMomentum.Dot( tanFriction );
magnitudeFriction = magnitudeFriction * mA * mB / ( mA + mB );
::Oyster::Math::Float mu = 0.5f * ( sFA + sFB );
::Oyster::Math::Float4 frictionImpulse;
if( abs(magnitudeFriction) < i * mu )
{
frictionImpulse = magnitudeFriction * tanFriction;
}
else
{
::Oyster::Math::Float dynamicFriction = 0.5f * ( dFA + dFB );
frictionImpulse = ( -i * dynamicFriction ) * tanFriction;
}
return ( 1 / mA ) * frictionImpulse;
}
else
return ::Oyster::Math::Float4::null;
}
}
} } }
#endif

View File

@ -1,35 +0,0 @@
#ifndef PHYSICS_FORMULA_H
#define PHYSICS_FORMULA_H
#include "OysterMath.h"
#include "OysterPhysics3D.h"
namespace Oyster { namespace Physics { namespace Formula
{
namespace MomentOfInertia
{
::Oyster::Math::Float4x4 CreateSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius );
::Oyster::Math::Float4x4 CreateHollowSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius );
::Oyster::Math::Float4x4 CreateCuboidMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth );
::Oyster::Math::Float4x4 CreateCylinderMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius );
::Oyster::Math::Float4x4 CreateRodMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length );
}
namespace CollisionResponse
{
::Oyster::Math::Float Bounce( ::Oyster::Math::Float coeffOfRestitution,
::Oyster::Math::Float massA, ::Oyster::Math::Float momentumA,
::Oyster::Math::Float massB, ::Oyster::Math::Float momentumB );
::Oyster::Math::Float4 Friction( ::Oyster::Math::Float impulse, ::Oyster::Math::Float4 impulseNormal,
::Oyster::Math::Float4 momentumA, ::Oyster::Math::Float staticFrictionA,
::Oyster::Math::Float dynamicFrictionA, ::Oyster::Math::Float massA,
::Oyster::Math::Float4 momentumB, ::Oyster::Math::Float staticFrictionB,
::Oyster::Math::Float dynamicFrictionB, ::Oyster::Math::Float massB );
}
} } }
#include "PhysicsFormula-Impl.h"
#endif

View File

@ -10,9 +10,10 @@ namespace Oyster
{ {
namespace Struct namespace Struct
{ {
inline CustomBodyState::CustomBodyState( ::Oyster::Math::Float mass, ::Oyster::Math::Float restitutionCoeff, ::Oyster::Math::Float staticFrictionCoeff, ::Oyster::Math::Float dynamicFrictionCoeff, const ::Oyster::Math::Float3 &centerPos, const ::Oyster::Math::Quaternion& quaternion) inline CustomBodyState::CustomBodyState( ::Oyster::Math::Float mass, ::Oyster::Math::Float3 reach, ::Oyster::Math::Float restitutionCoeff, ::Oyster::Math::Float staticFrictionCoeff, ::Oyster::Math::Float dynamicFrictionCoeff, const ::Oyster::Math::Float3 &centerPos, const ::Oyster::Math::Quaternion& quaternion)
{ {
this->mass = mass; this->mass = mass;
this->reach = reach;
this->restitutionCoeff = restitutionCoeff; this->restitutionCoeff = restitutionCoeff;
this->staticFrictionCoeff = staticFrictionCoeff; this->staticFrictionCoeff = staticFrictionCoeff;
this->dynamicFrictionCoeff = dynamicFrictionCoeff; this->dynamicFrictionCoeff = dynamicFrictionCoeff;
@ -24,6 +25,7 @@ namespace Oyster
{ {
this->mass = state.mass; this->mass = state.mass;
this->restitutionCoeff = state.restitutionCoeff; this->restitutionCoeff = state.restitutionCoeff;
this->reach = state.reach;
this->staticFrictionCoeff = state.staticFrictionCoeff; this->staticFrictionCoeff = state.staticFrictionCoeff;
this->dynamicFrictionCoeff = state.dynamicFrictionCoeff; this->dynamicFrictionCoeff = state.dynamicFrictionCoeff;
this->centerPos = state.centerPos; this->centerPos = state.centerPos;

View File

@ -16,6 +16,7 @@ namespace Oyster
public: public:
// Default constructor // Default constructor
CustomBodyState( ::Oyster::Math::Float mass = 1.0f, CustomBodyState( ::Oyster::Math::Float mass = 1.0f,
::Oyster::Math::Float3 reach = ::Oyster::Math::Float3(0,0,0),
::Oyster::Math::Float restitutionCoeff = 0.5f, ::Oyster::Math::Float restitutionCoeff = 0.5f,
::Oyster::Math::Float staticFrictionCoeff = 1.0f, ::Oyster::Math::Float staticFrictionCoeff = 1.0f,
::Oyster::Math::Float dynamicFrictionCoeff = 1.0f, ::Oyster::Math::Float dynamicFrictionCoeff = 1.0f,