GameServer - Merge with GameLogic
This commit is contained in:
commit
b7f550859d
BIN
Bin/Level.txt
BIN
Bin/Level.txt
Binary file not shown.
BIN
Bin/map.txt
BIN
Bin/map.txt
Binary file not shown.
|
@ -86,6 +86,9 @@ namespace DanBias
|
|||
float dt = (float)m_data->timer.getElapsedSeconds();
|
||||
m_data->timer.reset();
|
||||
|
||||
if(m_data->recieverObj->IsConnected())
|
||||
m_data->recieverObj->Update();
|
||||
|
||||
capFrame += dt;
|
||||
if(capFrame > 0.03)
|
||||
{
|
||||
|
@ -135,8 +138,7 @@ namespace DanBias
|
|||
|
||||
HRESULT DanBiasGame::Update(float deltaTime)
|
||||
{
|
||||
if(m_data->recieverObj->IsConnected())
|
||||
m_data->recieverObj->Update();
|
||||
|
||||
|
||||
m_data->inputObj->Update();
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ bool GameState::Init(Oyster::Network::NetworkClient* nwClient)
|
|||
privData->state = gameStateState_loading;
|
||||
privData->nwClient = nwClient;
|
||||
privData->state = LoadGame();
|
||||
|
||||
pitch = 0;
|
||||
//tELL SERver ready
|
||||
nwClient->Send(GameLogic::Protocol_General_Status(GameLogic::Protocol_General_Status::States_ready));
|
||||
|
||||
|
@ -120,7 +120,7 @@ bool GameState::LoadModels(std::wstring mapFile)
|
|||
|
||||
// add player model 2
|
||||
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 320, 0));
|
||||
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(50, 320, 0));
|
||||
|
||||
modelData.world = modelData.world * translate;
|
||||
modelData.visible = true;
|
||||
|
@ -131,6 +131,32 @@ bool GameState::LoadModels(std::wstring mapFile)
|
|||
privData->object.push_back(obj);
|
||||
privData->object[privData->object.size() -1 ]->Init(modelData);
|
||||
|
||||
// add house model
|
||||
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(50, 300, 0));
|
||||
//Oyster::Math3D::RotationMatrix_AxisZ()
|
||||
modelData.world = modelData.world * translate;
|
||||
modelData.visible = false;
|
||||
modelData.modelPath = L"building_corporation.dan";
|
||||
modelData.id = 4;
|
||||
// load models
|
||||
obj = new C_Player();
|
||||
privData->object.push_back(obj);
|
||||
privData->object[privData->object.size() -1 ]->Init(modelData);
|
||||
|
||||
// add crystal model
|
||||
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 305, 0));
|
||||
|
||||
modelData.world = modelData.world * translate;
|
||||
modelData.visible = true;
|
||||
modelData.modelPath = L"crystalformation_b.dan";
|
||||
modelData.id = 5;
|
||||
// load models
|
||||
obj = new C_Player();
|
||||
privData->object.push_back(obj);
|
||||
privData->object[privData->object.size() -1 ]->Init(modelData);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -286,14 +312,17 @@ void GameState::readKeyInput(InputClass* KeyInput)
|
|||
//send delta mouse movement
|
||||
if (KeyInput->IsMousePressed())
|
||||
{
|
||||
camera->Yaw(KeyInput->GetYaw());
|
||||
camera->Pitch(KeyInput->GetPitch());
|
||||
camera->Yaw(-KeyInput->GetYaw());
|
||||
//camera->Pitch(KeyInput->GetPitch());
|
||||
//pitch = KeyInput->GetPitch();
|
||||
camera->UpdateViewMatrix();
|
||||
GameLogic::Protocol_PlayerLook playerLookDir;
|
||||
Oyster::Math::Float3 look = camera->GetLook();
|
||||
Oyster::Math::Float4 look = camera->GetLook();
|
||||
playerLookDir.lookDirX = look.x;
|
||||
playerLookDir.lookDirY = look.y;
|
||||
playerLookDir.lookDirZ = look.z;
|
||||
playerLookDir.deltaX = -KeyInput->GetYaw();
|
||||
|
||||
privData->nwClient->Send(playerLookDir);
|
||||
}
|
||||
|
||||
|
@ -354,18 +383,34 @@ void GameState::Protocol( ObjPos* pos )
|
|||
{
|
||||
world[i] = pos->worldPos[i];
|
||||
}
|
||||
|
||||
//printf("pos for obj %d, ",pos->object_ID );
|
||||
for (unsigned int i = 0; i < privData->object.size(); i++)
|
||||
{
|
||||
if(privData->object[i]->GetId() == pos->object_ID)
|
||||
{
|
||||
privData->object[i]->setPos(world);
|
||||
//camera->setRight((Oyster::Math::Float3(world[0], world[1], world[2])));
|
||||
//camera->setUp((Oyster::Math::Float3(world[4], world[5], world[6])));
|
||||
//
|
||||
//camera->setLook((Oyster::Math::Float3(world[8], world[9], world[10])));
|
||||
if(i == myId) // playerobj
|
||||
{
|
||||
camera->SetPosition(Oyster::Math::Float3(world[12], world[13]+2.2f, world[14]-1));
|
||||
camera->setRight((Oyster::Math::Float3(world[0], world[1], world[2])));
|
||||
camera->setUp(Oyster::Math::Float3(world[4], world[5], world[6]));
|
||||
Oyster::Math::Float3 cameraLook = camera->GetLook();
|
||||
Oyster::Math::Float3 objForward = (Oyster::Math::Float3(world[8], world[9], world[10]));
|
||||
|
||||
camera->setLook(objForward);
|
||||
camera->UpdateViewMatrix();
|
||||
Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13], world[14]);
|
||||
Oyster::Math::Float3 up = Oyster::Math::Float3(world[4], world[5], world[6]);
|
||||
|
||||
up *= 2;
|
||||
objForward *= -3;
|
||||
Oyster::Math::Float3 cameraPos = up + pos + objForward;
|
||||
//camera->Pitch(pitch);
|
||||
camera->SetPosition(cameraPos);
|
||||
//camera->LookAt(pos, dir, up);
|
||||
//Oyster::Math::Float3 newLook = objForward;
|
||||
camera->UpdateViewMatrix();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ private:
|
|||
Camera* camera;
|
||||
|
||||
int myId;
|
||||
float pitch;
|
||||
struct myData;
|
||||
myData* privData;
|
||||
public:
|
||||
|
|
|
@ -173,6 +173,11 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="Launcher.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DanBiasGame\DanBiasGame.vcxproj">
|
||||
<Project>{2a1bc987-af42-4500-802d-89cd32fc1309}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
|
@ -9,12 +9,16 @@ using namespace GameLogic;
|
|||
AttatchmentMassDriver::AttatchmentMassDriver(void)
|
||||
{
|
||||
this->owner = 0;
|
||||
this->heldObject = NULL;
|
||||
this->hasObject = false;
|
||||
}
|
||||
|
||||
AttatchmentMassDriver::AttatchmentMassDriver(Player &owner)
|
||||
{
|
||||
|
||||
this->owner = &owner;
|
||||
this->heldObject = NULL;
|
||||
this->hasObject = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,22 +39,68 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage,
|
|||
ForcePush(usage,dt);
|
||||
break;
|
||||
case WEAPON_FIRE::WEAPON_USE_SECONDARY_PRESS:
|
||||
|
||||
if(hasObject)
|
||||
{
|
||||
ForcePush(usage,dt);//WARNING THIS IS A CRAP TEST TO MAKE SURE YOU CAN SHOOT BOXES
|
||||
break;
|
||||
}
|
||||
ForcePull(usage,dt);
|
||||
break;
|
||||
case WEAPON_FIRE::WEAPON_USE_UTILLITY_PRESS:
|
||||
ForceZip(usage,dt);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AttatchmentMassDriver::Update(float dt)
|
||||
{
|
||||
|
||||
//update position of heldObject if there is an object being held
|
||||
if(hasObject)
|
||||
{
|
||||
Oyster::Physics::ICustomBody::State state;
|
||||
state = heldObject->GetState();
|
||||
Oyster::Math::Float3 ownerPos = owner->GetPosition();
|
||||
ownerPos.y += 2;
|
||||
Oyster::Math::Float3 pos = ownerPos + owner->GetLookDir().GetNormalized()*2;
|
||||
|
||||
state.SetCenterPosition(pos);
|
||||
|
||||
heldObject->SetState(state);
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* Pushes objects in a cone in front of the weapon when fired
|
||||
*alternativly it puts a large force on the currently held object
|
||||
********************************************************/
|
||||
void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float dt)
|
||||
{
|
||||
//if the weapon has an object then it is only the object that will be shot away
|
||||
Oyster::Math::Float4 pushForce;
|
||||
|
||||
Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt);
|
||||
Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition());
|
||||
if(hasObject)
|
||||
{
|
||||
Oyster::Physics::API::Instance().ReleaseFromLimbo(heldObject);
|
||||
pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (2000);
|
||||
Oyster::Physics::ICustomBody::State state = heldObject->GetState();
|
||||
state.ApplyLinearImpulse((Oyster::Math::Float3)pushForce);
|
||||
heldObject->SetState(state);
|
||||
|
||||
Oyster::Math::Float4x4 hitSpace = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/4,1,1,20);
|
||||
hasObject = false;
|
||||
heldObject = NULL;
|
||||
return;
|
||||
}
|
||||
Oyster::Math::Float3 up = owner->GetOrientation().v[1];
|
||||
Oyster::Math::Float3 look = owner->GetLookDir();
|
||||
Oyster::Math::Float3 pos = owner->GetPosition();
|
||||
|
||||
pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (50000 * dt);
|
||||
Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(look, up, pos);
|
||||
|
||||
Oyster::Math::Float4x4 hitSpace = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/8,1,1,5);
|
||||
Oyster::Collision3D::Frustrum hitFrustum = Oyster::Collision3D::Frustrum(Oyster::Math3D::ViewProjectionMatrix(aim,hitSpace));
|
||||
forcePushData args;
|
||||
args.pushForce = pushForce;
|
||||
|
@ -61,7 +111,7 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float
|
|||
/********************************************************
|
||||
* Pulls the player in the direction he is looking, used for fast movement(kinda like a jetpack)
|
||||
********************************************************/
|
||||
void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt)
|
||||
void AttatchmentMassDriver::ForceZip(const WEAPON_FIRE &usage, float dt)
|
||||
{
|
||||
Oyster::Physics::Struct::CustomBodyState state = this->owner->GetRigidBody()->GetState();
|
||||
|
||||
|
@ -72,3 +122,37 @@ void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt)
|
|||
}
|
||||
|
||||
|
||||
void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt)
|
||||
{
|
||||
if(hasObject) return; //this test checks if the weapon already has something picked up, if so then it cant use this function
|
||||
|
||||
PickUpObject(usage,dt); //first test if there is a nearby object to pickup
|
||||
|
||||
if(hasObject) return; //this test checks if the weapon has now picked up an object, if so then it shall not apply a force to suck in objects
|
||||
|
||||
|
||||
//if no object has been picked up then suck objects towards you
|
||||
Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (100 * dt);
|
||||
Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition());
|
||||
|
||||
Oyster::Math::Float4x4 hitSpace = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/4,1,1,20);
|
||||
Oyster::Collision3D::Frustrum hitFrustum = Oyster::Collision3D::Frustrum(Oyster::Math3D::ViewProjectionMatrix(aim,hitSpace));
|
||||
forcePushData args;
|
||||
args.pushForce = -pushForce;
|
||||
|
||||
Oyster::Physics::API::Instance().ApplyEffect(hitFrustum,&args,ForcePushAction);
|
||||
}
|
||||
|
||||
void AttatchmentMassDriver::PickUpObject(const WEAPON_FIRE &usage, float dt)
|
||||
{
|
||||
Oyster::Math::Float3 pos = owner->GetPosition() + owner->GetLookDir().GetNormalized()*5;
|
||||
Oyster::Collision3D::Sphere hitSphere = Oyster::Collision3D::Sphere(pos,20);
|
||||
/*Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition());
|
||||
|
||||
Oyster::Math::Float4x4 hitSpace = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/4,1,1,20);
|
||||
Oyster::Collision3D::Frustrum hitFrustum = Oyster::Collision3D::Frustrum(Oyster::Math3D::ViewProjectionMatrix(aim,hitSpace));
|
||||
*/
|
||||
|
||||
|
||||
Oyster::Physics::API::Instance().ApplyEffect(hitSphere,this,AttemptPickUp);
|
||||
}
|
||||
|
|
|
@ -16,29 +16,42 @@ namespace GameLogic
|
|||
|
||||
|
||||
void UseAttatchment(const WEAPON_FIRE &usage, float dt);
|
||||
void Update(float dt);
|
||||
|
||||
private:
|
||||
/********************************************************
|
||||
* Pushes objects and players in a cone in front of the player
|
||||
* @param fireInput: allows switching on different functionality in this specific function
|
||||
* @param usage: allows switching on different functionality in this specific function
|
||||
********************************************************/
|
||||
void ForcePush(const WEAPON_FIRE &usage, float dt);
|
||||
|
||||
/********************************************************
|
||||
* Pulls the player forward, this is a movement tool
|
||||
* @param fireInput: allows switching on different functionality in this specific function
|
||||
* @param usage: allows switching on different functionality in this specific function
|
||||
********************************************************/
|
||||
void ForceZip(const WEAPON_FIRE &usage, float dt);
|
||||
|
||||
/********************************************************
|
||||
* Sucks objects towards the player, the player can then pick up an object and throw it as a projectile
|
||||
* @param usage: allows switching on different functionality in this specific function
|
||||
********************************************************/
|
||||
void ForcePull(const WEAPON_FIRE &usage, float dt);
|
||||
|
||||
/********************************************************
|
||||
* Sucks objects towards the player, the player can then pick up an object and throw it as a projectile
|
||||
* @param fireInput: allows switching on different functionality in this specific function
|
||||
* @param usage: allows switching on different functionality in this specific function
|
||||
********************************************************/
|
||||
void ForceSuck(const WEAPON_FIRE &usage, float dt);
|
||||
void PickUpObject(const WEAPON_FIRE &usage, float dt);
|
||||
|
||||
|
||||
static void ForcePushAction(Oyster::Physics::ICustomBody *obj, void* args);
|
||||
static void AttemptPickUp(Oyster::Physics::ICustomBody *obj, void* args);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
Oyster::Physics::ICustomBody *heldObject;
|
||||
bool hasObject;
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,13 +5,15 @@
|
|||
#include "Level.h"
|
||||
#include "AttatchmentMassDriver.h"
|
||||
#include "Game.h"
|
||||
#include "CollisionManager.h"
|
||||
#include "JumpPad.h"
|
||||
|
||||
using namespace Oyster;
|
||||
|
||||
using namespace GameLogic;
|
||||
|
||||
void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss);
|
||||
void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss);
|
||||
void SendObjectFlying(Oyster::Physics::ICustomBody &obj, Oyster::Math::Float3 force);
|
||||
|
||||
//Physics::ICustomBody::SubscriptMessage
|
||||
void Player::PlayerCollision(Oyster::Physics::ICustomBody *rigidBodyPlayer, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss)
|
||||
|
@ -28,26 +30,48 @@ using namespace GameLogic;
|
|||
break;
|
||||
|
||||
case OBJECT_TYPE::OBJECT_TYPE_BOX:
|
||||
PlayerVBox(*player,(*(DynamicObject*) realObj), kineticEnergyLoss);
|
||||
PlayerVObject(*player,*realObj, kineticEnergyLoss);
|
||||
//return Physics::ICustomBody::SubscriptMessage_none;
|
||||
break;
|
||||
case OBJECT_TYPE::OBJECT_TYPE_PLAYER:
|
||||
//return Physics::ICustomBody::SubscriptMessage_none;
|
||||
break;
|
||||
case OBJECT_TYPE::OBJECT_TYPE_WORLD:
|
||||
int test = 5;
|
||||
PlayerVObject(*player,*realObj, kineticEnergyLoss);
|
||||
break;
|
||||
}
|
||||
|
||||
//return Physics::ICustomBody::SubscriptMessage_none;
|
||||
}
|
||||
|
||||
void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss)
|
||||
void JumpPad::JumpPadActivated(Oyster::Physics::ICustomBody *rigidBodyJumpPad, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss)
|
||||
{
|
||||
//use kinetic energyloss of the collision in order too determin how much damage to take
|
||||
//use as part of the damage algorithm
|
||||
player.DamageLife(20);
|
||||
JumpPad *jumpPad = (JumpPad*)(rigidBodyJumpPad->GetCustomTag());
|
||||
Object *realObj = (Object*)obj->GetCustomTag(); //needs to be changed?
|
||||
|
||||
switch (realObj->GetObjectType())
|
||||
{
|
||||
case OBJECT_TYPE::OBJECT_TYPE_GENERIC:
|
||||
break;
|
||||
case OBJECT_TYPE::OBJECT_TYPE_BOX:
|
||||
break;
|
||||
case OBJECT_TYPE::OBJECT_TYPE_PLAYER:
|
||||
SendObjectFlying(*obj, jumpPad->pushForce);
|
||||
break;
|
||||
case OBJECT_TYPE::OBJECT_TYPE_WORLD:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SendObjectFlying(Oyster::Physics::ICustomBody &obj, Oyster::Math::Float3 force)
|
||||
{
|
||||
Oyster::Physics::ICustomBody::State state;
|
||||
|
||||
state = obj.GetState();
|
||||
state.ApplyLinearImpulse(force);
|
||||
obj.SetState(state);
|
||||
}
|
||||
|
||||
|
||||
void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss)
|
||||
{
|
||||
|
@ -55,7 +79,7 @@ using namespace GameLogic;
|
|||
//use kinetic energyloss of the collision in order too determin how much damage to take
|
||||
//use as part of the damage algorithm
|
||||
int damageDone = 0;
|
||||
int forceThreashHold = 200;
|
||||
int forceThreashHold = 200000;
|
||||
|
||||
if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough
|
||||
{
|
||||
|
@ -77,6 +101,13 @@ using namespace GameLogic;
|
|||
{
|
||||
return Physics::ICustomBody::SubscriptMessage_ignore_collision_response;
|
||||
}
|
||||
|
||||
Oyster::Physics::ICustomBody::SubscriptMessage CollisionManager::IgnoreCollision(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustomBody *obj)
|
||||
{
|
||||
return Physics::ICustomBody::SubscriptMessage_ignore_collision_response;
|
||||
}
|
||||
|
||||
|
||||
Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss)
|
||||
{
|
||||
return Physics::ICustomBody::SubscriptMessage_ignore_collision_response;
|
||||
|
@ -94,3 +125,32 @@ using namespace GameLogic;
|
|||
state.ApplyLinearImpulse(((forcePushData*)(args))->pushForce);
|
||||
obj->SetState(state);
|
||||
}
|
||||
|
||||
void AttatchmentMassDriver::AttemptPickUp(Oyster::Physics::ICustomBody *obj, void* args)
|
||||
{
|
||||
AttatchmentMassDriver *weapon = ((AttatchmentMassDriver*)args);
|
||||
|
||||
if(weapon->hasObject)
|
||||
{
|
||||
//do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
Object* realObj = (Object*)(obj->GetCustomTag());
|
||||
//check so that it is an object that you can pickup
|
||||
|
||||
switch(realObj->GetObjectType())
|
||||
{
|
||||
case OBJECT_TYPE::OBJECT_TYPE_BOX:
|
||||
//move obj to limbo in physics to make sure it wont collide with anything
|
||||
Oyster::Physics::API::Instance().MoveToLimbo(obj);
|
||||
weapon->heldObject = obj; //weapon now holds the object
|
||||
weapon->hasObject = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -11,6 +11,7 @@ namespace GameLogic
|
|||
{
|
||||
public:
|
||||
//put general collision functions here that are not part of a specific object
|
||||
static Oyster::Physics::ICustomBody::SubscriptMessage IgnoreCollision(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustomBody *obj);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ GameAPI& GameAPI::Instance()
|
|||
Game::Game(void)
|
||||
: initiated(false)
|
||||
, onMoveFnc(0)
|
||||
, onDeadFnc(0)
|
||||
, onDisableFnc(0)
|
||||
, frameTime(1.0f/120.0f)
|
||||
{}
|
||||
|
||||
|
@ -129,7 +129,7 @@ void Game::SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::O
|
|||
this->onMoveFnc = functionPointer;
|
||||
break;
|
||||
case GameLogic::GameEvent::ObjectEventFunctionType_OnDead:
|
||||
this->onDeadFnc = functionPointer;
|
||||
this->onDisableFnc = functionPointer;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -162,6 +162,6 @@ void Game::PhysicsOnMove(const ICustomBody *object)
|
|||
}
|
||||
void Game::PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer<ICustomBody> proto)
|
||||
{
|
||||
|
||||
if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace GameLogic
|
|||
Oyster::Math::Float4x4 GetOrientation() override;
|
||||
int GetID() const override;
|
||||
OBJECT_TYPE GetObjectType() const override;
|
||||
void Rotate(const Oyster::Math3D::Float3 lookDir) override;
|
||||
void Rotate(const Oyster::Math3D::Float4 lookDir) override;
|
||||
|
||||
Player *player;
|
||||
};
|
||||
|
@ -80,7 +80,7 @@ namespace GameLogic
|
|||
LevelData* level;
|
||||
float frameTime;
|
||||
bool initiated;
|
||||
GameEvent::ObjectEventFunction onDeadFnc;
|
||||
GameEvent::ObjectEventFunction onDisableFnc;
|
||||
GameEvent::ObjectEventFunction onMoveFnc;
|
||||
|
||||
};
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace GameLogic
|
|||
* @param x: The relative x axis
|
||||
* @param y: The relative y axis
|
||||
**/
|
||||
virtual void Rotate(const Oyster::Math3D::Float3 lookDir) = 0;
|
||||
virtual void Rotate(const Oyster::Math3D::Float4 lookDir) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Uses the chosen players weapon based on input
|
||||
|
|
|
@ -183,6 +183,7 @@
|
|||
<ClInclude Include="GameLogicStates.h" />
|
||||
<ClInclude Include="GameMode.h" />
|
||||
<ClInclude Include="IAttatchment.h" />
|
||||
<ClInclude Include="JumpPad.h" />
|
||||
<ClInclude Include="Level.h" />
|
||||
<ClInclude Include="LevelLoader\LevelLoader.h" />
|
||||
<ClInclude Include="LevelLoader\Loader.h" />
|
||||
|
@ -206,6 +207,7 @@
|
|||
<ClCompile Include="Game_LevelData.cpp" />
|
||||
<ClCompile Include="Game_PlayerData.cpp" />
|
||||
<ClCompile Include="IAttatchment.cpp" />
|
||||
<ClCompile Include="JumpPad.cpp" />
|
||||
<ClCompile Include="Level.cpp" />
|
||||
<ClCompile Include="LevelLoader\LevelLoader.cpp" />
|
||||
<ClCompile Include="LevelLoader\Loader.cpp" />
|
||||
|
|
|
@ -11,13 +11,19 @@ Game::PlayerData::PlayerData()
|
|||
sbDesc.size = Oyster::Math::Float3(4,7,4);
|
||||
sbDesc.mass = 70;
|
||||
sbDesc.restitutionCoeff = 0.5;
|
||||
sbDesc.rotation = Oyster::Math::Float3(0, Oyster::Math::pi, 0);
|
||||
|
||||
//create rigid body
|
||||
Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release();
|
||||
|
||||
//create player with this rigid body
|
||||
this->player = new Player(rigidBody,Object::DefaultCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER);
|
||||
this->player->GetRigidBody()->SetCustomTag(this);
|
||||
|
||||
/*Oyster::Physics::ICustomBody::State state;
|
||||
this->player->GetRigidBody()->GetState(state);
|
||||
state.SetRotation(Oyster::Math::Float3(0, Oyster::Math::pi, 0));
|
||||
this->player->GetRigidBody()->SetState(state);
|
||||
player->EndFrame();*/
|
||||
}
|
||||
Game::PlayerData::PlayerData(int playerID,int teamID)
|
||||
{
|
||||
|
@ -61,7 +67,7 @@ OBJECT_TYPE Game::PlayerData::GetObjectType() const
|
|||
{
|
||||
return this->player->GetObjectType();
|
||||
}
|
||||
void Game::PlayerData::Rotate(const Oyster::Math3D::Float3 lookDir)
|
||||
void Game::PlayerData::Rotate(const Oyster::Math3D::Float4 lookDir)
|
||||
{
|
||||
this->player->Rotate(lookDir);
|
||||
}
|
|
@ -20,6 +20,7 @@ namespace GameLogic
|
|||
~IAttatchment(void);
|
||||
|
||||
virtual void UseAttatchment(const WEAPON_FIRE &usage, float dt) = 0;
|
||||
virtual void Update(float dt) = 0;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#include "JumpPad.h"
|
||||
#include "PhysicsAPI.h"
|
||||
|
||||
using namespace GameLogic;
|
||||
using namespace Oyster::Physics;
|
||||
|
||||
JumpPad::JumpPad(void)
|
||||
{
|
||||
}
|
||||
|
||||
JumpPad::JumpPad(Oyster::Physics::ICustomBody *rigidBody ,Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter), Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), OBJECT_TYPE type, Oyster::Math::Float3 pushForce)
|
||||
:StaticObject(rigidBody, collisionFuncBefore, collisionFuncAfter, type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
JumpPad::~JumpPad(void)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef JUMPPAD_H
|
||||
#define JUMPPAD_H
|
||||
#include "StaticObject.h"
|
||||
namespace GameLogic
|
||||
{
|
||||
class JumpPad : public StaticObject
|
||||
{
|
||||
public:
|
||||
JumpPad(void);
|
||||
|
||||
JumpPad(Oyster::Physics::ICustomBody *rigidBody
|
||||
,Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter)
|
||||
,Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss)
|
||||
,OBJECT_TYPE type, Oyster::Math::Float3 pushForce);
|
||||
|
||||
~JumpPad(void);
|
||||
|
||||
static void JumpPadActivated(Oyster::Physics::ICustomBody *rigidBodyJumpPad, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
|
||||
|
||||
private:
|
||||
Oyster::Math::Float3 pushForce;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
|
@ -34,7 +34,8 @@ void Level::InitiateLevel(float radius)
|
|||
sbDesc.ignoreGravity = true;
|
||||
sbDesc.radius = 300;
|
||||
sbDesc.mass = 10e12f;
|
||||
|
||||
sbDesc.frictionCoeff_Static = 0;
|
||||
sbDesc.frictionCoeff_Dynamic = 0;
|
||||
ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release();
|
||||
|
||||
ICustomBody::State state;
|
||||
|
@ -45,28 +46,32 @@ void Level::InitiateLevel(float radius)
|
|||
this->levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD);
|
||||
rigidBody->SetCustomTag(levelObj);
|
||||
|
||||
// add gravitation
|
||||
API::Gravity gravityWell;
|
||||
gravityWell.gravityType = API::Gravity::GravityType_Well;
|
||||
gravityWell.well.mass = 1e15f;
|
||||
gravityWell.well.position = Oyster::Math::Float3(0,0,0);
|
||||
API::Instance().AddGravity(gravityWell);
|
||||
|
||||
// add box
|
||||
API::SimpleBodyDescription sbDesc_TestBox;
|
||||
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10,320,0,0);
|
||||
sbDesc_TestBox.ignoreGravity = false;
|
||||
|
||||
sbDesc_TestBox.mass = 50;
|
||||
sbDesc_TestBox.size = Oyster::Math::Float4(4,4,4,0);
|
||||
|
||||
|
||||
ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
|
||||
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
|
||||
|
||||
testBox = new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX);
|
||||
rigidBody_TestBox->SetCustomTag(testBox);
|
||||
rigidBody_TestBox->GetState(state);
|
||||
state.ApplyLinearImpulse(Oyster::Math::Float3(1,0,0));
|
||||
state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,0));
|
||||
rigidBody_TestBox->SetState(state);
|
||||
|
||||
|
||||
// add gravitation
|
||||
API::Gravity gravityWell;
|
||||
gravityWell.gravityType = API::Gravity::GravityType_Well;
|
||||
gravityWell.well.mass = 1e18f;
|
||||
gravityWell.well.position = Oyster::Math::Float4(0,0,0,1);
|
||||
API::Instance().AddGravity(gravityWell);
|
||||
}
|
||||
|
||||
void Level::AddPlayerToTeam(Player *player, int teamID)
|
||||
|
|
|
@ -3,16 +3,30 @@
|
|||
//////////////////////////////////
|
||||
|
||||
#include "LevelLoader.h"
|
||||
#include "LevelParser.h"
|
||||
using namespace GameLogic;
|
||||
using namespace GameLogic::LevelFileLoader;
|
||||
|
||||
|
||||
std::vector<ObjectTypeHeader> LevelLoader::LoadLevel(std::string fileName)
|
||||
struct LevelLoader::PrivData
|
||||
{
|
||||
return parser.Parse(fileName);
|
||||
LevelParser parser;
|
||||
};
|
||||
|
||||
LevelLoader::LevelLoader()
|
||||
: pData(new PrivData)
|
||||
{
|
||||
}
|
||||
|
||||
LevelLoader::~LevelLoader()
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<Utility::DynamicMemory::SmartPointer<ObjectTypeHeader>> LevelLoader::LoadLevel(std::string fileName)
|
||||
{
|
||||
return pData->parser.Parse(fileName);
|
||||
}
|
||||
|
||||
LevelMetaData LevelLoader::LoadLevelHeader(std::string fileName)
|
||||
{
|
||||
return parser.ParseHeader(fileName);
|
||||
return pData->parser.ParseHeader(fileName);
|
||||
}
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <Vector.h>
|
||||
#include "../Misc/Utilities.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "LevelParser.h"
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
|
@ -17,15 +16,15 @@ namespace GameLogic
|
|||
{
|
||||
|
||||
public:
|
||||
LevelLoader(){this->parser = GameLogic::LevelFileLoader::LevelParser(); }
|
||||
~LevelLoader(){}
|
||||
LevelLoader();
|
||||
~LevelLoader();
|
||||
|
||||
/********************************************************
|
||||
* Loads the level and objects from file.
|
||||
* @param fileName: Path to the level-file that you want to load.
|
||||
* @return: Returns all structs with objects and information about the level.
|
||||
********************************************************/
|
||||
std::vector<ObjectTypeHeader> LoadLevel(std::string fileName);
|
||||
std::vector<Utility::DynamicMemory::SmartPointer<ObjectTypeHeader>> LoadLevel(std::string fileName);
|
||||
|
||||
/********************************************************
|
||||
* Just for fast access for the meta information about the level.
|
||||
|
@ -35,7 +34,8 @@ namespace GameLogic
|
|||
LevelMetaData LoadLevelHeader(std::string fileName); //.
|
||||
|
||||
private:
|
||||
GameLogic::LevelFileLoader::LevelParser parser;
|
||||
struct PrivData;
|
||||
Utility::DynamicMemory::SmartPointer<PrivData> pData;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
using namespace GameLogic;
|
||||
using namespace ::LevelFileLoader;
|
||||
using namespace Utility::DynamicMemory;
|
||||
|
||||
LevelParser::LevelParser()
|
||||
{
|
||||
|
@ -16,12 +17,12 @@ LevelParser::~LevelParser()
|
|||
{
|
||||
}
|
||||
|
||||
std::vector<ObjectTypeHeader> LevelParser::Parse(std::string filename)
|
||||
std::vector<SmartPointer<ObjectTypeHeader>> LevelParser::Parse(std::string filename)
|
||||
{
|
||||
int bufferSize = 0;
|
||||
int counter = 0;
|
||||
|
||||
std::vector<ObjectTypeHeader> objects;
|
||||
std::vector<SmartPointer<ObjectTypeHeader>> objects;
|
||||
|
||||
//Read entire level file.
|
||||
Loader loader;
|
||||
|
@ -29,7 +30,8 @@ std::vector<ObjectTypeHeader> LevelParser::Parse(std::string filename)
|
|||
|
||||
//Read format version
|
||||
FormatVersion levelFormatVersion;
|
||||
//ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion));
|
||||
ParseObject(&buffer[counter], &levelFormatVersion, sizeof(levelFormatVersion));
|
||||
counter += sizeof(levelFormatVersion);
|
||||
if(this->formatVersion != levelFormatVersion)
|
||||
{
|
||||
//Do something if it's not the same version
|
||||
|
@ -44,21 +46,60 @@ std::vector<ObjectTypeHeader> LevelParser::Parse(std::string filename)
|
|||
{
|
||||
case ObjectType_LevelMetaData:
|
||||
{
|
||||
LevelMetaData header;
|
||||
ParseLevelMetaData(&buffer[counter], header, counter);
|
||||
LevelMetaData* header = new LevelMetaData;
|
||||
ParseLevelMetaData(&buffer[counter], *header, counter);
|
||||
objects.push_back(header);
|
||||
break;
|
||||
}
|
||||
|
||||
case ObjectType_Dynamic:
|
||||
//This is by design, static and dynamic is using the same converter. Do not add anything inbetween them.
|
||||
case ObjectType_Static: case ObjectType_Dynamic:
|
||||
{
|
||||
ObjectHeader header;
|
||||
ParseObject(&buffer[counter], &header, sizeof(header));
|
||||
ObjectHeader* header = new ObjectHeader;
|
||||
ParseObject(&buffer[counter], *header, counter);
|
||||
objects.push_back(header);
|
||||
counter += sizeof(header);
|
||||
break;
|
||||
}
|
||||
|
||||
case ObjectType_Light:
|
||||
{
|
||||
LightType lightType;
|
||||
|
||||
//Get Light type
|
||||
ParseObject(&buffer[counter+4], &lightType, sizeof(lightType));
|
||||
|
||||
switch(lightType)
|
||||
{
|
||||
case LightType_PointLight:
|
||||
{
|
||||
PointLight* header = new PointLight;
|
||||
ParseObject(&buffer[counter], header, sizeof(*header));
|
||||
counter += sizeof(*header);
|
||||
objects.push_back(header);
|
||||
break;
|
||||
}
|
||||
case LightType_DirectionalLight:
|
||||
{
|
||||
DirectionalLight* header = new DirectionalLight;
|
||||
ParseObject(&buffer[counter], header, sizeof(*header));
|
||||
counter += sizeof(*header);
|
||||
objects.push_back(header);
|
||||
break;
|
||||
}
|
||||
case LightType_SpotLight:
|
||||
{
|
||||
SpotLight* header = new SpotLight;
|
||||
ParseObject(&buffer[counter], header, sizeof(*header));
|
||||
counter += sizeof(*header);
|
||||
objects.push_back(header);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
//Undefined LightType.
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
//Couldn't find typeID. FAIL!!!!!!
|
||||
break;
|
||||
|
@ -83,7 +124,8 @@ LevelMetaData LevelParser::ParseHeader(std::string filename)
|
|||
|
||||
//Read format version
|
||||
FormatVersion levelFormatVersion;
|
||||
//ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion));
|
||||
ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion));
|
||||
counter += sizeof(levelFormatVersion);
|
||||
if(this->formatVersion != levelFormatVersion)
|
||||
{
|
||||
//Do something if it's not the same version
|
||||
|
@ -101,11 +143,42 @@ LevelMetaData LevelParser::ParseHeader(std::string filename)
|
|||
ParseLevelMetaData(&buffer[counter], levelHeader, counter);
|
||||
return levelHeader;
|
||||
break;
|
||||
case ObjectType_Dynamic:
|
||||
//Do not call parse this object, since we are only interested in the LevelMetaData
|
||||
//Only increase the counter size
|
||||
counter += sizeof(ObjectHeader);
|
||||
|
||||
//This is by design, static and dynamic is using the same converter. Do not add anything inbetween them.
|
||||
case ObjectType_Static: case ObjectType_Dynamic:
|
||||
{
|
||||
ObjectHeader header;
|
||||
ParseObject(&buffer[counter], header, counter);
|
||||
break;
|
||||
}
|
||||
|
||||
case ObjectType_Light:
|
||||
{
|
||||
LightType lightType;
|
||||
ParseObject(&buffer[counter+4], &lightType, sizeof(lightType));
|
||||
|
||||
switch(lightType)
|
||||
{
|
||||
case LightType_PointLight:
|
||||
{
|
||||
counter += sizeof(PointLight);
|
||||
break;
|
||||
}
|
||||
case LightType_DirectionalLight:
|
||||
{
|
||||
counter += sizeof(DirectionalLight);
|
||||
break;
|
||||
}
|
||||
case LightType_SpotLight:
|
||||
{
|
||||
counter += sizeof(SpotLight);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
//Undefined LightType.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
//Couldn't find typeID. FAIL!!!!!!
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include "ObjectDefines.h"
|
||||
#include "../Misc/Utilities.h"
|
||||
|
||||
namespace GameLogic
|
||||
{
|
||||
|
@ -16,7 +17,7 @@ namespace GameLogic
|
|||
~LevelParser();
|
||||
|
||||
//
|
||||
std::vector<ObjectTypeHeader> Parse(std::string filename);
|
||||
std::vector<Utility::DynamicMemory::SmartPointer<ObjectTypeHeader>> Parse(std::string filename);
|
||||
|
||||
//
|
||||
LevelMetaData ParseHeader(std::string filename);
|
||||
|
|
|
@ -15,11 +15,12 @@ namespace GameLogic
|
|||
ObjectType_LevelMetaData,
|
||||
ObjectType_Static,
|
||||
ObjectType_Dynamic,
|
||||
ObjectType_Light,
|
||||
//Etc
|
||||
|
||||
ObjectType_NUM_OF_TYPES,
|
||||
|
||||
ObjectType_Unknown = -1,
|
||||
ObjectType_Unknown = -1
|
||||
};
|
||||
|
||||
enum UsePhysics
|
||||
|
@ -27,9 +28,20 @@ namespace GameLogic
|
|||
UsePhysics_UseFullPhysics,
|
||||
UsePhysics_IgnoreGravity,
|
||||
UsePhysics_IgnorePhysics,
|
||||
UsePhysics_IgnoreCollision,
|
||||
|
||||
UsePhysics_Count,
|
||||
UsePhysics_Unknown = -1,
|
||||
UsePhysics_Unknown = -1
|
||||
};
|
||||
|
||||
enum LightType
|
||||
{
|
||||
LightType_PointLight,
|
||||
LightType_DirectionalLight,
|
||||
LightType_SpotLight,
|
||||
|
||||
LightType_Count,
|
||||
LightType_Unknown = -1
|
||||
};
|
||||
|
||||
//Should this be moved somewhere else?
|
||||
|
@ -40,7 +52,7 @@ namespace GameLogic
|
|||
//Etc
|
||||
|
||||
GameMode_Count,
|
||||
GameMode_Unknown = -1,
|
||||
GameMode_Unknown = -1
|
||||
};
|
||||
|
||||
|
||||
|
@ -71,32 +83,31 @@ namespace GameLogic
|
|||
|
||||
struct PhysicsObject
|
||||
{
|
||||
UsePhysics usePhysics;
|
||||
float mass;
|
||||
float elasticity;
|
||||
float inertiaMagnitude[3];
|
||||
float inertiaRotation[3];
|
||||
float frictionCoeffStatic;
|
||||
float frictionCoeffDynamic;
|
||||
float inertiaTensor[16];
|
||||
UsePhysics usePhysics;
|
||||
|
||||
};
|
||||
|
||||
struct LevelMetaData : ObjectTypeHeader
|
||||
{
|
||||
std::string levelName;
|
||||
FormatVersion levelVersion;
|
||||
int levelVersion;
|
||||
std::string levelDescription;
|
||||
std::string levelAuthor;
|
||||
int maxNumberOfPlayer;
|
||||
float worldSize;
|
||||
int overviewPictureID;
|
||||
int worldSize;
|
||||
std::string overviewPicturePath;
|
||||
std::vector<GameMode> gameModesSupported;
|
||||
};
|
||||
|
||||
struct ObjectHeader : public ObjectTypeHeader
|
||||
{
|
||||
//Model,
|
||||
int ModelID;
|
||||
//Texture
|
||||
int TextureID;
|
||||
std::string ModelFile;
|
||||
//Position
|
||||
float position[3];
|
||||
//Rotation
|
||||
|
@ -104,6 +115,36 @@ namespace GameLogic
|
|||
//Scale
|
||||
float scale[3];
|
||||
};
|
||||
|
||||
|
||||
/************************************
|
||||
Lights
|
||||
*************************************/
|
||||
|
||||
struct BasicLight : public ObjectTypeHeader
|
||||
{
|
||||
LightType lightType;
|
||||
float ambientColor[3];
|
||||
float diffuseColor[3];
|
||||
float specularColor[3];
|
||||
};
|
||||
|
||||
struct PointLight : public BasicLight
|
||||
{
|
||||
float position[3];
|
||||
};
|
||||
|
||||
struct DirectionalLight : public BasicLight
|
||||
{
|
||||
float direction[3];
|
||||
};
|
||||
|
||||
struct SpotLight : public BasicLight
|
||||
{
|
||||
float direction[3];
|
||||
float range;
|
||||
float attenuation[3];
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -20,11 +20,33 @@ namespace GameLogic
|
|||
memcpy(header, buffer, size);
|
||||
}
|
||||
|
||||
void ParseObject(char* buffer, ObjectHeader& header, int& size)
|
||||
{
|
||||
char tempName[128];
|
||||
int tempSize = 0;
|
||||
int start = 0;
|
||||
|
||||
memcpy(&header.typeID, &buffer[start], 4);
|
||||
start += 4;
|
||||
|
||||
memcpy(&tempSize, &buffer[start], 4);
|
||||
start += 4;
|
||||
|
||||
memcpy(&tempName, &buffer[start], tempSize);
|
||||
header.ModelFile.assign(&tempName[0], &tempName[tempSize]);
|
||||
start += tempSize;
|
||||
|
||||
memcpy(&header.position, &buffer[start], 36);
|
||||
start += 36;
|
||||
|
||||
size += start;
|
||||
}
|
||||
|
||||
void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size)
|
||||
{
|
||||
int start = 0;
|
||||
int tempSize;
|
||||
char tempName[100];
|
||||
char tempName[128];
|
||||
|
||||
memcpy(&header.typeID, &buffer[start], 4);
|
||||
start += 4;
|
||||
|
@ -36,8 +58,8 @@ namespace GameLogic
|
|||
header.levelName.assign(&tempName[0], &tempName[tempSize]);
|
||||
start += tempSize;
|
||||
|
||||
memcpy(&header.levelVersion, &buffer[start], 8);
|
||||
start += 8;
|
||||
memcpy(&header.levelVersion, &buffer[start], 4);
|
||||
start += 4;
|
||||
|
||||
memcpy(&tempSize, &buffer[start], 4);
|
||||
start +=4;
|
||||
|
@ -59,9 +81,13 @@ namespace GameLogic
|
|||
memcpy(&header.worldSize, &buffer[start], 4);
|
||||
start += 4;
|
||||
|
||||
memcpy(&header.overviewPictureID, &buffer[start], 4);
|
||||
memcpy(&tempSize, &buffer[start], 4);
|
||||
start += 4;
|
||||
|
||||
memcpy(&tempName, &buffer[start], tempSize);
|
||||
header.overviewPicturePath.assign(&tempName[0], &tempName[tempSize]);
|
||||
start += tempSize;
|
||||
|
||||
memcpy(&tempSize, &buffer[start], 4);
|
||||
start += 4;
|
||||
|
||||
|
|
|
@ -10,7 +10,16 @@ namespace GameLogic
|
|||
{
|
||||
namespace LevelFileLoader
|
||||
{
|
||||
/*
|
||||
These functions will copy data from where the buffer pointer points.
|
||||
header is the destination where the data will be copied.
|
||||
size is either the size of the data to be copied (if it is NOT sent by reference).
|
||||
Or the current index that is being used to parse the entire file (if it is sent by reference) this means you have to increase size with the appropiate size after you have copied.
|
||||
|
||||
*/
|
||||
|
||||
void ParseObject(char* buffer, void *header, int size);
|
||||
void ParseObject(char* buffer, ObjectHeader& header, int& size);
|
||||
void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,8 +22,8 @@ Object::Object()
|
|||
|
||||
this->type = OBJECT_TYPE::OBJECT_TYPE_UNKNOWN;
|
||||
this->objectID = GID();
|
||||
this->getState = this->rigidBody->GetState();
|
||||
this->setState = this->getState;
|
||||
this->currPhysicsState = this->rigidBody->GetState();
|
||||
this->newPhysicsState = this->currPhysicsState;
|
||||
}
|
||||
|
||||
Object::Object(OBJECT_TYPE type)
|
||||
|
@ -34,8 +34,8 @@ Object::Object(OBJECT_TYPE type)
|
|||
Oyster::Physics::API::Instance().AddObject(rigidBody);
|
||||
this->type = type;
|
||||
this->objectID = GID();
|
||||
this->getState = this->rigidBody->GetState();
|
||||
this->setState = this->getState;
|
||||
this->currPhysicsState = this->rigidBody->GetState();
|
||||
this->newPhysicsState = this->currPhysicsState;
|
||||
}
|
||||
|
||||
Object::Object(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type)
|
||||
|
@ -44,8 +44,8 @@ Object::Object(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type)
|
|||
this->rigidBody = rigidBody;
|
||||
this->type = type;
|
||||
this->objectID = GID();
|
||||
this->getState = this->rigidBody->GetState();
|
||||
this->setState = this->getState;
|
||||
this->currPhysicsState = this->rigidBody->GetState();
|
||||
this->newPhysicsState = this->currPhysicsState;
|
||||
}
|
||||
|
||||
Object::Object(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type)
|
||||
|
@ -57,8 +57,8 @@ Object::Object(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE
|
|||
|
||||
this->type = type;
|
||||
this->objectID = GID();
|
||||
this->getState = this->rigidBody->GetState();
|
||||
this->setState = this->getState;
|
||||
this->currPhysicsState = this->rigidBody->GetState();
|
||||
this->newPhysicsState = this->currPhysicsState;
|
||||
}
|
||||
|
||||
Object::Object(Oyster::Physics::ICustomBody *rigidBody ,void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type)
|
||||
|
@ -71,8 +71,8 @@ Object::Object(Oyster::Physics::ICustomBody *rigidBody ,void* collisionFuncBefor
|
|||
|
||||
this->type = type;
|
||||
this->objectID = GID();
|
||||
this->getState = this->rigidBody->GetState();
|
||||
this->setState = this->getState;
|
||||
this->currPhysicsState = this->rigidBody->GetState();
|
||||
this->newPhysicsState = this->currPhysicsState;
|
||||
}
|
||||
|
||||
Object::Object(Oyster::Physics::ICustomBody *rigidBody ,Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter), Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), OBJECT_TYPE type)
|
||||
|
@ -86,13 +86,13 @@ Object::Object(Oyster::Physics::ICustomBody *rigidBody ,Oyster::Physics::ICustom
|
|||
|
||||
this->type = type;
|
||||
this->objectID = GID();
|
||||
this->getState = this->rigidBody->GetState();
|
||||
this->setState = this->getState;
|
||||
this->currPhysicsState = this->rigidBody->GetState();
|
||||
this->newPhysicsState = this->currPhysicsState;
|
||||
}
|
||||
|
||||
void Object::ApplyLinearImpulse(Oyster::Math::Float3 force)
|
||||
{
|
||||
setState.ApplyLinearImpulse(force);
|
||||
newPhysicsState.ApplyLinearImpulse(force);
|
||||
}
|
||||
|
||||
|
||||
|
@ -118,24 +118,33 @@ Oyster::Physics::ICustomBody* Object::GetRigidBody()
|
|||
|
||||
void Object::BeginFrame()
|
||||
{
|
||||
Oyster::Math::Float4 axis;
|
||||
if(setState.GetGravityNormal()!= Float3::null)
|
||||
{
|
||||
Oyster::Math3D::SnapAngularAxis(Oyster::Math::Float4(setState.GetAngularAxis(), 0), Oyster::Math::Float4::standard_unit_y, -Oyster::Math::Float4(setState.GetGravityNormal()), axis);
|
||||
setState.SetRotation(axis.xyz);
|
||||
setState.SetAngularMomentum(Float3::null);
|
||||
Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y);
|
||||
debug += setState.GetGravityNormal();
|
||||
}
|
||||
|
||||
|
||||
this->rigidBody->SetState(this->setState);
|
||||
|
||||
|
||||
|
||||
this->rigidBody->SetState(this->newPhysicsState);
|
||||
}
|
||||
// update physic
|
||||
void Object::EndFrame()
|
||||
{
|
||||
this->getState = this->rigidBody->GetState();
|
||||
this->setState = this->getState;
|
||||
this->currPhysicsState = this->rigidBody->GetState();
|
||||
|
||||
if(currPhysicsState.GetGravityNormal()!= Float3::null)
|
||||
{
|
||||
Oyster::Math::Float4 axis;
|
||||
Oyster::Math3D::SnapAngularAxis(Oyster::Math::Float4(currPhysicsState.GetAngularAxis(), 0), Oyster::Math::Float4::standard_unit_y, -Oyster::Math::Float4(currPhysicsState.GetGravityNormal()), axis);
|
||||
if(axis !=axis)
|
||||
{
|
||||
//error
|
||||
int i =0 ;
|
||||
}
|
||||
currPhysicsState.SetRotation(axis.xyz);
|
||||
currPhysicsState.SetAngularMomentum(Float3::null);
|
||||
Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y);
|
||||
debug += currPhysicsState.GetGravityNormal();
|
||||
}
|
||||
this->newPhysicsState = this->currPhysicsState;
|
||||
}
|
||||
|
||||
void Object::setBeforeCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter))
|
||||
|
|
|
@ -35,8 +35,8 @@ namespace GameLogic
|
|||
Oyster::Physics::ICustomBody* GetRigidBody();
|
||||
void ApplyLinearImpulse(Oyster::Math::Float3 force);
|
||||
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
virtual void BeginFrame();
|
||||
virtual void EndFrame();
|
||||
|
||||
void setBeforeCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter));
|
||||
void setAfterCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss));
|
||||
|
@ -49,11 +49,12 @@ namespace GameLogic
|
|||
|
||||
protected:
|
||||
Oyster::Physics::ICustomBody *rigidBody;
|
||||
Oyster::Physics::ICustomBody::State setState;
|
||||
Oyster::Physics::ICustomBody::State getState;
|
||||
Oyster::Physics::ICustomBody::State newPhysicsState;
|
||||
Oyster::Physics::ICustomBody::State currPhysicsState;
|
||||
|
||||
static const Game* gameInstance;
|
||||
|
||||
Oyster::Math::Float3 currLook;
|
||||
Oyster::Math::Float3 newLook;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -58,6 +58,18 @@ Player::~Player(void)
|
|||
}
|
||||
}
|
||||
|
||||
void Player::BeginFrame()
|
||||
{
|
||||
weapon->Update(0.002f);
|
||||
Object::BeginFrame();
|
||||
}
|
||||
|
||||
void Player::EndFrame()
|
||||
{
|
||||
|
||||
Object::EndFrame();
|
||||
}
|
||||
|
||||
void Player::Move(const PLAYER_MOVEMENT &movement)
|
||||
{
|
||||
switch(movement)
|
||||
|
@ -86,24 +98,32 @@ void Player::Move(const PLAYER_MOVEMENT &movement)
|
|||
|
||||
void Player::MoveForward()
|
||||
{
|
||||
setState.ApplyLinearImpulse(this->lookDir * (2000 * this->gameInstance->GetFrameTime()));
|
||||
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
|
||||
//Oyster::Math::Float3 forward = lookDir;
|
||||
newPhysicsState.ApplyLinearImpulse(forward * (30000 * this->gameInstance->GetFrameTime()));
|
||||
}
|
||||
void Player::MoveBackwards()
|
||||
{
|
||||
setState.ApplyLinearImpulse(-this->lookDir * 2000 * this->gameInstance->GetFrameTime());
|
||||
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
|
||||
//Oyster::Math::Float3 forward = lookDir;
|
||||
newPhysicsState.ApplyLinearImpulse(-forward * 30000 * this->gameInstance->GetFrameTime());
|
||||
}
|
||||
void Player::MoveRight()
|
||||
{
|
||||
//Do cross product with forward vector and negative gravity vector
|
||||
Oyster::Math::Float3 r = (-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)this->lookDir);
|
||||
setState.ApplyLinearImpulse(r * 2000 * this->gameInstance->GetFrameTime());
|
||||
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
|
||||
//Oyster::Math::Float3 forward = lookDir;
|
||||
Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward);
|
||||
newPhysicsState.ApplyLinearImpulse(-r * 30000 * this->gameInstance->GetFrameTime());
|
||||
|
||||
}
|
||||
void Player::MoveLeft()
|
||||
{
|
||||
//Do cross product with forward vector and negative gravity vector
|
||||
Oyster::Math::Float3 r = -(-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)this->lookDir); //Still get zero
|
||||
setState.ApplyLinearImpulse(-r * 2000 * this->gameInstance->GetFrameTime());
|
||||
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
|
||||
//Oyster::Math::Float3 forward = lookDir;
|
||||
Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); //Still get zero
|
||||
newPhysicsState.ApplyLinearImpulse(r * 30000 * this->gameInstance->GetFrameTime());
|
||||
}
|
||||
|
||||
void Player::UseWeapon(const WEAPON_FIRE &usage)
|
||||
|
@ -113,31 +133,32 @@ void Player::UseWeapon(const WEAPON_FIRE &usage)
|
|||
|
||||
void Player::Respawn(Oyster::Math::Float3 spawnPoint)
|
||||
{
|
||||
|
||||
this->life = 100;
|
||||
this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE;
|
||||
this->lookDir = Oyster::Math::Float4(1,0,0);
|
||||
this->newPhysicsState.SetCenterPosition(spawnPoint);
|
||||
}
|
||||
|
||||
void Player::Rotate(const Oyster::Math3D::Float3 lookDir)
|
||||
void Player::Rotate(const Oyster::Math3D::Float4 lookDir)
|
||||
{
|
||||
this->lookDir = lookDir;
|
||||
Oyster::Math::Float dx = lookDir.w;
|
||||
if(dx > 0.0f)
|
||||
{
|
||||
int i =0 ;
|
||||
}
|
||||
Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1];
|
||||
Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ;
|
||||
Oyster::Math::Float3 oldOrt = currPhysicsState.GetRotation();
|
||||
|
||||
Oyster::Math::Float4 up = -setState.GetGravityNormal();
|
||||
Oyster::Math::Float4 pos = setState.GetCenterPosition();
|
||||
Oyster::Math::Float4x4 world = Oyster::Math3D::OrientationMatrix_LookAtDirection(lookDir, up.xyz, pos.xyz);
|
||||
// cant set rotation
|
||||
//setState.SetOrientation(world);
|
||||
//this->lookDir = lookDir - up.xyz;
|
||||
//this->lookDir = lookDir;
|
||||
newPhysicsState.SetRotation(oldOrt + deltaAxis);
|
||||
|
||||
//this->setState.AddRotation(Oyster::Math::Float4(x, y));
|
||||
//this->setState.SetRotation();
|
||||
this->lookDir = lookDir.xyz;
|
||||
}
|
||||
|
||||
void Player::Jump()
|
||||
{
|
||||
|
||||
Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1];
|
||||
newPhysicsState.ApplyLinearImpulse(up * 30000 * this->gameInstance->GetFrameTime());
|
||||
}
|
||||
|
||||
bool Player::IsWalking()
|
||||
|
@ -155,11 +176,11 @@ bool Player::IsIdle()
|
|||
|
||||
Oyster::Math::Float3 Player::GetPosition() const
|
||||
{
|
||||
return (Oyster::Math::Float3)getState.GetCenterPosition();
|
||||
return (Oyster::Math::Float3)currPhysicsState.GetCenterPosition();
|
||||
}
|
||||
Oyster::Math::Float4x4 Player::GetOrientation() const
|
||||
{
|
||||
return this->getState.GetOrientation();
|
||||
return this->currPhysicsState.GetOrientation();
|
||||
}
|
||||
Oyster::Math::Float3 Player::GetLookDir() const
|
||||
{
|
||||
|
@ -177,5 +198,13 @@ PLAYER_STATE Player::GetState() const
|
|||
void Player::DamageLife(int damage)
|
||||
{
|
||||
this->life -= damage;
|
||||
this->life = 0;
|
||||
|
||||
if(this->life <= 0)
|
||||
{
|
||||
this->life = 0;
|
||||
playerState = PLAYER_STATE_DEAD;
|
||||
this->gameInstance->onDisableFnc(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace GameLogic
|
|||
void Respawn(Oyster::Math::Float3 spawnPoint);
|
||||
|
||||
|
||||
void Rotate(const Oyster::Math3D::Float3 lookDir);
|
||||
void Rotate(const Oyster::Math3D::Float4 lookDir);
|
||||
|
||||
/********************************************************
|
||||
* Collision function for player, this is to be sent to physics through the subscribe function with the rigidbody
|
||||
|
@ -71,6 +71,9 @@ namespace GameLogic
|
|||
|
||||
void DamageLife(int damage);
|
||||
|
||||
void BeginFrame();
|
||||
void EndFrame();
|
||||
|
||||
private:
|
||||
void Jump();
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "StaticObject.h"
|
||||
#include "CollisionManager.h"
|
||||
|
||||
using namespace GameLogic;
|
||||
|
||||
|
@ -17,7 +18,8 @@ StaticObject::StaticObject(OBJECT_TYPE type)
|
|||
StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type)
|
||||
:Object(rigidBody,type)
|
||||
{
|
||||
|
||||
this->rigidBody->SetGravity(true);
|
||||
this->rigidBody->SetSubscription((Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse)(CollisionManager::IgnoreCollision));
|
||||
}
|
||||
|
||||
StaticObject::StaticObject(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type)
|
||||
|
|
|
@ -138,3 +138,8 @@ void Weapon::SelectAttatchment(int socketID)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
void Weapon::Update(float dt)
|
||||
{
|
||||
selectedAttatchment->Update(dt);
|
||||
}
|
|
@ -20,6 +20,7 @@ namespace GameLogic
|
|||
~Weapon(void);
|
||||
|
||||
void Use(const WEAPON_FIRE &usage, float dt);
|
||||
void Update(float dt);
|
||||
|
||||
void AddNewAttatchment(IAttatchment *attatchment, Player *owner);
|
||||
void SwitchAttatchment(IAttatchment *attatchment, int socketID, Player *owner);
|
||||
|
|
|
@ -69,6 +69,7 @@ namespace GameLogic
|
|||
float lookDirX;
|
||||
float lookDirY;
|
||||
float lookDirZ;
|
||||
float deltaX;
|
||||
|
||||
Protocol_PlayerLook()
|
||||
{
|
||||
|
@ -78,6 +79,7 @@ namespace GameLogic
|
|||
this->protocol[1].type = Oyster::Network::NetAttributeType_Float;
|
||||
this->protocol[2].type = Oyster::Network::NetAttributeType_Float;
|
||||
this->protocol[3].type = Oyster::Network::NetAttributeType_Float;
|
||||
this->protocol[4].type = Oyster::Network::NetAttributeType_Float;
|
||||
|
||||
}
|
||||
Protocol_PlayerLook(Oyster::Network::CustomNetProtocol& p)
|
||||
|
@ -85,12 +87,14 @@ namespace GameLogic
|
|||
lookDirX = p[1].value.netFloat;
|
||||
lookDirY = p[2].value.netFloat;
|
||||
lookDirZ = p[3].value.netFloat;
|
||||
deltaX = p[4].value.netFloat;
|
||||
}
|
||||
const Protocol_PlayerLook& operator=(Oyster::Network::CustomNetProtocol& val)
|
||||
{
|
||||
lookDirX = val[1].value.netFloat;
|
||||
lookDirY = val[2].value.netFloat;
|
||||
lookDirZ = val[3].value.netFloat;
|
||||
deltaX = val[4].value.netFloat;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -99,6 +103,8 @@ namespace GameLogic
|
|||
this->protocol[1].value = lookDirX;
|
||||
this->protocol[2].value = lookDirY;
|
||||
this->protocol[3].value = lookDirZ;
|
||||
this->protocol[4].value = deltaX;
|
||||
|
||||
|
||||
return protocol;
|
||||
}
|
||||
|
|
|
@ -200,6 +200,9 @@
|
|||
<ProjectReference Include="..\..\OysterMath\OysterMath.vcxproj">
|
||||
<Project>{f10cbc03-9809-4cba-95d8-327c287b18ee}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\GameLogic\GameLogic.vcxproj">
|
||||
<Project>{b1195bb9-b3a5-47f0-906c-8dea384d1520}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
@ -176,10 +176,11 @@ namespace DanBias
|
|||
}
|
||||
void GameSession::Gameplay_PlayerLookDir ( Protocol_PlayerLook& p, DanBias::GameClient* c )
|
||||
{
|
||||
Oyster::Math3D::Float3 lookDir;
|
||||
Oyster::Math3D::Float4 lookDir;
|
||||
lookDir.x = p.lookDirX;
|
||||
lookDir.y = p.lookDirY;
|
||||
lookDir.z = p.lookDirZ;
|
||||
lookDir.w = p.deltaX;
|
||||
c->GetPlayer()->Rotate(lookDir);
|
||||
}
|
||||
void GameSession::Gameplay_PlayerChangeWeapon ( Protocol_PlayerChangeWeapon& p, DanBias::GameClient* c )
|
||||
|
@ -188,7 +189,9 @@ namespace DanBias
|
|||
}
|
||||
void GameSession::Gameplay_PlayerShot ( Protocol_PlayerShot& p, DanBias::GameClient* c )
|
||||
{
|
||||
c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS);
|
||||
//c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS);
|
||||
c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_SECONDARY_PRESS);
|
||||
//c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS);
|
||||
}
|
||||
void GameSession::Gameplay_PlayerJump ( Protocol_PlayerJump& p, DanBias::GameClient* c )
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@ void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef)
|
|||
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);
|
||||
|
||||
|
@ -64,6 +65,33 @@ void Octree::MoveToUpdateQueue(UniquePointer< ICustomBody > customBodyRef)
|
|||
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);
|
||||
|
@ -86,7 +114,7 @@ std::vector<ICustomBody*>& Octree::Sample(ICustomBody* customBodyRef, std::vecto
|
|||
|
||||
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
||||
{
|
||||
if(tempRef != i) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
|
||||
if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
|
||||
{
|
||||
updateList.push_back(this->leafData[i].customBodyRef);
|
||||
}
|
||||
|
@ -99,7 +127,7 @@ std::vector<ICustomBody*>& Octree::Sample(const Oyster::Collision3D::ICollideabl
|
|||
{
|
||||
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
||||
{
|
||||
if(this->leafData[i].container.Intersects(collideable))
|
||||
if(!this->leafData[i].limbo && this->leafData[i].container.Intersects(collideable))
|
||||
{
|
||||
updateList.push_back(this->leafData[i].customBodyRef);
|
||||
}
|
||||
|
@ -121,7 +149,7 @@ void Octree::Visit(ICustomBody* customBodyRef, VisitorAction hitAction )
|
|||
|
||||
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
||||
{
|
||||
if(tempRef != i) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
|
||||
if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
|
||||
{
|
||||
hitAction(*this, tempRef, i);
|
||||
}
|
||||
|
@ -132,7 +160,7 @@ void Octree::Visit(const Oyster::Collision3D::ICollideable& collideable, void* a
|
|||
{
|
||||
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
||||
{
|
||||
if(collideable.Intersects(this->leafData[i].container))
|
||||
if(!this->leafData[i].limbo && collideable.Intersects(this->leafData[i].container))
|
||||
{
|
||||
hitAction( this->GetCustomBody(i), args );
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ namespace Oyster
|
|||
|
||||
::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef;
|
||||
|
||||
bool limbo;
|
||||
|
||||
unsigned int queueRef;
|
||||
};
|
||||
|
||||
|
@ -48,6 +50,10 @@ namespace Oyster
|
|||
|
||||
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);
|
||||
|
@ -66,6 +72,7 @@ namespace Oyster
|
|||
private:
|
||||
std::vector < Data > leafData;
|
||||
std::vector < Data* > updateQueue;
|
||||
std::vector < Data* > limbo;
|
||||
|
||||
std::map< const ICustomBody*, unsigned int > mapReferences;
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ namespace
|
|||
return;
|
||||
}
|
||||
|
||||
// calculate and store time interpolation value, for later rebound.
|
||||
proto->SetTimeOfContact( worldPointOfContact );
|
||||
|
||||
// bounce
|
||||
Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(),
|
||||
|
@ -79,9 +81,13 @@ namespace
|
|||
|
||||
Float4 bounce = Average( bounceD, bounceP );
|
||||
|
||||
Float4 friction = Formula::CollisionResponse::Friction( protoG_Magnitude, normal,
|
||||
Float4(protoState.GetLinearMomentum(), 0), protoState.GetFrictionCoeff_Static(), protoState.GetFrictionCoeff_Kinetic(), protoState.GetMass(),
|
||||
Float4(deuterState.GetLinearMomentum(), 0), deuterState.GetFrictionCoeff_Static(), deuterState.GetFrictionCoeff_Kinetic(), deuterState.GetMass());
|
||||
|
||||
Float kineticEnergyPBefore = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), protoState.GetLinearMomentum()/protoState.GetMass() );
|
||||
|
||||
protoState.ApplyImpulse( bounce.xyz, worldPointOfContact.xyz, normal.xyz );
|
||||
protoState.ApplyImpulse( bounce.xyz - friction.xyz, worldPointOfContact.xyz, normal.xyz );
|
||||
proto->SetState( protoState );
|
||||
|
||||
Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() );
|
||||
|
@ -233,17 +239,16 @@ void API_Impl::Update()
|
|||
|
||||
bool API_Impl::IsInLimbo( const ICustomBody* objRef )
|
||||
{
|
||||
//! @todo TODO: implement stub
|
||||
return true;
|
||||
return this->worldScene.IsInLimbo( objRef );
|
||||
}
|
||||
|
||||
void API_Impl::MoveToLimbo( const ICustomBody* objRef )
|
||||
{
|
||||
/** @todo TODO: Fix this function.*/
|
||||
this->worldScene.MoveToLimbo( objRef );
|
||||
}
|
||||
void API_Impl::ReleaseFromLimbo( const ICustomBody* objRef )
|
||||
{
|
||||
/** @todo TODO: Fix this function.*/
|
||||
this->worldScene.ReleaseFromLimbo( objRef );
|
||||
}
|
||||
|
||||
void API_Impl::AddObject( ::Utility::DynamicMemory::UniquePointer<ICustomBody> handle )
|
||||
|
|
|
@ -49,6 +49,12 @@ SimpleRigidBody::SimpleRigidBody()
|
|||
this->onCollision = Default::EventAction_BeforeCollisionResponse;
|
||||
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
|
||||
this->onMovement = Default::EventAction_Move;
|
||||
|
||||
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
|
||||
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
|
||||
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
|
||||
this->collisionRebound.timeOfContact = 1.0f;
|
||||
|
||||
this->scene = nullptr;
|
||||
this->customTag = nullptr;
|
||||
this->ignoreGravity = this->isForwarded = false;
|
||||
|
@ -56,9 +62,13 @@ SimpleRigidBody::SimpleRigidBody()
|
|||
|
||||
SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
||||
{
|
||||
//this->rigid.SetRotation( desc.rotation );
|
||||
this->rigid = RigidBody();
|
||||
this->rigid.SetRotation( desc.rotation );
|
||||
this->rigid.centerPos = desc.centerPosition;
|
||||
this->rigid.SetSize( desc.size );
|
||||
this->rigid.restitutionCoeff = desc.restitutionCoeff;
|
||||
this->rigid.frictionCoeff_Static = desc.frictionCoeff_Static;
|
||||
this->rigid.frictionCoeff_Kinetic = desc.frictionCoeff_Dynamic;
|
||||
this->rigid.SetMass_KeepMomentum( desc.mass );
|
||||
this->rigid.SetMomentOfInertia_KeepMomentum( desc.inertiaTensor );
|
||||
this->deltaPos = Float4::null;
|
||||
|
@ -66,6 +76,11 @@ SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
|||
|
||||
this->gravityNormal = Float3::null;
|
||||
|
||||
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
|
||||
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
|
||||
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
|
||||
this->collisionRebound.timeOfContact = 1.0f;
|
||||
|
||||
if( desc.subscription_onCollision )
|
||||
{
|
||||
this->onCollision = desc.subscription_onCollision;
|
||||
|
@ -198,6 +213,26 @@ bool SimpleRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointO
|
|||
return object.Intersects( Box(this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize()), worldPointOfContact );
|
||||
}
|
||||
|
||||
void SimpleRigidBody::SetTimeOfContact( Float4 &worldPointOfContact )
|
||||
{
|
||||
Point pointOfContact = Point( worldPointOfContact );
|
||||
Box start = Box();
|
||||
{
|
||||
start.rotation = RotationMatrix( this->collisionRebound.previousSpatial.axis );
|
||||
start.center = this->collisionRebound.previousSpatial.center;
|
||||
start.boundingOffset = this->collisionRebound.previousSpatial.reach;
|
||||
}
|
||||
Box end = Box();
|
||||
{
|
||||
end.rotation = RotationMatrix( this->rigid.axis );
|
||||
end.center = this->rigid.centerPos;
|
||||
end.boundingOffset = this->rigid.boundingReach;
|
||||
}
|
||||
Float timeOfContact = ::Oyster::Collision3D::Utility::TimeOfContact( start, end, pointOfContact );
|
||||
|
||||
this->collisionRebound.timeOfContact = Min( this->collisionRebound.timeOfContact, timeOfContact );
|
||||
}
|
||||
|
||||
Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||
{
|
||||
return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.GetMagnitude() );
|
||||
|
@ -290,21 +325,49 @@ void * SimpleRigidBody::GetCustomTag() const
|
|||
// return this->rigid.GetLinearVelocity();
|
||||
//}
|
||||
|
||||
|
||||
UpdateState SimpleRigidBody::Update( Float timeStepLength )
|
||||
{
|
||||
if( this->isForwarded )
|
||||
if( this->collisionRebound.timeOfContact < 1.0f )
|
||||
{ // Rebound if needed
|
||||
this->rigid.centerPos = Lerp( this->collisionRebound.previousSpatial.center, this->rigid.centerPos, this->collisionRebound.timeOfContact );
|
||||
this->rigid.SetRotation( Lerp(this->collisionRebound.previousSpatial.axis, this->rigid.axis, this->collisionRebound.timeOfContact) );
|
||||
this->rigid.boundingReach = Lerp( this->collisionRebound.previousSpatial.reach, this->rigid.boundingReach, this->collisionRebound.timeOfContact );
|
||||
this->collisionRebound.timeOfContact = 1.0f;
|
||||
}
|
||||
|
||||
// Maintain rotation resolution by keeping axis within [0, 2pi] (trigonometric methods gets faster too)
|
||||
Float4 temp;
|
||||
::std::modf( this->rigid.axis * (0.5f / pi), temp.xyz );
|
||||
this->rigid.axis -= ((2.0f * pi) * temp).xyz;
|
||||
|
||||
// Update rebound data
|
||||
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
|
||||
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
|
||||
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
|
||||
|
||||
// Check if this is close enough to be set resting
|
||||
temp = Float4( this->rigid.impulse_Linear, 0.0f ) + Float4( this->rigid.impulse_Angular, 0.0f );
|
||||
if( temp.Dot(temp) <= (Constant::epsilon * Constant::epsilon) )
|
||||
{
|
||||
this->rigid.Move( this->deltaPos.xyz, this->deltaAxis.xyz );
|
||||
this->deltaPos = Float4::null;
|
||||
this->deltaAxis = Float4::null;
|
||||
this->isForwarded = false;
|
||||
unsigned char resting = 0;
|
||||
if( this->rigid.momentum_Linear.Dot(this->rigid.momentum_Linear) <= (Constant::epsilon * Constant::epsilon) )
|
||||
{
|
||||
this->rigid.momentum_Linear = Float3::null;
|
||||
resting = 1;
|
||||
}
|
||||
if( this->rigid.momentum_Angular.Dot(this->rigid.momentum_Angular) <= (Constant::epsilon * Constant::epsilon) )
|
||||
{
|
||||
this->rigid.momentum_Angular = Float3::null;
|
||||
++resting;
|
||||
}
|
||||
if( resting == 2 )
|
||||
{
|
||||
this->rigid.impulse_Linear = this->rigid.impulse_Angular = Float3::null;
|
||||
return UpdateState_resting;
|
||||
}
|
||||
}
|
||||
|
||||
this->rigid.Update_LeapFrog( timeStepLength );
|
||||
|
||||
//! @todo TODO: compare previous and new state and return result
|
||||
//return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
|
||||
return UpdateState_altered;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ namespace Oyster { namespace Physics
|
|||
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
|
||||
void SetTimeOfContact( ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
|
||||
::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const;
|
||||
::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const;
|
||||
::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
|
||||
|
@ -65,9 +67,17 @@ namespace Oyster { namespace Physics
|
|||
::Oyster::Physics3D::RigidBody rigid;
|
||||
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
||||
::Oyster::Math::Float3 gravityNormal;
|
||||
|
||||
struct
|
||||
{
|
||||
struct { ::Oyster::Math::Float3 center, axis, reach; } previousSpatial;
|
||||
::Oyster::Math::Float timeOfContact;
|
||||
} collisionRebound;
|
||||
|
||||
EventAction_BeforeCollisionResponse onCollision;
|
||||
EventAction_AfterCollisionResponse onCollisionResponse;
|
||||
EventAction_Move onMovement;
|
||||
|
||||
Octree *scene;
|
||||
void *customTag;
|
||||
bool ignoreGravity, isForwarded;
|
||||
|
|
|
@ -11,11 +11,17 @@ using namespace ::Utility::Value;
|
|||
SphericalRigidBody::SphericalRigidBody()
|
||||
{
|
||||
this->rigid = RigidBody();
|
||||
this->rigid.SetMass_KeepMomentum( 10.0f );
|
||||
this->rigid.SetMass_KeepMomentum( 16.0f );
|
||||
this->gravityNormal = Float3::null;
|
||||
this->onCollision = Default::EventAction_BeforeCollisionResponse;
|
||||
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
|
||||
this->onMovement = Default::EventAction_Move;
|
||||
|
||||
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
|
||||
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
|
||||
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
|
||||
this->collisionRebound.timeOfContact = 1.0f;
|
||||
|
||||
this->scene = nullptr;
|
||||
this->customTag = nullptr;
|
||||
this->ignoreGravity = this->isForwarded = false;
|
||||
|
@ -24,9 +30,12 @@ SphericalRigidBody::SphericalRigidBody()
|
|||
SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc )
|
||||
{
|
||||
this->rigid = RigidBody();
|
||||
//this->rigid.SetRotation( desc.rotation );
|
||||
this->rigid.SetRotation( desc.rotation );
|
||||
this->rigid.centerPos = desc.centerPosition;
|
||||
this->rigid.boundingReach = Float4( desc.radius, desc.radius, desc.radius, 0.0f );
|
||||
this->rigid.restitutionCoeff = desc.restitutionCoeff;
|
||||
this->rigid.frictionCoeff_Static = desc.frictionCoeff_Static;
|
||||
this->rigid.frictionCoeff_Kinetic = desc.frictionCoeff_Dynamic;
|
||||
this->rigid.SetMass_KeepMomentum( desc.mass );
|
||||
this->rigid.SetMomentOfInertia_KeepMomentum( MomentOfInertia::Sphere(desc.mass, desc.radius) );
|
||||
this->deltaPos = Float4::null;
|
||||
|
@ -34,6 +43,11 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des
|
|||
|
||||
this->gravityNormal = Float3::null;
|
||||
|
||||
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
|
||||
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
|
||||
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
|
||||
this->collisionRebound.timeOfContact = 1.0f;
|
||||
|
||||
if( desc.subscription_onCollision )
|
||||
{
|
||||
this->onCollision = desc.subscription_onCollision;
|
||||
|
@ -64,6 +78,11 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des
|
|||
this->scene = nullptr;
|
||||
this->customTag = nullptr;
|
||||
this->ignoreGravity = desc.ignoreGravity;
|
||||
|
||||
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
|
||||
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
|
||||
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
|
||||
this->collisionRebound.timeOfContact = 1.0f;
|
||||
}
|
||||
|
||||
SphericalRigidBody::~SphericalRigidBody() {}
|
||||
|
@ -165,6 +184,17 @@ bool SphericalRigidBody::Intersects( const ICustomBody &object, Float4 &worldPoi
|
|||
return object.Intersects( Sphere(this->rigid.centerPos, this->rigid.boundingReach.x), worldPointOfContact );
|
||||
}
|
||||
|
||||
void SphericalRigidBody::SetTimeOfContact( Float4 &worldPointOfContact )
|
||||
{
|
||||
Point pointOfContact = Point( worldPointOfContact );
|
||||
Sphere start = Sphere( this->collisionRebound.previousSpatial.center, this->collisionRebound.previousSpatial.reach.x );
|
||||
Sphere end = Sphere( this->rigid.centerPos, this->rigid.boundingReach.x );
|
||||
|
||||
Float timeOfContact = ::Oyster::Collision3D::Utility::TimeOfContact( start, end, pointOfContact );
|
||||
|
||||
this->collisionRebound.timeOfContact = Min( this->collisionRebound.timeOfContact, timeOfContact );
|
||||
}
|
||||
|
||||
Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||
{
|
||||
return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.x );
|
||||
|
@ -219,18 +249,47 @@ void * SphericalRigidBody::GetCustomTag() const
|
|||
|
||||
UpdateState SphericalRigidBody::Update( Float timeStepLength )
|
||||
{
|
||||
if( this->isForwarded )
|
||||
if( this->collisionRebound.timeOfContact < 1.0f )
|
||||
{ // Rebound if needed
|
||||
this->rigid.centerPos = Lerp( this->collisionRebound.previousSpatial.center, this->rigid.centerPos, this->collisionRebound.timeOfContact );
|
||||
this->rigid.SetRotation( Lerp(this->collisionRebound.previousSpatial.axis, this->rigid.axis, this->collisionRebound.timeOfContact) );
|
||||
this->rigid.boundingReach = Lerp( this->collisionRebound.previousSpatial.reach, this->rigid.boundingReach, this->collisionRebound.timeOfContact );
|
||||
this->collisionRebound.timeOfContact = 1.0f;
|
||||
}
|
||||
|
||||
// Maintain rotation resolution by keeping axis within [0, 2pi] (trigonometric methods gets faster too)
|
||||
Float4 temp;
|
||||
::std::modf( this->rigid.axis * (0.5f / pi), temp.xyz );
|
||||
this->rigid.axis -= ((2.0f * pi) * temp).xyz;
|
||||
|
||||
// Update rebound data
|
||||
this->collisionRebound.previousSpatial.center = this->rigid.centerPos;
|
||||
this->collisionRebound.previousSpatial.axis = this->rigid.axis;
|
||||
this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach;
|
||||
|
||||
// Check if this is close enough to be set resting
|
||||
temp = Float4( this->rigid.impulse_Linear, 0.0f ) + Float4( this->rigid.impulse_Angular, 0.0f );
|
||||
if( temp.Dot(temp) <= (Constant::epsilon * Constant::epsilon) )
|
||||
{
|
||||
this->rigid.Move( this->deltaPos.xyz, this->deltaAxis.xyz );
|
||||
this->deltaPos = Float4::null;
|
||||
this->deltaAxis = Float4::null;
|
||||
this->isForwarded = false;
|
||||
unsigned char resting = 0;
|
||||
if( this->rigid.momentum_Linear.Dot(this->rigid.momentum_Linear) <= (Constant::epsilon * Constant::epsilon) )
|
||||
{
|
||||
this->rigid.momentum_Linear = Float3::null;
|
||||
resting = 1;
|
||||
}
|
||||
if( this->rigid.momentum_Angular.Dot(this->rigid.momentum_Angular) <= (Constant::epsilon * Constant::epsilon) )
|
||||
{
|
||||
this->rigid.momentum_Angular = Float3::null;
|
||||
++resting;
|
||||
}
|
||||
if( resting == 2 )
|
||||
{
|
||||
this->rigid.impulse_Linear = this->rigid.impulse_Angular = Float3::null;
|
||||
return UpdateState_resting;
|
||||
}
|
||||
}
|
||||
|
||||
this->rigid.Update_LeapFrog( timeStepLength );
|
||||
|
||||
// compare previous and new state and return result
|
||||
//return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
|
||||
return UpdateState_altered;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ namespace Oyster { namespace Physics
|
|||
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
|
||||
void SetTimeOfContact( ::Oyster::Math::Float4 &worldPointOfContact );
|
||||
|
||||
::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const;
|
||||
::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const;
|
||||
::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const;
|
||||
|
@ -66,6 +68,13 @@ namespace Oyster { namespace Physics
|
|||
::Oyster::Physics3D::RigidBody rigid;
|
||||
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
||||
::Oyster::Math::Float3 gravityNormal;
|
||||
|
||||
struct
|
||||
{
|
||||
struct { ::Oyster::Math::Float3 center, axis, reach; } previousSpatial;
|
||||
::Oyster::Math::Float timeOfContact;
|
||||
} collisionRebound;
|
||||
|
||||
EventAction_BeforeCollisionResponse onCollision;
|
||||
EventAction_AfterCollisionResponse onCollisionResponse;
|
||||
EventAction_Move onMovement;
|
||||
|
|
|
@ -322,6 +322,11 @@ namespace Oyster
|
|||
********************************************************/
|
||||
virtual bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
|
||||
|
||||
/********************************************************
|
||||
* Sets how far back it needs to be interpolated to not be overlapping worldPointOfContact.
|
||||
********************************************************/
|
||||
virtual void SetTimeOfContact( ::Oyster::Math::Float4 &worldPointOfContact ) = 0;
|
||||
|
||||
/********************************************************
|
||||
* Required by Engine's Collision Search.
|
||||
* @param targetMem: Provided memory that written into and then returned.
|
||||
|
|
|
@ -48,26 +48,32 @@ namespace Oyster { namespace Physics { namespace Formula
|
|||
// Relative momentum after normal impulse
|
||||
::Oyster::Math::Float4 relativeMomentum = momB - momA;
|
||||
|
||||
::Oyster::Math::Float4 tanFriction = relativeMomentum - relativeMomentum.Dot( iN )*iN;
|
||||
::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 );
|
||||
magnitudeFriction = magnitudeFriction * mA * mB / ( mA + mB );
|
||||
|
||||
::Oyster::Math::Float mu = 0.5f*( sFA + sFB );
|
||||
::Oyster::Math::Float mu = 0.5f * ( sFA + sFB );
|
||||
|
||||
::Oyster::Math::Float4 frictionImpulse;
|
||||
if( abs(magnitudeFriction) < i*mu )
|
||||
if( abs(magnitudeFriction) < i * mu )
|
||||
{
|
||||
frictionImpulse = magnitudeFriction*tanFriction;
|
||||
frictionImpulse = magnitudeFriction * tanFriction;
|
||||
}
|
||||
else
|
||||
{
|
||||
::Oyster::Math::Float dynamicFriction = 0.5f*( dFA + dFB );
|
||||
frictionImpulse = -i*tanFriction*dynamicFriction;
|
||||
::Oyster::Math::Float dynamicFriction = 0.5f * ( dFA + dFB );
|
||||
frictionImpulse = ( -i * dynamicFriction ) * tanFriction;
|
||||
}
|
||||
|
||||
return ( 1 / mA )*frictionImpulse;
|
||||
return ( 1 / mA ) * frictionImpulse;
|
||||
}
|
||||
else
|
||||
return ::Oyster::Math::Float4::null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Oyster
|
|||
{
|
||||
inline SimpleBodyDescription::SimpleBodyDescription()
|
||||
{
|
||||
this->rotation = ::Oyster::Math::Float4x4::identity;
|
||||
this->rotation = ::Oyster::Math::Float3::null;
|
||||
this->centerPosition = ::Oyster::Math::Float3::null;
|
||||
this->size = ::Oyster::Math::Float3( 1.0f );
|
||||
this->mass = 6.0f;
|
||||
|
@ -28,7 +28,7 @@ namespace Oyster
|
|||
|
||||
inline SphericalBodyDescription::SphericalBodyDescription()
|
||||
{
|
||||
this->rotation = ::Oyster::Math::Float4x4::identity;
|
||||
this->rotation = ::Oyster::Math::Float3::null;
|
||||
this->centerPosition = ::Oyster::Math::Float3::null;
|
||||
this->radius = 0.5f;
|
||||
this->mass = 10.0f;
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace Oyster { namespace Physics
|
|||
{
|
||||
struct SimpleBodyDescription
|
||||
{
|
||||
::Oyster::Math::Float4x4 rotation;
|
||||
::Oyster::Math::Float3 rotation;
|
||||
::Oyster::Math::Float3 centerPosition;
|
||||
::Oyster::Math::Float3 size;
|
||||
::Oyster::Math::Float mass;
|
||||
|
@ -29,7 +29,7 @@ namespace Oyster { namespace Physics
|
|||
|
||||
struct SphericalBodyDescription
|
||||
{
|
||||
::Oyster::Math::Float4x4 rotation;
|
||||
::Oyster::Math::Float3 rotation;
|
||||
::Oyster::Math::Float3 centerPosition;
|
||||
::Oyster::Math::Float radius;
|
||||
::Oyster::Math::Float mass;
|
||||
|
|
|
@ -315,6 +315,14 @@ namespace Utility
|
|||
{
|
||||
using ::std::numeric_limits;
|
||||
|
||||
template<typename ValueType>
|
||||
inline bool Within( const ValueType &value, const ValueType &lower, const ValueType &upper )
|
||||
{
|
||||
if( value < lower ) return false;
|
||||
if( value > upper ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
inline ValueType Abs( const ValueType &value )
|
||||
{ return value < 0 ? value * -1 : value; }
|
||||
|
|
|
@ -84,8 +84,8 @@ namespace Oyster
|
|||
*/
|
||||
std::string GetLanAddress();
|
||||
|
||||
/**
|
||||
*
|
||||
/** Returns the port the server is listening on.
|
||||
* @return Returns the port the server has been initiated with.
|
||||
*/
|
||||
int NetworkServer::GetPort();
|
||||
|
||||
|
|
|
@ -11,27 +11,6 @@
|
|||
#include "Quaternion.h"
|
||||
#include <math.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Vector2<ScalarType> asin( const ::LinearAlgebra::Vector2<ScalarType> &vec )
|
||||
{
|
||||
return ::LinearAlgebra::Vector2<ScalarType>( asin(vec.x), asin(vec.y) );
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Vector3<ScalarType> asin( const ::LinearAlgebra::Vector3<ScalarType> &vec )
|
||||
{
|
||||
return ::LinearAlgebra::Vector3<ScalarType>( asin(vec.x), asin(vec.y), asin(vec.z) );
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Vector4<ScalarType> asin( const ::LinearAlgebra::Vector4<ScalarType> &vec )
|
||||
{
|
||||
return ::LinearAlgebra::Vector4<ScalarType>( asin(vec.x), asin(vec.y), asin(vec.z), asin(vec.w) );
|
||||
}
|
||||
}
|
||||
|
||||
// x2
|
||||
|
||||
template<typename ScalarType>
|
||||
|
@ -112,6 +91,69 @@ inline ::LinearAlgebra::Vector4<ScalarType> operator * ( const ::LinearAlgebra::
|
|||
(vector.x * matrix.m14) + (vector.y * matrix.m24) + (vector.z * matrix.m34) + (vector.w * matrix.m44) );
|
||||
}
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Vector2<ScalarType> asin( const ::LinearAlgebra::Vector2<ScalarType> &vec )
|
||||
{
|
||||
return ::LinearAlgebra::Vector2<ScalarType>( asin(vec.x), asin(vec.y) );
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Vector3<ScalarType> asin( const ::LinearAlgebra::Vector3<ScalarType> &vec )
|
||||
{
|
||||
return ::LinearAlgebra::Vector3<ScalarType>( asin(vec.x), asin(vec.y), asin(vec.z) );
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Vector4<ScalarType> asin( const ::LinearAlgebra::Vector4<ScalarType> &vec )
|
||||
{
|
||||
return ::LinearAlgebra::Vector4<ScalarType>( asin(vec.x), asin(vec.y), asin(vec.z), asin(vec.w) );
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* @param numerator of the vector vec
|
||||
* @return the denomiator of the vector vec.
|
||||
*******************************************************************/
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Vector2<ScalarType> modf( const ::LinearAlgebra::Vector2<ScalarType> &vec, ::LinearAlgebra::Vector2<ScalarType> &numerator )
|
||||
{
|
||||
::LinearAlgebra::Vector2<ScalarType> denominator;
|
||||
denominator.x = (ScalarType)modf( vec.x, &numerator.x );
|
||||
denominator.y = (ScalarType)modf( vec.y, &numerator.y );
|
||||
return denominator;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* @param numerator of the vector vec
|
||||
* @return the denomiator of the vector vec.
|
||||
*******************************************************************/
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Vector3<ScalarType> modf( const ::LinearAlgebra::Vector3<ScalarType> &vec, ::LinearAlgebra::Vector3<ScalarType> &numerator )
|
||||
{
|
||||
::LinearAlgebra::Vector3<ScalarType> denominator;
|
||||
denominator.x = (ScalarType)modf( vec.x, &numerator.x );
|
||||
denominator.y = (ScalarType)modf( vec.y, &numerator.y );
|
||||
denominator.z = (ScalarType)modf( vec.z, &numerator.z );
|
||||
return denominator;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
* @param numerator of the vector vec
|
||||
* @return the denomiator of the vector vec.
|
||||
*******************************************************************/
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Vector4<ScalarType> modf( const ::LinearAlgebra::Vector4<ScalarType> &vec, ::LinearAlgebra::Vector4<ScalarType> &numerator )
|
||||
{
|
||||
::LinearAlgebra::Vector4<ScalarType> denominator;
|
||||
denominator.x = (ScalarType)modf( vec.x, &numerator.x );
|
||||
denominator.y = (ScalarType)modf( vec.y, &numerator.y );
|
||||
denominator.z = (ScalarType)modf( vec.z, &numerator.z );
|
||||
denominator.w = (ScalarType)modf( vec.w, &numerator.w );
|
||||
return denominator;
|
||||
}
|
||||
}
|
||||
|
||||
namespace LinearAlgebra
|
||||
{
|
||||
// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||
|
@ -752,7 +794,7 @@ namespace LinearAlgebra3D
|
|||
{
|
||||
::LinearAlgebra::Vector4<ScalarType> worldStartNormal( WorldAxisOf(Rotation(startAngularAxis.xyz), localStartNormal.xyz), (ScalarType)0 );
|
||||
targetMem = ::LinearAlgebra::Vector4<ScalarType>( worldStartNormal.xyz.Cross(worldEndNormal.xyz), (ScalarType)0);
|
||||
targetMem *= (ScalarType)::std::acos( worldStartNormal.Dot(worldEndNormal) );
|
||||
targetMem *= (ScalarType)::std::acos( ::Utility::Value::Clamp(worldStartNormal.Dot(worldEndNormal), (ScalarType)0, (ScalarType)1) );
|
||||
return targetMem += startAngularAxis;
|
||||
}
|
||||
|
||||
|
@ -795,11 +837,42 @@ namespace LinearAlgebra3D
|
|||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
::LinearAlgebra::Matrix4x4<ScalarType> & InterpolateOrientation_UsingNonRigidNlerp( const ::LinearAlgebra::Matrix4x4<ScalarType> &start, const ::LinearAlgebra::Matrix4x4<ScalarType> &end, ScalarType t, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem )
|
||||
inline ::LinearAlgebra::Matrix4x4<ScalarType> & InterpolateRotation_UsingNonRigidNlerp( const ::LinearAlgebra::Matrix4x4<ScalarType> &start, const ::LinearAlgebra::Matrix4x4<ScalarType> &end, ScalarType t, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem )
|
||||
{
|
||||
targetMem.v[0] = ::LinearAlgebra::Nlerp( start.v[0], end.v[0], t );
|
||||
targetMem.v[1] = ::LinearAlgebra::Nlerp( start.v[1], end.v[1], t );
|
||||
targetMem.v[2] = ::LinearAlgebra::Nlerp( start.v[2], end.v[2], t );
|
||||
return targetMem;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Matrix4x4<ScalarType> & InterpolateOrientation_UsingNonRigidNlerp( const ::LinearAlgebra::Matrix4x4<ScalarType> &start, const ::LinearAlgebra::Matrix4x4<ScalarType> &end, ScalarType t, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem )
|
||||
{
|
||||
InterpolateRotation_UsingNonRigidNlerp( start, end, t, targetMem );
|
||||
targetMem.v[3] = ::LinearAlgebra::Lerp( start.v[3], end.v[3], t );
|
||||
return targetMem;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
::LinearAlgebra::Matrix4x4<ScalarType> & InterpolateRotation_UsingRigidNlerp( const ::LinearAlgebra::Matrix4x4<ScalarType> &start, const ::LinearAlgebra::Matrix4x4<ScalarType> &end, ScalarType t, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem )
|
||||
{
|
||||
// Nlerp y axis
|
||||
targetMem.v[1] = ::LinearAlgebra::Nlerp( start.v[1], end.v[1], t );
|
||||
|
||||
// Lerp z axis and orthogonolize against y axis
|
||||
targetMem.v[2] = ::LinearAlgebra::Lerp( start.v[2], end.v[2], t );
|
||||
targetMem.v[2] -= targetMem.v[2].Dot(targetMem.v[1]) * targetMem.v[1];
|
||||
targetMem.v[2].Normalize();
|
||||
|
||||
// Cross product x axis from y and z
|
||||
targetMem.v[0].xyz = targetMem.v[1].xyz.Cross(targetMem.v[2].xyz);
|
||||
return targetMem;
|
||||
}
|
||||
|
||||
template<typename ScalarType>
|
||||
inline ::LinearAlgebra::Matrix4x4<ScalarType> & InterpolateOrientation_UsingRigidNlerp( const ::LinearAlgebra::Matrix4x4<ScalarType> &start, const ::LinearAlgebra::Matrix4x4<ScalarType> &end, ScalarType t, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem )
|
||||
{
|
||||
InterpolateRotation_UsingRigidNlerp( start, end, t, targetMem );
|
||||
targetMem.v[3] = ::LinearAlgebra::Lerp( start.v[3], end.v[3], t );
|
||||
return targetMem;
|
||||
}
|
||||
|
|
|
@ -322,7 +322,10 @@ namespace Oyster { namespace Math3D //! Oyster's native math library specialized
|
|||
|
||||
using ::LinearAlgebra3D::SnapAxisYToNormal_UsingNlerp;
|
||||
using ::LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp;
|
||||
using ::LinearAlgebra3D::InterpolateRotation_UsingNonRigidNlerp;
|
||||
using ::LinearAlgebra3D::InterpolateRotation_UsingRigidNlerp;
|
||||
using ::LinearAlgebra3D::InterpolateOrientation_UsingNonRigidNlerp;
|
||||
using ::LinearAlgebra3D::InterpolateOrientation_UsingRigidNlerp;
|
||||
using ::LinearAlgebra3D::InterpolateOrientation_UsingSlerp;
|
||||
using ::LinearAlgebra3D::SnapAngularAxis;
|
||||
} }
|
||||
|
|
|
@ -93,3 +93,26 @@ bool Box::Contains( const ICollideable &target ) const
|
|||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
Float Box::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const
|
||||
{
|
||||
if( deuterStart.type != deuterEnd.type )
|
||||
return -1.0f;
|
||||
|
||||
switch( deuterStart.type )
|
||||
{ // TODO: more to implement
|
||||
case Type_universe: return 0.0f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Oyster { namespace Math
|
||||
{
|
||||
Box & Nlerp( const Box &start, const Box &end, Float t, Box &targetMem )
|
||||
{
|
||||
InterpolateRotation_UsingRigidNlerp( start.rotation, end.rotation, t, targetMem.rotation );
|
||||
targetMem.center = Lerp( start.center, end.center, t );
|
||||
targetMem.boundingOffset = Lerp( start.boundingOffset, end.boundingOffset, t );
|
||||
return targetMem;
|
||||
}
|
||||
} }
|
|
@ -9,8 +9,10 @@
|
|||
#include "OysterMath.h"
|
||||
#include "ICollideable.h"
|
||||
|
||||
namespace Oyster { namespace Collision3D
|
||||
namespace Oyster
|
||||
{
|
||||
namespace Collision3D
|
||||
{
|
||||
class Box : public ICollideable
|
||||
{
|
||||
public:
|
||||
|
@ -37,7 +39,18 @@ namespace Oyster { namespace Collision3D
|
|||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
|
||||
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||
};
|
||||
} }
|
||||
}
|
||||
|
||||
namespace Math
|
||||
{
|
||||
/********************************************************************
|
||||
* Normalized Linear Interpolation
|
||||
********************************************************************/
|
||||
::Oyster::Collision3D::Box & Nlerp( const ::Oyster::Collision3D::Box &start, const ::Oyster::Collision3D::Box &end, ::Oyster::Math::Float t, ::Oyster::Collision3D::Box &targetMem = ::Oyster::Collision3D::Box() );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -77,3 +77,15 @@ bool BoxAxisAligned::Contains( const ICollideable &target ) const
|
|||
//}
|
||||
return false;
|
||||
}
|
||||
|
||||
Float BoxAxisAligned::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const
|
||||
{
|
||||
if( deuterStart.type != deuterEnd.type )
|
||||
return -1.0f;
|
||||
|
||||
switch( deuterStart.type )
|
||||
{ // TODO: more to implement
|
||||
case Type_universe: return 0.0f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
|
@ -31,6 +31,8 @@ namespace Oyster { namespace Collision3D
|
|||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
|
||||
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||
};
|
||||
} }
|
||||
|
||||
|
|
|
@ -15,37 +15,37 @@ namespace PrivateStatic
|
|||
Float4x4 m = vp.GetTranspose();
|
||||
|
||||
// left
|
||||
lp.normal = m.v[3].xyz + m.v[0].xyz;
|
||||
lp.normal = Float4(m.v[3].xyz + m.v[0].xyz,0);
|
||||
lp.phasing = lp.normal.GetMagnitude();
|
||||
lp.normal /= lp.phasing;
|
||||
lp.phasing = (m.v[3].w + m.v[0].w) / lp.phasing;
|
||||
|
||||
// right
|
||||
rp.normal = m.v[3].xyz - m.v[0].xyz;
|
||||
rp.normal = Float4(m.v[3].xyz - m.v[0].xyz,0);
|
||||
rp.phasing = rp.normal.GetMagnitude();
|
||||
rp.normal /= rp.phasing;
|
||||
rp.phasing = (m.v[3].w - m.v[0].w) / rp.phasing;
|
||||
|
||||
// bottom
|
||||
bp.normal = m.v[3].xyz + m.v[1].xyz;
|
||||
bp.normal = Float4(m.v[3].xyz + m.v[1].xyz,0);
|
||||
bp.phasing = bp.normal.GetMagnitude();
|
||||
bp.normal /= bp.phasing;
|
||||
bp.phasing = (m.v[3].w + m.v[1].w) / bp.phasing;
|
||||
|
||||
// top
|
||||
tp.normal = m.v[3].xyz - m.v[1].xyz;
|
||||
tp.normal = Float4(m.v[3].xyz - m.v[1].xyz,0);
|
||||
tp.phasing = tp.normal.GetMagnitude();
|
||||
tp.normal /= tp.phasing;
|
||||
tp.phasing = (m.v[3].w - m.v[1].w) / tp.phasing;
|
||||
|
||||
// near leftHanded DirectX
|
||||
np.normal = m.v[2].xyz;
|
||||
np.normal = Float4(m.v[2].xyz,0);
|
||||
np.phasing = np.normal.GetMagnitude();
|
||||
np.normal /= np.phasing;
|
||||
np.phasing = m.v[2].w / np.phasing;
|
||||
|
||||
// far lefthanded
|
||||
fp.normal = m.v[3].xyz - m.v[2].xyz;
|
||||
fp.normal = Float4(m.v[3].xyz - m.v[2].xyz,0);
|
||||
fp.phasing = fp.normal.GetMagnitude();
|
||||
fp.normal /= fp.phasing;
|
||||
fp.phasing = (m.v[3].w - m.v[2].w) / fp.phasing;
|
||||
|
@ -243,6 +243,18 @@ bool Frustrum::Contains( const ICollideable &target ) const
|
|||
}
|
||||
}
|
||||
|
||||
Float Frustrum::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const
|
||||
{
|
||||
if( deuterStart.type != deuterEnd.type )
|
||||
return -1.0f;
|
||||
|
||||
switch( deuterStart.type )
|
||||
{ // TODO: more to implement
|
||||
case Type_universe: return 0.0f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
::Oyster::Math::Float3 Frustrum::ExtractForwad()
|
||||
{
|
||||
return this->bottomPlane.normal.xyz;
|
||||
|
|
|
@ -42,6 +42,8 @@ namespace Oyster { namespace Collision3D
|
|||
bool Intersects( const ICollideable &target, Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
|
||||
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||
|
||||
::Oyster::Math::Float3 ExtractForwad();
|
||||
};
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@ namespace Oyster { namespace Collision3D //! Contains a collection of 3D shapes
|
|||
virtual bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
|
||||
virtual bool Intersects( const ICollideable &target ) const = 0;
|
||||
virtual bool Contains( const ICollideable &target ) const = 0;
|
||||
|
||||
virtual ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const = 0;
|
||||
};
|
||||
} }
|
||||
#endif
|
|
@ -76,3 +76,15 @@ bool Line::Intersects( const ICollideable &target, Float4 &worldPointOfContact )
|
|||
|
||||
bool Line::Contains( const ICollideable &target ) const
|
||||
{ /* TODO: : */ return false; }
|
||||
|
||||
Float Line::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const
|
||||
{
|
||||
if( deuterStart.type != deuterEnd.type )
|
||||
return -1.0f;
|
||||
|
||||
switch( deuterStart.type )
|
||||
{ // TODO: more to implement
|
||||
case Type_universe: return 0.0f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
|
@ -32,6 +32,8 @@ namespace Oyster { namespace Collision3D
|
|||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
|
||||
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||
};
|
||||
} }
|
||||
|
||||
|
|
|
@ -1061,4 +1061,47 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
return container.normal == -plane.normal;
|
||||
return false;
|
||||
}
|
||||
|
||||
Float TimeOfContact( const Sphere &protoStart, const Sphere &protoEnd, const Point &deuter )
|
||||
{ // Bisection with 5 levels of detail
|
||||
Float t = 0.5f,
|
||||
d = 0.25f;
|
||||
Sphere s;
|
||||
for( int i = 0; i < 5; ++i )
|
||||
{
|
||||
Nlerp( protoStart, protoEnd, t, s );
|
||||
if( Intersect(s, deuter) )
|
||||
{
|
||||
t -= d;
|
||||
}
|
||||
else
|
||||
{
|
||||
t += d;
|
||||
}
|
||||
d *= 0.5f;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
Float TimeOfContact( const Box &protoStart, const Box &protoEnd, const Point &deuter )
|
||||
{ // Bisection with 5 levels of detail
|
||||
Float t = 0.5f,
|
||||
d = 0.25f;
|
||||
Box b;
|
||||
for( int i = 0; i < 5; ++i )
|
||||
{
|
||||
Nlerp( protoStart, protoEnd, t, b );
|
||||
if( Intersect(b, deuter) )
|
||||
{
|
||||
t -= d;
|
||||
}
|
||||
else
|
||||
{
|
||||
t += d;
|
||||
}
|
||||
d *= 0.5f;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
} } }
|
|
@ -121,6 +121,9 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
|||
// bool Contains( const Frustrum &container, const BoxAxisAligned &box );
|
||||
// bool Contains( const Frustrum &container, const Box &box );
|
||||
// bool Contains( const Frustrum &container, const Frustrum &frustrum );
|
||||
|
||||
::Oyster::Math::Float TimeOfContact( const Sphere &protoStart, const Sphere &protoEnd, const Point &deuter );
|
||||
::Oyster::Math::Float TimeOfContact( const Box &protoStart, const Box &protoEnd, const Point &deuter );
|
||||
} } }
|
||||
|
||||
#endif
|
|
@ -27,9 +27,6 @@
|
|||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Universe.h">
|
||||
<Filter>Header Files\Collision</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Box.h">
|
||||
<Filter>Header Files\Collision</Filter>
|
||||
</ClInclude>
|
||||
|
@ -81,6 +78,9 @@
|
|||
<ClInclude Include="Inertia.h">
|
||||
<Filter>Header Files\Physics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Universe.h">
|
||||
<Filter>Header Files\Collision</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Box.cpp">
|
||||
|
|
|
@ -84,3 +84,15 @@ bool Plane::Contains( const ICollideable &target ) const
|
|||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
Float Plane::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const
|
||||
{
|
||||
if( deuterStart.type != deuterEnd.type )
|
||||
return -1.0f;
|
||||
|
||||
switch( deuterStart.type )
|
||||
{ // TODO: more to implement
|
||||
case Type_universe: return 0.0f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
|
@ -31,6 +31,8 @@ namespace Oyster { namespace Collision3D
|
|||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
|
||||
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||
};
|
||||
} }
|
||||
|
||||
|
|
|
@ -82,3 +82,17 @@ bool Point::Contains( const ICollideable &target ) const
|
|||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
Float Point::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const
|
||||
{
|
||||
if( deuterStart.type != deuterEnd.type )
|
||||
return -1.0f;
|
||||
|
||||
switch( deuterStart.type )
|
||||
{ // TODO: more to implement
|
||||
case Type_sphere: return Utility::TimeOfContact( (const Sphere&)deuterStart, (const Sphere&)deuterEnd, *this );
|
||||
case Type_box: return Utility::TimeOfContact( (const Box&)deuterStart, (const Box&)deuterEnd, *this );
|
||||
case Type_universe: return 0.0f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
|
@ -31,6 +31,8 @@ namespace Oyster { namespace Collision3D
|
|||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
|
||||
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||
};
|
||||
} }
|
||||
|
||||
|
|
|
@ -93,3 +93,15 @@ bool Ray::Contains( const ICollideable &target ) const
|
|||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
Float Ray::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const
|
||||
{
|
||||
if( deuterStart.type != deuterEnd.type )
|
||||
return -1.0f;
|
||||
|
||||
switch( deuterStart.type )
|
||||
{ // TODO: more to implement
|
||||
case Type_universe: return 0.0f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
|
@ -39,6 +39,8 @@ namespace Oyster { namespace Collision3D
|
|||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
|
||||
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||
};
|
||||
} }
|
||||
|
||||
|
|
|
@ -49,13 +49,13 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength )
|
|||
{ // by Dan Andersson: Euler leap frog update when Runga Kutta is not needed
|
||||
|
||||
// updating the linear
|
||||
//Decrease momentum with 1% as "fall-off"
|
||||
//! HACK: @todo Add real solution with fluid drag
|
||||
this->momentum_Linear = this->momentum_Linear*0.9999f;
|
||||
this->momentum_Angular = this->momentum_Angular*0.9999f;
|
||||
|
||||
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
|
||||
Float3 deltaPos = ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear );
|
||||
if( deltaPos.GetLength() < 0.001f )
|
||||
{
|
||||
deltaPos = Float3::null;
|
||||
}
|
||||
this->centerPos += deltaPos;
|
||||
this->centerPos += ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear );
|
||||
|
||||
// updating the angular
|
||||
// dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H
|
||||
|
@ -181,6 +181,12 @@ void RigidBody::SetMass_KeepMomentum( const Float &m )
|
|||
}
|
||||
}
|
||||
|
||||
void RigidBody::SetRotation( const Float3 &axis )
|
||||
{ // by Dan Andersson
|
||||
this->axis = axis;
|
||||
this->rotation = Rotation( this->axis );
|
||||
}
|
||||
|
||||
void RigidBody::SetMomentum_Linear( const Float3 &worldG, const Float3 &atWorldPos )
|
||||
{ // by Dan Andersson
|
||||
Float3 worldOffset = atWorldPos - this->centerPos;
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace Oyster { namespace Physics3D
|
|||
void SetMass_KeepMomentum( const ::Oyster::Math::Float &m );
|
||||
|
||||
//void SetOrientation( const ::Oyster::Math::Float4x4 &o );
|
||||
//void SetRotation( const ::Oyster::Math::Float4x4 &r );
|
||||
void SetRotation( const ::Oyster::Math::Float3 &axis );
|
||||
void SetSize( const ::Oyster::Math::Float3 &widthHeight );
|
||||
|
||||
void SetMomentum_Linear( const ::Oyster::Math::Float3 &worldG, const ::Oyster::Math::Float3 &atWorldPos );
|
||||
|
|
|
@ -87,3 +87,29 @@ bool Sphere::Contains( const ICollideable &target ) const
|
|||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
Float Sphere::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const
|
||||
{
|
||||
if( deuterStart.type != deuterEnd.type )
|
||||
return -1.0f;
|
||||
|
||||
switch( deuterStart.type )
|
||||
{
|
||||
//case Type_point: // not implemented
|
||||
//case Type_sphere: // not implemented
|
||||
//case Type_box: // not implemented
|
||||
case Type_universe: return 0.0f;
|
||||
default: return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Oyster { namespace Math
|
||||
{
|
||||
Sphere & Nlerp( const Sphere &start, const Sphere &end, Float t, Sphere &targetMem )
|
||||
{
|
||||
Float4 i = Lerp( Float4(start.center.xyz, start.radius), Float4(end.center.xyz, end.radius), t );
|
||||
targetMem.center.xyz = i.xyz;
|
||||
targetMem.radius = i.w;
|
||||
return targetMem;
|
||||
}
|
||||
} }
|
|
@ -9,8 +9,10 @@
|
|||
#include "OysterMath.h"
|
||||
#include "ICollideable.h"
|
||||
|
||||
namespace Oyster { namespace Collision3D
|
||||
namespace Oyster
|
||||
{
|
||||
namespace Collision3D
|
||||
{
|
||||
class Sphere : public ICollideable
|
||||
{
|
||||
public:
|
||||
|
@ -31,7 +33,18 @@ namespace Oyster { namespace Collision3D
|
|||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
|
||||
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||
};
|
||||
} }
|
||||
}
|
||||
|
||||
namespace Math
|
||||
{
|
||||
/********************************************************************
|
||||
* Normalized Linear Interpolation
|
||||
********************************************************************/
|
||||
::Oyster::Collision3D::Sphere & Nlerp( const ::Oyster::Collision3D::Sphere &start, const ::Oyster::Collision3D::Sphere &end, ::Oyster::Math::Float t, ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -79,3 +79,8 @@ bool Universe::Contains( const ICollideable &target ) const
|
|||
{ // universe contains everything
|
||||
return true;
|
||||
}
|
||||
|
||||
Float Universe::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
|
@ -23,6 +23,8 @@ namespace Oyster { namespace Collision3D
|
|||
bool Intersects( const ICollideable &target ) const;
|
||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||
bool Contains( const ICollideable &target ) const;
|
||||
|
||||
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||
};
|
||||
} }
|
||||
|
||||
|
|
Loading…
Reference in New Issue