Merge remote-tracking branch 'origin/GameLogic' into Graphics
Conflicts: Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl
This commit is contained in:
commit
7167d042ac
BIN
Bin/Level.txt
BIN
Bin/Level.txt
Binary file not shown.
BIN
Bin/map.txt
BIN
Bin/map.txt
Binary file not shown.
Binary file not shown.
|
@ -204,6 +204,7 @@
|
||||||
<ClCompile Include="DLLMain.cpp" />
|
<ClCompile Include="DLLMain.cpp" />
|
||||||
<ClCompile Include="GameClientState\GameClientState.cpp" />
|
<ClCompile Include="GameClientState\GameClientState.cpp" />
|
||||||
<ClCompile Include="GameClientState\GameState.cpp" />
|
<ClCompile Include="GameClientState\GameState.cpp" />
|
||||||
|
<ClCompile Include="GameClientState\LanMenuState.cpp" />
|
||||||
<ClCompile Include="GameClientState\LobbyState.cpp" />
|
<ClCompile Include="GameClientState\LobbyState.cpp" />
|
||||||
<ClCompile Include="GameClientState\C_Object.cpp" />
|
<ClCompile Include="GameClientState\C_Object.cpp" />
|
||||||
<ClCompile Include="GameClientState\LoginState.cpp" />
|
<ClCompile Include="GameClientState\LoginState.cpp" />
|
||||||
|
@ -217,6 +218,7 @@
|
||||||
<ClInclude Include="GameClientState\C_obj\C_UIobject.h" />
|
<ClInclude Include="GameClientState\C_obj\C_UIobject.h" />
|
||||||
<ClInclude Include="GameClientState\GameClientState.h" />
|
<ClInclude Include="GameClientState\GameClientState.h" />
|
||||||
<ClInclude Include="GameClientState\GameState.h" />
|
<ClInclude Include="GameClientState\GameState.h" />
|
||||||
|
<ClInclude Include="GameClientState\LanMenuState.h" />
|
||||||
<ClInclude Include="GameClientState\LoginState.h" />
|
<ClInclude Include="GameClientState\LoginState.h" />
|
||||||
<ClInclude Include="Include\DanBiasGame.h" />
|
<ClInclude Include="Include\DanBiasGame.h" />
|
||||||
<ClInclude Include="GameClientState\LobbyState.h" />
|
<ClInclude Include="GameClientState\LobbyState.h" />
|
||||||
|
|
|
@ -6,8 +6,10 @@
|
||||||
#include "GameClientState\GameState.h"
|
#include "GameClientState\GameState.h"
|
||||||
#include "GameClientState\LobbyState.h"
|
#include "GameClientState\LobbyState.h"
|
||||||
#include "GameClientState\LoginState.h"
|
#include "GameClientState\LoginState.h"
|
||||||
|
#include "GameClientState\LanMenuState.h"
|
||||||
#include <Protocols.h>
|
#include <Protocols.h>
|
||||||
#include "NetworkClient.h"
|
#include "NetworkClient.h"
|
||||||
|
#include <GameServerAPI.h>
|
||||||
|
|
||||||
#include "../WindowManager/WindowShell.h"
|
#include "../WindowManager/WindowShell.h"
|
||||||
#include "L_inputClass.h"
|
#include "L_inputClass.h"
|
||||||
|
@ -36,8 +38,9 @@ namespace DanBias
|
||||||
public:
|
public:
|
||||||
WindowShell* window;
|
WindowShell* window;
|
||||||
InputClass* inputObj;
|
InputClass* inputObj;
|
||||||
Utility::WinTimer* timer;
|
Utility::WinTimer timer;
|
||||||
GameRecieverObject* recieverObj;
|
GameRecieverObject* recieverObj;
|
||||||
|
bool serverOwner;
|
||||||
|
|
||||||
} data;
|
} data;
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
@ -63,20 +66,14 @@ namespace DanBias
|
||||||
return DanBiasClientReturn_Error;
|
return DanBiasClientReturn_Error;
|
||||||
|
|
||||||
m_data->recieverObj = new GameRecieverObject;
|
m_data->recieverObj = new GameRecieverObject;
|
||||||
/*m_data->recieverObj->Connect(desc.port, desc.IP);
|
m_data->serverOwner = false;
|
||||||
|
|
||||||
if (!m_data->recieverObj->IsConnected())
|
|
||||||
{
|
|
||||||
// failed to connect
|
|
||||||
return DanBiasClientReturn_Error;
|
|
||||||
}*/
|
|
||||||
// Start in lobby state
|
// Start in lobby state
|
||||||
m_data->recieverObj->gameClientState = new Client::LoginState();
|
m_data->recieverObj->gameClientState = new Client::LoginState();
|
||||||
if(!m_data->recieverObj->gameClientState->Init(m_data->recieverObj))
|
if(!m_data->recieverObj->gameClientState->Init(m_data->recieverObj))
|
||||||
return DanBiasClientReturn_Error;
|
return DanBiasClientReturn_Error;
|
||||||
|
|
||||||
m_data->timer = new Utility::WinTimer(); //why dynamic memory?
|
m_data->timer.reset();
|
||||||
m_data->timer->reset();
|
|
||||||
return DanBiasClientReturn_Sucess;
|
return DanBiasClientReturn_Sucess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,8 +82,11 @@ namespace DanBias
|
||||||
// Main message loop
|
// Main message loop
|
||||||
while(m_data->window->Frame())
|
while(m_data->window->Frame())
|
||||||
{
|
{
|
||||||
float dt = (float)m_data->timer->getElapsedSeconds();
|
float dt = (float)m_data->timer.getElapsedSeconds();
|
||||||
m_data->timer->reset();
|
m_data->timer.reset();
|
||||||
|
|
||||||
|
if(m_data->recieverObj->IsConnected())
|
||||||
|
m_data->recieverObj->Update();
|
||||||
|
|
||||||
capFrame += dt;
|
capFrame += dt;
|
||||||
if(capFrame > 0.03)
|
if(capFrame > 0.03)
|
||||||
|
@ -133,9 +133,14 @@ namespace DanBias
|
||||||
|
|
||||||
HRESULT DanBiasGame::Update(float deltaTime)
|
HRESULT DanBiasGame::Update(float deltaTime)
|
||||||
{
|
{
|
||||||
m_data->recieverObj->Update();
|
|
||||||
|
|
||||||
m_data->inputObj->Update();
|
m_data->inputObj->Update();
|
||||||
|
|
||||||
|
if(m_data->serverOwner)
|
||||||
|
{
|
||||||
|
DanBias::GameServerAPI::ServerUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
DanBias::Client::GameClientState::ClientState state = DanBias::Client::GameClientState::ClientState_Same;
|
DanBias::Client::GameClientState::ClientState state = DanBias::Client::GameClientState::ClientState_Same;
|
||||||
state = m_data->recieverObj->gameClientState->Update(deltaTime, m_data->inputObj);
|
state = m_data->recieverObj->gameClientState->Update(deltaTime, m_data->inputObj);
|
||||||
|
@ -148,11 +153,19 @@ namespace DanBias
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
|
case Client::GameClientState::ClientState_LobbyCreated:
|
||||||
|
m_data->serverOwner = true;
|
||||||
case Client::GameClientState::ClientState_Lobby:
|
case Client::GameClientState::ClientState_Lobby:
|
||||||
m_data->recieverObj->gameClientState = new Client::LobbyState();
|
m_data->recieverObj->gameClientState = new Client::LobbyState();
|
||||||
break;
|
break;
|
||||||
case Client::GameClientState::ClientState_Game:
|
case Client::GameClientState::ClientState_Game:
|
||||||
|
if(m_data->serverOwner)
|
||||||
|
DanBias::GameServerAPI::GameStart();
|
||||||
m_data->recieverObj->gameClientState = new Client::GameState();
|
m_data->recieverObj->gameClientState = new Client::GameState();
|
||||||
|
if(m_data->serverOwner)
|
||||||
|
((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(0);
|
||||||
|
else
|
||||||
|
((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
@ -187,7 +200,6 @@ namespace DanBias
|
||||||
delete m_data->recieverObj->gameClientState;
|
delete m_data->recieverObj->gameClientState;
|
||||||
m_data->recieverObj->Disconnect();
|
m_data->recieverObj->Disconnect();
|
||||||
delete m_data->recieverObj;
|
delete m_data->recieverObj;
|
||||||
delete m_data->timer;
|
|
||||||
delete m_data->inputObj;
|
delete m_data->inputObj;
|
||||||
delete m_data;
|
delete m_data;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#define DANBIAS_CLIENTRECIEVEROBJECT_H
|
#define DANBIAS_CLIENTRECIEVEROBJECT_H
|
||||||
|
|
||||||
//WTF!? No headers included???
|
//WTF!? No headers included???
|
||||||
|
#include "../DanBiasGame/Include/DanBiasGame.h"
|
||||||
|
#include "../GameProtocols/GeneralProtocols.h"
|
||||||
|
|
||||||
namespace DanBias
|
namespace DanBias
|
||||||
{
|
{
|
||||||
|
@ -100,6 +102,18 @@ namespace DanBias
|
||||||
((Client::GameState*)gameClientState)->Protocol(&protocolData);
|
((Client::GameState*)gameClientState)->Protocol(&protocolData);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case protocol_Lobby_Start:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if(dynamic_cast<Client::LobbyState*>(gameClientState))
|
||||||
|
{
|
||||||
|
gameClientState->Release();
|
||||||
|
delete gameClientState;
|
||||||
|
gameClientState = new Client::GameState();
|
||||||
|
gameClientState->Init(m_data->recieverObj);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -128,8 +142,8 @@ namespace DanBias
|
||||||
break;
|
break;
|
||||||
case protocol_Lobby_GameData: //this->LobbyGameData (Protocol_LobbyGameData (p), c);
|
case protocol_Lobby_GameData: //this->LobbyGameData (Protocol_LobbyGameData (p), c);
|
||||||
{
|
{
|
||||||
GameLogic::Protocol_LobbyGameData temp(p);
|
//GameLogic::Protocol_LobbyGameData temp(p);
|
||||||
printf("%s, %i.%i\n", temp.mapName.c_str(), temp.majorVersion, temp.minorVersion);
|
//printf("%s, %i.%i\n", temp.mapName.c_str(), temp.majorVersion, temp.minorVersion);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case protocol_Lobby_ClientData: //this->LobbyMainData (Protocol_LobbyClientData (p), c);
|
case protocol_Lobby_ClientData: //this->LobbyMainData (Protocol_LobbyClientData (p), c);
|
||||||
|
|
|
@ -53,6 +53,8 @@ public:
|
||||||
{
|
{
|
||||||
ClientState_Login,
|
ClientState_Login,
|
||||||
ClientState_Lobby,
|
ClientState_Lobby,
|
||||||
|
ClientState_Lan,
|
||||||
|
ClientState_LobbyCreated,
|
||||||
ClientState_Game,
|
ClientState_Game,
|
||||||
ClientState_Same,
|
ClientState_Same,
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,21 +43,31 @@ bool GameState::Init(Oyster::Network::NetworkClient* nwClient)
|
||||||
privData->state = gameStateState_loading;
|
privData->state = gameStateState_loading;
|
||||||
privData->nwClient = nwClient;
|
privData->nwClient = nwClient;
|
||||||
privData->state = LoadGame();
|
privData->state = LoadGame();
|
||||||
|
pitch = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
GameState::gameStateState GameState::LoadGame()
|
GameState::gameStateState GameState::LoadGame()
|
||||||
{
|
{
|
||||||
Oyster::Graphics::Definitions::Pointlight plight;
|
Oyster::Graphics::Definitions::Pointlight plight;
|
||||||
plight.Pos = Oyster::Math::Float3(0,15,5);
|
plight.Pos = Oyster::Math::Float3(315, 0 ,5);
|
||||||
plight.Color = Oyster::Math::Float3(0,1,0);
|
plight.Color = Oyster::Math::Float3(0.9,0.7,0.2);
|
||||||
plight.Radius = 50;
|
plight.Radius = 100;
|
||||||
plight.Bright = 2;
|
plight.Bright = 0.9;
|
||||||
Oyster::Graphics::API::AddLight(plight);
|
Oyster::Graphics::API::AddLight(plight);
|
||||||
plight.Pos = Oyster::Math::Float3(10,15,5);
|
plight.Pos = Oyster::Math::Float3(10,350,5);
|
||||||
plight.Color = Oyster::Math::Float3(1,0,0);
|
plight.Color = Oyster::Math::Float3(0.9,0.7,0.3);
|
||||||
plight.Radius = 50;
|
plight.Radius = 200;
|
||||||
plight.Bright = 2;
|
plight.Bright = 0.7;
|
||||||
|
Oyster::Graphics::API::AddLight(plight);
|
||||||
|
plight.Pos = Oyster::Math::Float3(350,350,5);
|
||||||
|
plight.Color = Oyster::Math::Float3(0.9,0.7,0.3);
|
||||||
|
plight.Radius = 200;
|
||||||
|
plight.Bright = 0.7;
|
||||||
|
Oyster::Graphics::API::AddLight(plight);
|
||||||
|
plight.Pos = Oyster::Math::Float3(10,350,350);
|
||||||
|
plight.Color = Oyster::Math::Float3(0.9,0.7,0.3);
|
||||||
|
plight.Radius = 200;
|
||||||
|
plight.Bright = 0.7;
|
||||||
Oyster::Graphics::API::AddLight(plight);
|
Oyster::Graphics::API::AddLight(plight);
|
||||||
plight.Pos = Oyster::Math::Float3(10,-15,5);
|
plight.Pos = Oyster::Math::Float3(10,-15,5);
|
||||||
plight.Color = Oyster::Math::Float3(0,0,1);
|
plight.Color = Oyster::Math::Float3(0,0,1);
|
||||||
|
@ -74,20 +84,18 @@ bool GameState::LoadModels(std::wstring mapFile)
|
||||||
// open file
|
// open file
|
||||||
// read file
|
// read file
|
||||||
// init models
|
// init models
|
||||||
privData->modelCount = 2;
|
int nrOfBoxex = 20;
|
||||||
|
privData->modelCount = 3+nrOfBoxex;
|
||||||
|
myId += privData->modelCount;
|
||||||
|
int id = 0;
|
||||||
// add world model
|
// add world model
|
||||||
ModelInitData modelData;
|
ModelInitData modelData;
|
||||||
Oyster::Math3D::Float4x4 translate;
|
Oyster::Math3D::Float4x4 translate;
|
||||||
C_Object* obj;
|
C_Object* obj;
|
||||||
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0,0,0));
|
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0,0,0));
|
||||||
Oyster::Math3D::Float4x4 scale = Oyster::Math3D::Float4x4::identity;
|
modelData.world = translate ;//modelData.world * translate
|
||||||
scale.v[0].x = 8;
|
modelData.modelPath = L"world_earth.dan";
|
||||||
scale.v[1].y = 8;
|
modelData.id = id++;
|
||||||
scale.v[2].z = 8;
|
|
||||||
modelData.world = scale; //modelData.world * translate
|
|
||||||
modelData.modelPath = L"..\\Content\\Models\\ball.dan";
|
|
||||||
modelData.id = 0;
|
|
||||||
|
|
||||||
obj = new C_Player();
|
obj = new C_Player();
|
||||||
privData->object.push_back(obj);
|
privData->object.push_back(obj);
|
||||||
|
@ -95,43 +103,116 @@ bool GameState::LoadModels(std::wstring mapFile)
|
||||||
|
|
||||||
// add box model
|
// add box model
|
||||||
modelData.world = Oyster::Math3D::Float4x4::identity;
|
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||||
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(-5,15,0));
|
modelData.modelPath = L"crate_colonists.dan";
|
||||||
|
|
||||||
|
|
||||||
|
for(int i =0; i< nrOfBoxex; i ++)
|
||||||
|
{
|
||||||
|
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(4,320,0));
|
||||||
modelData.world = modelData.world * translate;
|
modelData.world = modelData.world * translate;
|
||||||
modelData.modelPath = L"..\\Content\\Models\\box.dan";
|
modelData.id = id++;
|
||||||
modelData.id = 1;
|
|
||||||
|
|
||||||
obj = new C_Player();
|
obj = new C_Player();
|
||||||
privData->object.push_back(obj);
|
privData->object.push_back(obj);
|
||||||
privData->object[privData->object.size() -1 ]->Init(modelData);
|
privData->object[privData->object.size() -1 ]->Init(modelData);
|
||||||
modelData.world = Oyster::Math3D::Float4x4::identity;
|
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||||
|
}
|
||||||
|
|
||||||
// add player model
|
// add crystal model
|
||||||
modelData.world = Oyster::Math3D::Float4x4::identity;
|
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||||
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0, 15, 0));
|
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 301, 0));
|
||||||
|
|
||||||
modelData.world = modelData.world * translate;
|
modelData.world = modelData.world * translate;
|
||||||
modelData.visible = true;
|
modelData.visible = true;
|
||||||
modelData.modelPath = L"..\\Content\\Models\\char_white.dan";
|
modelData.modelPath = L"crystalformation_b.dan";
|
||||||
modelData.id = 2;
|
modelData.id = id++;
|
||||||
|
// load models
|
||||||
|
obj = new C_Player();
|
||||||
|
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, 290, 0));
|
||||||
|
Oyster::Math3D::Float4x4 rot = Oyster::Math3D::RotationMatrix(Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0));
|
||||||
|
|
||||||
|
modelData.world = modelData.world * translate * rot;
|
||||||
|
modelData.visible = true;
|
||||||
|
modelData.modelPath = L"building_corporation.dan";
|
||||||
|
modelData.id = id++;
|
||||||
// load models
|
// load models
|
||||||
obj = new C_Player();
|
obj = new C_Player();
|
||||||
privData->object.push_back(obj);
|
privData->object.push_back(obj);
|
||||||
privData->object[privData->object.size() -1 ]->Init(modelData);
|
privData->object[privData->object.size() -1 ]->Init(modelData);
|
||||||
|
|
||||||
|
|
||||||
|
// add player model
|
||||||
|
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||||
|
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0, 320, 0));
|
||||||
|
|
||||||
|
modelData.world = modelData.world * translate;
|
||||||
|
modelData.visible = true;
|
||||||
|
modelData.modelPath = L"char_still_sizeref.dan";
|
||||||
|
modelData.id = id++;
|
||||||
|
// load models
|
||||||
|
obj = new C_Player();
|
||||||
|
privData->object.push_back(obj);
|
||||||
|
privData->object[privData->object.size() -1 ]->Init(modelData);
|
||||||
|
|
||||||
|
// add player model 2
|
||||||
|
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||||
|
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(50, 320, 0));
|
||||||
|
|
||||||
|
modelData.world = modelData.world * translate;
|
||||||
|
modelData.visible = true;
|
||||||
|
modelData.modelPath = L"char_still_sizeref.dan";
|
||||||
|
modelData.id = id++;
|
||||||
|
// load models
|
||||||
|
obj = new C_Player();
|
||||||
|
privData->object.push_back(obj);
|
||||||
|
privData->object[privData->object.size() -1 ]->Init(modelData);
|
||||||
|
|
||||||
|
// add jumppad
|
||||||
|
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||||
|
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(4, 300.3, 0));
|
||||||
|
//Oyster::Math3D::RotationMatrix_AxisZ()
|
||||||
|
modelData.world = modelData.world * translate;
|
||||||
|
modelData.visible = true;
|
||||||
|
modelData.modelPath = L"jumppad_round.dan";
|
||||||
|
modelData.id = id++;
|
||||||
|
// load models
|
||||||
|
obj = new C_Player();
|
||||||
|
privData->object.push_back(obj);
|
||||||
|
privData->object[privData->object.size() -1 ]->Init(modelData);
|
||||||
|
|
||||||
|
// add sky sphere
|
||||||
|
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||||
|
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0, 0, 0));
|
||||||
|
//Oyster::Math3D::RotationMatrix_AxisZ()
|
||||||
|
modelData.world = modelData.world * translate;
|
||||||
|
modelData.world.v[0].x = 800;
|
||||||
|
modelData.world.v[1].y = 800;
|
||||||
|
modelData.world.v[2].z = 800;
|
||||||
|
modelData.visible = true;
|
||||||
|
modelData.modelPath = L"skysphere.dan";
|
||||||
|
modelData.id = id++;
|
||||||
|
// load models
|
||||||
|
obj = new C_Player();
|
||||||
|
privData->object.push_back(obj);
|
||||||
|
privData->object[privData->object.size() -1 ]->Init(modelData);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool GameState::InitCamera(Oyster::Math::Float3 startPos)
|
bool GameState::InitCamera(Oyster::Math::Float3 startPos)
|
||||||
{
|
{
|
||||||
Oyster::Math::Float3 dir = Oyster::Math::Float3(0,0,-1);
|
Oyster::Math::Float3 dir = Oyster::Math::Float3(0,0,1);
|
||||||
Oyster::Math::Float3 up =Oyster::Math::Float3(0,1,0);
|
Oyster::Math::Float3 up =Oyster::Math::Float3(0,1,0);
|
||||||
Oyster::Math::Float3 pos = Oyster::Math::Float3(0, 0, 20);
|
Oyster::Math::Float3 pos = Oyster::Math::Float3(0, 0, 20);
|
||||||
|
|
||||||
camera->LookAt(pos, dir, up);
|
camera->LookAt(pos, dir, up);
|
||||||
camera->SetLens(3.14f/2, 1024/768, 1, 1000);
|
camera->SetLens(3.14f/2, 1024/768, 1, 1000);
|
||||||
|
|
||||||
privData->proj = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/2,1024.0f/768.0f,.1f,1000);
|
privData->proj = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/4,1024.0f/768.0f,.1f,1000);
|
||||||
//privData->proj = Oyster::Math3D::ProjectionMatrix_Orthographic(1024, 768, 1, 1000);
|
//privData->proj = Oyster::Math3D::ProjectionMatrix_Orthographic(1024, 768, 1, 1000);
|
||||||
Oyster::Graphics::API::SetProjection(privData->proj);
|
Oyster::Graphics::API::SetProjection(privData->proj);
|
||||||
camera->UpdateViewMatrix();
|
camera->UpdateViewMatrix();
|
||||||
|
@ -141,10 +222,12 @@ bool GameState::InitCamera(Oyster::Math::Float3 startPos)
|
||||||
privData->view = Oyster::Math3D::InverseOrientationMatrix(privData->view);
|
privData->view = Oyster::Math3D::InverseOrientationMatrix(privData->view);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
void GameState::setClientId(int id)
|
||||||
|
{
|
||||||
|
myId = id;
|
||||||
|
}
|
||||||
GameClientState::ClientState GameState::Update(float deltaTime, InputClass* KeyInput)
|
GameClientState::ClientState GameState::Update(float deltaTime, InputClass* KeyInput)
|
||||||
{
|
{
|
||||||
DanBias::GameServerAPI::ServerUpdate();
|
|
||||||
switch (privData->state)
|
switch (privData->state)
|
||||||
{
|
{
|
||||||
case gameStateState_loading:
|
case gameStateState_loading:
|
||||||
|
@ -272,14 +355,17 @@ void GameState::readKeyInput(InputClass* KeyInput)
|
||||||
//send delta mouse movement
|
//send delta mouse movement
|
||||||
if (KeyInput->IsMousePressed())
|
if (KeyInput->IsMousePressed())
|
||||||
{
|
{
|
||||||
camera->Yaw(KeyInput->GetYaw());
|
camera->Yaw(-KeyInput->GetYaw());
|
||||||
camera->Pitch(KeyInput->GetPitch());
|
camera->Pitch(KeyInput->GetPitch());
|
||||||
|
pitch = KeyInput->GetPitch();
|
||||||
camera->UpdateViewMatrix();
|
camera->UpdateViewMatrix();
|
||||||
GameLogic::Protocol_PlayerLook playerLookDir;
|
GameLogic::Protocol_PlayerLook playerLookDir;
|
||||||
Oyster::Math::Float3 look = camera->GetLook();
|
Oyster::Math::Float4 look = camera->GetLook();
|
||||||
playerLookDir.lookDirX = look.x;
|
playerLookDir.lookDirX = look.x;
|
||||||
playerLookDir.lookDirY = look.y;
|
playerLookDir.lookDirY = look.y;
|
||||||
playerLookDir.lookDirZ = look.z;
|
playerLookDir.lookDirZ = look.z;
|
||||||
|
playerLookDir.deltaX = -KeyInput->GetYaw();
|
||||||
|
|
||||||
privData->nwClient->Send(playerLookDir);
|
privData->nwClient->Send(playerLookDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +375,37 @@ void GameState::readKeyInput(InputClass* KeyInput)
|
||||||
if(!key_Shoot)
|
if(!key_Shoot)
|
||||||
{
|
{
|
||||||
GameLogic::Protocol_PlayerShot playerShot;
|
GameLogic::Protocol_PlayerShot playerShot;
|
||||||
playerShot.hasShot = true;
|
playerShot.primaryPressed = true;
|
||||||
|
playerShot.secondaryPressed = false;
|
||||||
|
playerShot.utilityPressed = false;
|
||||||
|
privData->nwClient->Send(playerShot);
|
||||||
|
key_Shoot = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
key_Shoot = false;
|
||||||
|
if(KeyInput->IsKeyPressed(DIK_X))
|
||||||
|
{
|
||||||
|
if(!key_Shoot)
|
||||||
|
{
|
||||||
|
GameLogic::Protocol_PlayerShot playerShot;
|
||||||
|
playerShot.primaryPressed = false;
|
||||||
|
playerShot.secondaryPressed = true;
|
||||||
|
playerShot.utilityPressed = false;
|
||||||
|
privData->nwClient->Send(playerShot);
|
||||||
|
key_Shoot = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
key_Shoot = false;
|
||||||
|
if(KeyInput->IsKeyPressed(DIK_C))
|
||||||
|
{
|
||||||
|
if(!key_Shoot)
|
||||||
|
{
|
||||||
|
GameLogic::Protocol_PlayerShot playerShot;
|
||||||
|
playerShot.primaryPressed = false;
|
||||||
|
playerShot.secondaryPressed = false;
|
||||||
|
playerShot.utilityPressed = true;
|
||||||
privData->nwClient->Send(playerShot);
|
privData->nwClient->Send(playerShot);
|
||||||
key_Shoot = true;
|
key_Shoot = true;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +414,7 @@ void GameState::readKeyInput(InputClass* KeyInput)
|
||||||
key_Shoot = false;
|
key_Shoot = false;
|
||||||
|
|
||||||
// jump
|
// jump
|
||||||
if(KeyInput->IsKeyPressed(DIK_X))
|
if(KeyInput->IsKeyPressed(DIK_SPACE))
|
||||||
{
|
{
|
||||||
if(!key_Jump)
|
if(!key_Jump)
|
||||||
{
|
{
|
||||||
|
@ -340,18 +456,40 @@ void GameState::Protocol( ObjPos* pos )
|
||||||
{
|
{
|
||||||
world[i] = pos->worldPos[i];
|
world[i] = pos->worldPos[i];
|
||||||
}
|
}
|
||||||
|
//printf("pos for obj %d, ",pos->object_ID );
|
||||||
for (unsigned int i = 0; i < privData->object.size(); i++)
|
for (unsigned int i = 0; i < privData->object.size(); i++)
|
||||||
{
|
{
|
||||||
if(privData->object[i]->GetId() == pos->object_ID)
|
if(privData->object[i]->GetId() == pos->object_ID)
|
||||||
{
|
{
|
||||||
privData->object[i]->setPos(world);
|
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])));
|
if(i == myId) // playerobj
|
||||||
//camera->setLook((Oyster::Math::Float3(world[8], world[9], world[10])));
|
|
||||||
if(i == 2) // playerobj
|
|
||||||
{
|
{
|
||||||
camera->SetPosition(Oyster::Math::Float3(world[12], world[13], world[14]));
|
Oyster::Math::Float3 right = Oyster::Math::Float3(world[0], world[1], world[2]);
|
||||||
|
Oyster::Math::Float3 up = Oyster::Math::Float3(world[4], world[5], world[6]);
|
||||||
|
Oyster::Math::Float3 objForward = (Oyster::Math::Float3(world[8], world[9], world[10]));
|
||||||
|
Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13], world[14]);
|
||||||
|
|
||||||
|
Oyster::Math::Float3 cameraLook = camera->GetLook();
|
||||||
|
Oyster::Math::Float3 cameraUp = camera->GetUp();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*Oyster::Math::Float3 newUp = cameraUp.Dot(up);
|
||||||
|
up *= newUp;
|
||||||
|
up.Normalize();
|
||||||
|
Oyster::Math::Float3 newLook = up.Cross(right);
|
||||||
|
newLook.Normalize();*/
|
||||||
|
|
||||||
|
camera->setRight(right);
|
||||||
|
camera->setUp(up);
|
||||||
|
camera->setLook(objForward);
|
||||||
|
|
||||||
|
up *= 1;
|
||||||
|
objForward *= -2;
|
||||||
|
Oyster::Math::Float3 cameraPos = up + pos + objForward;
|
||||||
|
camera->SetPosition(cameraPos);
|
||||||
|
|
||||||
camera->UpdateViewMatrix();
|
camera->UpdateViewMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ private:
|
||||||
bool key_Jump;
|
bool key_Jump;
|
||||||
Camera* camera;
|
Camera* camera;
|
||||||
|
|
||||||
|
int myId;
|
||||||
|
float pitch;
|
||||||
struct myData;
|
struct myData;
|
||||||
myData* privData;
|
myData* privData;
|
||||||
public:
|
public:
|
||||||
|
@ -36,7 +38,7 @@ public:
|
||||||
bool LoadModels(std::wstring mapFile) ;
|
bool LoadModels(std::wstring mapFile) ;
|
||||||
bool InitCamera(Oyster::Math::Float3 startPos) ;
|
bool InitCamera(Oyster::Math::Float3 startPos) ;
|
||||||
gameStateState LoadGame();
|
gameStateState LoadGame();
|
||||||
|
void setClientId(int id);
|
||||||
void readKeyInput(InputClass* KeyInput);
|
void readKeyInput(InputClass* KeyInput);
|
||||||
bool Render()override;
|
bool Render()override;
|
||||||
bool Release()override;
|
bool Release()override;
|
||||||
|
|
|
@ -0,0 +1,215 @@
|
||||||
|
#include "LanMenuState.h"
|
||||||
|
|
||||||
|
#include "C_obj/C_Player.h"
|
||||||
|
#include "C_obj/C_StaticObj.h"
|
||||||
|
#include "C_obj/C_DynamicObj.h"
|
||||||
|
#include "DllInterfaces/GFXAPI.h"
|
||||||
|
|
||||||
|
#include "LobbyState.h"
|
||||||
|
#include "GameState.h"
|
||||||
|
#include "../GameClientRecieverFunc.h"
|
||||||
|
|
||||||
|
#include <GameServerAPI.h>
|
||||||
|
|
||||||
|
using namespace DanBias::Client;
|
||||||
|
|
||||||
|
struct LanMenuState::myData
|
||||||
|
{
|
||||||
|
myData(){}
|
||||||
|
Oyster::Math3D::Float4x4 view;
|
||||||
|
Oyster::Math3D::Float4x4 proj;
|
||||||
|
C_Object* object[2];
|
||||||
|
int modelCount;
|
||||||
|
|
||||||
|
GameRecieverObject* recieverObj;
|
||||||
|
bool serverOwner;
|
||||||
|
|
||||||
|
// UI object
|
||||||
|
// game client*
|
||||||
|
}privData;
|
||||||
|
|
||||||
|
LanMenuState::LanMenuState()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LanMenuState::~LanMenuState()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LanMenuState::Init(Oyster::Network::NetworkClient* nwClient)
|
||||||
|
{
|
||||||
|
privData = new myData();
|
||||||
|
this->nwClient = nwClient;
|
||||||
|
// load models
|
||||||
|
LoadModels(L"UImodels.txt");
|
||||||
|
InitCamera(Oyster::Math::Float3(0,0,5.4f));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LanMenuState::LoadModels(std::wstring file)
|
||||||
|
{
|
||||||
|
Oyster::Graphics::Definitions::Pointlight plight;
|
||||||
|
plight.Pos = Oyster::Math::Float3(-2,3,0);
|
||||||
|
plight.Color = Oyster::Math::Float3(0,1,0);
|
||||||
|
plight.Radius = 10;
|
||||||
|
plight.Bright = 1;
|
||||||
|
Oyster::Graphics::API::AddLight(plight);
|
||||||
|
// open file
|
||||||
|
// read file
|
||||||
|
// init models
|
||||||
|
privData->modelCount = 2;
|
||||||
|
|
||||||
|
ModelInitData modelData;
|
||||||
|
|
||||||
|
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||||
|
modelData.visible = true;
|
||||||
|
modelData.modelPath = L"..\\Content\\Models\\box_2.dan";
|
||||||
|
// load models
|
||||||
|
privData->object[0] = new C_StaticObj();
|
||||||
|
privData->object[0]->Init(modelData);
|
||||||
|
|
||||||
|
Oyster::Math3D::Float4x4 translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(-2,-2,-2));
|
||||||
|
modelData.world = modelData.world * translate;
|
||||||
|
|
||||||
|
privData->object[1] = new C_DynamicObj();
|
||||||
|
privData->object[1]->Init(modelData);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LanMenuState::InitCamera(Oyster::Math::Float3 startPos)
|
||||||
|
{
|
||||||
|
privData->proj = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/2,1024.0f/768.0f,.1f,1000);
|
||||||
|
//privData->proj = Oyster::Math3D::ProjectionMatrix_Orthographic(1024, 768, 1, 1000);
|
||||||
|
Oyster::Graphics::API::SetProjection(privData->proj);
|
||||||
|
|
||||||
|
privData->view = Oyster::Math3D::OrientationMatrix_LookAtDirection(Oyster::Math::Float3(0,0,-1),Oyster::Math::Float3(0,1,0),startPos);
|
||||||
|
privData->view = Oyster::Math3D::InverseOrientationMatrix(privData->view);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameClientState::ClientState LanMenuState::Update(float deltaTime, InputClass* KeyInput)
|
||||||
|
{
|
||||||
|
/*ChangeState(KeyInput);
|
||||||
|
|
||||||
|
if(privData->recieverObj->IsConnected())
|
||||||
|
privData->recieverObj->Update();
|
||||||
|
KeyInput->Update();
|
||||||
|
|
||||||
|
if(privData->serverOwner)
|
||||||
|
{
|
||||||
|
DanBias::GameServerAPI::ServerUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
DanBias::Client::GameClientState::ClientState state = DanBias::Client::GameClientState::ClientState_Same;
|
||||||
|
state = privData->recieverObj->gameClientState->Update(deltaTime, KeyInput);
|
||||||
|
|
||||||
|
if(state != Client::GameClientState::ClientState_Same)
|
||||||
|
{
|
||||||
|
privData->recieverObj->gameClientState->Release();
|
||||||
|
delete privData->recieverObj->gameClientState;
|
||||||
|
privData->recieverObj->gameClientState = NULL;
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case Client::GameClientState::ClientState_LobbyCreated:
|
||||||
|
privData->serverOwner = true;
|
||||||
|
case Client::GameClientState::ClientState_Lobby:
|
||||||
|
privData->recieverObj->gameClientState = new Client::LobbyState();
|
||||||
|
break;
|
||||||
|
case Client::GameClientState::ClientState_Game:
|
||||||
|
privData->recieverObj->gameClientState = new Client::GameState();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//return E_FAIL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
privData->recieverObj->gameClientState->Init(privData->recieverObj); // send game client
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return ChangeState(KeyInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
GameClientState::ClientState LanMenuState::ChangeState(InputClass* KeyInput)
|
||||||
|
{
|
||||||
|
// create game
|
||||||
|
if( KeyInput->IsKeyPressed(DIK_C))
|
||||||
|
{
|
||||||
|
DanBias::GameServerAPI::ServerInitDesc desc;
|
||||||
|
|
||||||
|
DanBias::GameServerAPI::ServerInitiate(desc);
|
||||||
|
DanBias::GameServerAPI::ServerStart();
|
||||||
|
// my ip
|
||||||
|
nwClient->Connect(15151, "127.0.0.1");
|
||||||
|
|
||||||
|
if (!nwClient->IsConnected())
|
||||||
|
{
|
||||||
|
// failed to connect
|
||||||
|
return ClientState_Same;
|
||||||
|
}
|
||||||
|
return ClientState_Lobby;
|
||||||
|
}
|
||||||
|
// join game
|
||||||
|
if( KeyInput->IsKeyPressed(DIK_J))
|
||||||
|
{
|
||||||
|
// game ip
|
||||||
|
nwClient->Connect(15151, "194.47.150.56");
|
||||||
|
|
||||||
|
if (!nwClient->IsConnected())
|
||||||
|
{
|
||||||
|
// failed to connect
|
||||||
|
return ClientState_Same;
|
||||||
|
}
|
||||||
|
return ClientState_Lobby;
|
||||||
|
}
|
||||||
|
return ClientState_Same;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LanMenuState::Render()
|
||||||
|
{
|
||||||
|
Oyster::Graphics::API::SetView(privData->view);
|
||||||
|
Oyster::Graphics::API::SetProjection( privData->proj);
|
||||||
|
|
||||||
|
|
||||||
|
Oyster::Graphics::API::NewFrame();
|
||||||
|
// render objects
|
||||||
|
for (int i = 0; i < privData->modelCount; i++)
|
||||||
|
{
|
||||||
|
privData->object[i]->Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
// render effects
|
||||||
|
|
||||||
|
// render lights
|
||||||
|
|
||||||
|
Oyster::Graphics::API::EndFrame();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LanMenuState::Release()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < privData->modelCount; i++)
|
||||||
|
{
|
||||||
|
privData->object[i]->Release();
|
||||||
|
delete privData->object[i];
|
||||||
|
privData->object[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete privData;
|
||||||
|
privData = NULL;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LanMenuState::Protocol(ProtocolStruct* protocolStruct)
|
||||||
|
{
|
||||||
|
if((PlayerName*)protocolStruct)
|
||||||
|
PlayerJoinProtocol((PlayerName*)protocolStruct);
|
||||||
|
}
|
||||||
|
void LanMenuState::PlayerJoinProtocol(PlayerName* name)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef LAN_MENU_STATE_H
|
||||||
|
#define LAN_MENU_STATE_H
|
||||||
|
|
||||||
|
#include "GameClientState.h"
|
||||||
|
#include "OysterMath.h"
|
||||||
|
|
||||||
|
namespace DanBias
|
||||||
|
{
|
||||||
|
namespace Client
|
||||||
|
{
|
||||||
|
class LanMenuState : public GameClientState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LanMenuState();
|
||||||
|
virtual ~LanMenuState();
|
||||||
|
|
||||||
|
virtual bool Init(Oyster::Network::NetworkClient* nwClient);
|
||||||
|
virtual ClientState Update(float deltaTime, InputClass* KeyInput);
|
||||||
|
|
||||||
|
ClientState ChangeState(InputClass* KeyInput);
|
||||||
|
|
||||||
|
bool LoadModels(std::wstring file);
|
||||||
|
bool InitCamera(Oyster::Math::Float3 startPos);
|
||||||
|
|
||||||
|
virtual bool Render();
|
||||||
|
virtual bool Release();
|
||||||
|
virtual void Protocol(ProtocolStruct* protocolStruct);
|
||||||
|
|
||||||
|
void PlayerJoinProtocol(PlayerName* name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Oyster::Network::NetworkClient* nwClient;
|
||||||
|
struct myData;
|
||||||
|
myData* privData;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -87,12 +87,9 @@ GameClientState::ClientState LobbyState::Update(float deltaTime, InputClass* Key
|
||||||
// update animation
|
// update animation
|
||||||
// send data to server
|
// send data to server
|
||||||
// check data from server
|
// check data from server
|
||||||
DanBias::GameServerAPI::ServerUpdate();
|
|
||||||
|
|
||||||
if( KeyInput->IsKeyPressed(DIK_G))
|
if( KeyInput->IsKeyPressed(DIK_G))
|
||||||
{
|
{
|
||||||
if(!DanBias::GameServerAPI::GameStart())
|
|
||||||
return GameClientState::ClientState_Same;
|
|
||||||
return ClientState_Game;
|
return ClientState_Game;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ public:
|
||||||
bool Release();
|
bool Release();
|
||||||
void Protocol(ProtocolStruct* protocol)override;
|
void Protocol(ProtocolStruct* protocol)override;
|
||||||
void PlayerJoinProtocol(PlayerName* name);
|
void PlayerJoinProtocol(PlayerName* name);
|
||||||
|
void GameStarted();
|
||||||
|
|
||||||
};};};
|
};};};
|
||||||
#endif // ! DANBIAS_CLIENT_GAMECLIENTSTATE_H
|
#endif // ! DANBIAS_CLIENT_GAMECLIENTSTATE_H
|
||||||
|
|
|
@ -41,9 +41,9 @@ bool LoginState::Init(Oyster::Network::NetworkClient* nwClient)
|
||||||
bool LoginState::LoadModels(std::wstring file)
|
bool LoginState::LoadModels(std::wstring file)
|
||||||
{
|
{
|
||||||
Oyster::Graphics::Definitions::Pointlight plight;
|
Oyster::Graphics::Definitions::Pointlight plight;
|
||||||
plight.Pos = Oyster::Math::Float3(-2,3,0);
|
plight.Pos = Oyster::Math::Float3(0,0,5);
|
||||||
plight.Color = Oyster::Math::Float3(0,1,0);
|
plight.Color = Oyster::Math::Float3(1,1,1);
|
||||||
plight.Radius = 10;
|
plight.Radius = 100;
|
||||||
plight.Bright = 1;
|
plight.Bright = 1;
|
||||||
Oyster::Graphics::API::AddLight(plight);
|
Oyster::Graphics::API::AddLight(plight);
|
||||||
// open file
|
// open file
|
||||||
|
@ -55,13 +55,22 @@ bool LoginState::LoadModels(std::wstring file)
|
||||||
|
|
||||||
modelData.world = Oyster::Math3D::Float4x4::identity;
|
modelData.world = Oyster::Math3D::Float4x4::identity;
|
||||||
modelData.visible = true;
|
modelData.visible = true;
|
||||||
modelData.modelPath = L"..\\Content\\Models\\box_2.dan";
|
modelData.modelPath = L"identityPlane.dan";
|
||||||
// load models
|
// load models
|
||||||
privData->object[0] = new C_StaticObj();
|
Oyster::Math3D::Float4x4 translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(2,2,-2));
|
||||||
|
Oyster::Math3D::Float4x4 rot = Oyster::Math3D::RotationMatrix(Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0));
|
||||||
|
Oyster::Math3D::Float4x4 scale = Oyster::Math3D::Float4x4::identity;
|
||||||
|
int scaling = 2;
|
||||||
|
scale.v[0].x = scaling;
|
||||||
|
scale.v[1].y = scaling;
|
||||||
|
scale.v[2].z = scaling;
|
||||||
|
|
||||||
|
modelData.world = translate; //scale * translate * rot;
|
||||||
|
privData->object[0] = new C_DynamicObj();
|
||||||
privData->object[0]->Init(modelData);
|
privData->object[0]->Init(modelData);
|
||||||
|
|
||||||
Oyster::Math3D::Float4x4 translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(-2,-2,-2));
|
translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0,0,-2));
|
||||||
modelData.world = modelData.world * translate;
|
modelData.world = translate ;//* rot;
|
||||||
|
|
||||||
privData->object[1] = new C_DynamicObj();
|
privData->object[1] = new C_DynamicObj();
|
||||||
privData->object[1]->Init(modelData);
|
privData->object[1]->Init(modelData);
|
||||||
|
@ -103,13 +112,13 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key
|
||||||
// failed to connect
|
// failed to connect
|
||||||
return ClientState_Same;
|
return ClientState_Same;
|
||||||
}
|
}
|
||||||
return ClientState_Lobby;
|
return ClientState_LobbyCreated;
|
||||||
}
|
}
|
||||||
// join game
|
// join game
|
||||||
if( KeyInput->IsKeyPressed(DIK_J))
|
if( KeyInput->IsKeyPressed(DIK_J))
|
||||||
{
|
{
|
||||||
// game ip
|
// game ip
|
||||||
nwClient->Connect(15151, "194.47.150.56");
|
nwClient->Connect(15151, "127.0.0.1");
|
||||||
|
|
||||||
if (!nwClient->IsConnected())
|
if (!nwClient->IsConnected())
|
||||||
{
|
{
|
||||||
|
@ -126,7 +135,6 @@ bool LoginState::Render()
|
||||||
Oyster::Graphics::API::SetView(privData->view);
|
Oyster::Graphics::API::SetView(privData->view);
|
||||||
Oyster::Graphics::API::SetProjection( privData->proj);
|
Oyster::Graphics::API::SetProjection( privData->proj);
|
||||||
|
|
||||||
|
|
||||||
Oyster::Graphics::API::NewFrame();
|
Oyster::Graphics::API::NewFrame();
|
||||||
// render objects
|
// render objects
|
||||||
for (int i = 0; i < privData->modelCount; i++)
|
for (int i = 0; i < privData->modelCount; i++)
|
||||||
|
|
|
@ -173,6 +173,11 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Launcher.cpp" />
|
<ClCompile Include="Launcher.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\DanBiasGame\DanBiasGame.vcxproj">
|
||||||
|
<Project>{2a1bc987-af42-4500-802d-89cd32fc1309}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "AttatchmentMassDriver.h"
|
#include "AttatchmentMassDriver.h"
|
||||||
#include "PhysicsAPI.h"
|
#include "PhysicsAPI.h"
|
||||||
|
#include "GameLogicStates.h"
|
||||||
|
|
||||||
using namespace GameLogic;
|
using namespace GameLogic;
|
||||||
|
|
||||||
|
@ -8,12 +9,16 @@ using namespace GameLogic;
|
||||||
AttatchmentMassDriver::AttatchmentMassDriver(void)
|
AttatchmentMassDriver::AttatchmentMassDriver(void)
|
||||||
{
|
{
|
||||||
this->owner = 0;
|
this->owner = 0;
|
||||||
|
this->heldObject = NULL;
|
||||||
|
this->hasObject = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AttatchmentMassDriver::AttatchmentMassDriver(Player &owner)
|
AttatchmentMassDriver::AttatchmentMassDriver(Player &owner)
|
||||||
{
|
{
|
||||||
|
|
||||||
this->owner = &owner;
|
this->owner = &owner;
|
||||||
|
this->heldObject = NULL;
|
||||||
|
this->hasObject = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,30 +39,81 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage,
|
||||||
ForcePush(usage,dt);
|
ForcePush(usage,dt);
|
||||||
break;
|
break;
|
||||||
case WEAPON_FIRE::WEAPON_USE_SECONDARY_PRESS:
|
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);
|
ForcePull(usage,dt);
|
||||||
break;
|
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();
|
||||||
|
Oyster::Physics::ICustomBody::State ownerState = owner->GetRigidBody()->GetState();
|
||||||
|
Oyster::Math::Float3 up = -ownerState.GetGravityNormal();
|
||||||
|
up *= -0.3;
|
||||||
|
Oyster::Math::Float3 pos = ownerPos + up + (owner->GetLookDir().GetNormalized()*5);
|
||||||
|
|
||||||
|
state.SetCenterPosition(pos);
|
||||||
|
|
||||||
|
heldObject->SetState(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Pushes objects in a cone in front of the weapon when fired
|
* 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)
|
void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float dt)
|
||||||
{
|
{
|
||||||
//Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt);
|
//if the weapon has an object then it is only the object that will be shot away
|
||||||
Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition());
|
Oyster::Math::Float4 pushForce;
|
||||||
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));
|
|
||||||
int arg = 0;
|
|
||||||
|
|
||||||
Oyster::Physics::API::Instance().ApplyEffect(hitFrustum,&arg,ForcePushAction);
|
if(hasObject)
|
||||||
|
{
|
||||||
|
Oyster::Physics::API::Instance().ReleaseFromLimbo(heldObject);
|
||||||
|
pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (700);
|
||||||
|
Oyster::Physics::ICustomBody::State state = heldObject->GetState();
|
||||||
|
state.ApplyLinearImpulse((Oyster::Math::Float3)pushForce);
|
||||||
|
heldObject->SetState(state);
|
||||||
|
|
||||||
|
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()) * (20000 * 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,50);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Pulls the player in the direction he is looking, used for fast movement(kinda like a jetpack)
|
* 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();
|
Oyster::Physics::Struct::CustomBodyState state = this->owner->GetRigidBody()->GetState();
|
||||||
|
|
||||||
|
@ -68,3 +124,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 UseAttatchment(const WEAPON_FIRE &usage, float dt);
|
||||||
|
void Update(float dt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Pushes objects and players in a cone in front of the player
|
* 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);
|
void ForcePush(const WEAPON_FIRE &usage, float dt);
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Pulls the player forward, this is a movement tool
|
* 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);
|
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
|
* 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 ForcePushAction(Oyster::Physics::ICustomBody *obj, void* args);
|
||||||
|
static void AttemptPickUp(Oyster::Physics::ICustomBody *obj, void* args);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Oyster::Physics::ICustomBody *heldObject;
|
||||||
|
bool hasObject;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,15 @@
|
||||||
#include "Level.h"
|
#include "Level.h"
|
||||||
#include "AttatchmentMassDriver.h"
|
#include "AttatchmentMassDriver.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
|
#include "CollisionManager.h"
|
||||||
|
#include "JumpPad.h"
|
||||||
|
|
||||||
using namespace Oyster;
|
using namespace Oyster;
|
||||||
|
|
||||||
using namespace GameLogic;
|
using namespace GameLogic;
|
||||||
|
|
||||||
void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss);
|
|
||||||
void PlayerVObject(Player &player, Object &obj, 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
|
//Physics::ICustomBody::SubscriptMessage
|
||||||
void Player::PlayerCollision(Oyster::Physics::ICustomBody *rigidBodyPlayer, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss)
|
void Player::PlayerCollision(Oyster::Physics::ICustomBody *rigidBodyPlayer, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss)
|
||||||
|
@ -20,7 +22,6 @@ using namespace GameLogic;
|
||||||
Player *player = ((Game::PlayerData*)(rigidBodyPlayer->GetCustomTag()))->player;
|
Player *player = ((Game::PlayerData*)(rigidBodyPlayer->GetCustomTag()))->player;
|
||||||
Object *realObj = (Object*)obj->GetCustomTag(); //needs to be changed?
|
Object *realObj = (Object*)obj->GetCustomTag(); //needs to be changed?
|
||||||
|
|
||||||
return;
|
|
||||||
switch (realObj->GetObjectType())
|
switch (realObj->GetObjectType())
|
||||||
{
|
{
|
||||||
case OBJECT_TYPE::OBJECT_TYPE_GENERIC:
|
case OBJECT_TYPE::OBJECT_TYPE_GENERIC:
|
||||||
|
@ -29,26 +30,48 @@ using namespace GameLogic;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OBJECT_TYPE::OBJECT_TYPE_BOX:
|
case OBJECT_TYPE::OBJECT_TYPE_BOX:
|
||||||
PlayerVBox(*player,(*(DynamicObject*) realObj), kineticEnergyLoss);
|
PlayerVObject(*player,*realObj, kineticEnergyLoss);
|
||||||
//return Physics::ICustomBody::SubscriptMessage_none;
|
//return Physics::ICustomBody::SubscriptMessage_none;
|
||||||
break;
|
break;
|
||||||
case OBJECT_TYPE::OBJECT_TYPE_PLAYER:
|
case OBJECT_TYPE::OBJECT_TYPE_PLAYER:
|
||||||
//return Physics::ICustomBody::SubscriptMessage_none;
|
//return Physics::ICustomBody::SubscriptMessage_none;
|
||||||
break;
|
break;
|
||||||
case OBJECT_TYPE::OBJECT_TYPE_WORLD:
|
case OBJECT_TYPE::OBJECT_TYPE_WORLD:
|
||||||
int test = 5;
|
PlayerVObject(*player,*realObj, kineticEnergyLoss);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//return Physics::ICustomBody::SubscriptMessage_none;
|
//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
|
JumpPad *jumpPad = (JumpPad*)(rigidBodyJumpPad->GetCustomTag());
|
||||||
//use as part of the damage algorithm
|
Object *realObj = (Object*)obj->GetCustomTag(); //needs to be changed?
|
||||||
player.DamageLife(20);
|
|
||||||
|
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)
|
void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss)
|
||||||
{
|
{
|
||||||
|
@ -56,12 +79,12 @@ using namespace GameLogic;
|
||||||
//use kinetic energyloss of the collision in order too determin how much damage to take
|
//use kinetic energyloss of the collision in order too determin how much damage to take
|
||||||
//use as part of the damage algorithm
|
//use as part of the damage algorithm
|
||||||
int damageDone = 0;
|
int damageDone = 0;
|
||||||
int forceThreashHold = 200;
|
int forceThreashHold = 200000;
|
||||||
|
|
||||||
if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough
|
if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough
|
||||||
{
|
{
|
||||||
damageDone = kineticEnergyLoss * 0.10f;
|
damageDone = kineticEnergyLoss * 0.10f;
|
||||||
player.DamageLife(damageDone);
|
//player.DamageLife(damageDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -69,11 +92,30 @@ using namespace GameLogic;
|
||||||
{
|
{
|
||||||
return Physics::ICustomBody::SubscriptMessage_none;
|
return Physics::ICustomBody::SubscriptMessage_none;
|
||||||
}
|
}
|
||||||
|
Oyster::Physics::ICustomBody::SubscriptMessage Object::DefaultCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss)
|
||||||
|
{
|
||||||
|
return Physics::ICustomBody::SubscriptMessage_none;
|
||||||
|
}
|
||||||
|
Oyster::Physics::ICustomBody::SubscriptMessage Player::PlayerCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj)
|
||||||
|
{
|
||||||
|
return Physics::ICustomBody::SubscriptMessage_player_collision_response;
|
||||||
|
}
|
||||||
|
Oyster::Physics::ICustomBody::SubscriptMessage Player::PlayerCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss)
|
||||||
|
{
|
||||||
|
return Physics::ICustomBody::SubscriptMessage_none;
|
||||||
|
}
|
||||||
//Oyster::Physics::ICustomBody::SubscriptMessage
|
//Oyster::Physics::ICustomBody::SubscriptMessage
|
||||||
Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj)
|
Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj)
|
||||||
{
|
{
|
||||||
return Physics::ICustomBody::SubscriptMessage_ignore_collision_response;
|
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)
|
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;
|
return Physics::ICustomBody::SubscriptMessage_ignore_collision_response;
|
||||||
|
@ -81,10 +123,42 @@ using namespace GameLogic;
|
||||||
|
|
||||||
void AttatchmentMassDriver::ForcePushAction(Oyster::Physics::ICustomBody *obj, void *args)
|
void AttatchmentMassDriver::ForcePushAction(Oyster::Physics::ICustomBody *obj, void *args)
|
||||||
{
|
{
|
||||||
Oyster::Math::Float3 pushForce = Oyster::Math::Float4(1,0,0) * (1);
|
|
||||||
Oyster::Physics::ICustomBody::State state;
|
Oyster::Physics::ICustomBody::State state;
|
||||||
|
Object *realObj = (Object*)obj->GetCustomTag();
|
||||||
|
|
||||||
|
if(realObj->GetObjectType() == OBJECT_TYPE_PLAYER || realObj->GetObjectType() == OBJECT_TYPE_WORLD)
|
||||||
|
return;
|
||||||
|
|
||||||
state = obj->GetState();
|
state = obj->GetState();
|
||||||
state.ApplyLinearImpulse(pushForce);
|
state.ApplyLinearImpulse(((forcePushData*)(args))->pushForce);
|
||||||
obj->SetState(state);
|
obj->SetState(state);
|
||||||
//((Object*)obj->GetCustomTag())->ApplyLinearImpulse(pushForce);
|
}
|
||||||
|
|
||||||
|
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:
|
public:
|
||||||
//put general collision functions here that are not part of a specific object
|
//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)
|
Game::Game(void)
|
||||||
: initiated(false)
|
: initiated(false)
|
||||||
, onMoveFnc(0)
|
, onMoveFnc(0)
|
||||||
, onDeadFnc(0)
|
, onDisableFnc(0)
|
||||||
, frameTime(1.0f/120.0f)
|
, frameTime(1.0f/120.0f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -129,6 +129,7 @@ bool Game::NewFrame()
|
||||||
}
|
}
|
||||||
|
|
||||||
gameInstance.onMoveFnc(this->level);
|
gameInstance.onMoveFnc(this->level);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +151,7 @@ void Game::SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::O
|
||||||
this->onMoveFnc = functionPointer;
|
this->onMoveFnc = functionPointer;
|
||||||
break;
|
break;
|
||||||
case GameLogic::GameEvent::ObjectEventFunctionType_OnDead:
|
case GameLogic::GameEvent::ObjectEventFunctionType_OnDead:
|
||||||
this->onDeadFnc = functionPointer;
|
this->onDisableFnc = functionPointer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +183,6 @@ void Game::PhysicsOnMove(const ICustomBody *object)
|
||||||
}
|
}
|
||||||
void Game::PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer<ICustomBody> proto)
|
void Game::PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer<ICustomBody> proto)
|
||||||
{
|
{
|
||||||
if(gameInstance.onDeadFnc) gameInstance.onDeadFnc(0);
|
if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ namespace GameLogic
|
||||||
Oyster::Math::Float4x4 GetOrientation() override;
|
Oyster::Math::Float4x4 GetOrientation() override;
|
||||||
int GetID() const override;
|
int GetID() const override;
|
||||||
OBJECT_TYPE GetObjectType() 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;
|
Player *player;
|
||||||
};
|
};
|
||||||
|
@ -53,6 +53,7 @@ namespace GameLogic
|
||||||
Oyster::Math::Float4x4 GetOrientation() override;
|
Oyster::Math::Float4x4 GetOrientation() override;
|
||||||
int GetID() const override;
|
int GetID() const override;
|
||||||
OBJECT_TYPE GetObjectType() const override;
|
OBJECT_TYPE GetObjectType() const override;
|
||||||
|
int getNrOfDynamicObj()const override;
|
||||||
IObjectData* GetObjectAt(int ID) const override;
|
IObjectData* GetObjectAt(int ID) const override;
|
||||||
Level *level;
|
Level *level;
|
||||||
};
|
};
|
||||||
|
@ -73,16 +74,14 @@ namespace GameLogic
|
||||||
|
|
||||||
float GetFrameTime() const;
|
float GetFrameTime() const;
|
||||||
|
|
||||||
private:
|
|
||||||
static void PhysicsOnMove(const Oyster::Physics::ICustomBody *object);
|
static void PhysicsOnMove(const Oyster::Physics::ICustomBody *object);
|
||||||
static void PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer<Oyster::Physics::ICustomBody> proto);
|
static void PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer<Oyster::Physics::ICustomBody> proto);
|
||||||
|
|
||||||
private:
|
|
||||||
Utility::DynamicMemory::DynamicArray<PlayerData*> players;
|
Utility::DynamicMemory::DynamicArray<PlayerData*> players;
|
||||||
LevelData* level;
|
LevelData* level;
|
||||||
float frameTime;
|
float frameTime;
|
||||||
bool initiated;
|
bool initiated;
|
||||||
GameEvent::ObjectEventFunction onDeadFnc;
|
GameEvent::ObjectEventFunction onDisableFnc;
|
||||||
GameEvent::ObjectEventFunction onMoveFnc;
|
GameEvent::ObjectEventFunction onMoveFnc;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace GameLogic
|
||||||
* @param x: The relative x axis
|
* @param x: The relative x axis
|
||||||
* @param y: The relative y 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
|
* Uses the chosen players weapon based on input
|
||||||
|
@ -100,6 +100,7 @@ namespace GameLogic
|
||||||
class ILevelData :public IObjectData
|
class ILevelData :public IObjectData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual int getNrOfDynamicObj()const = 0;
|
||||||
virtual IObjectData* GetObjectAt(int ID) const = 0;
|
virtual IObjectData* GetObjectAt(int ID) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,7 @@
|
||||||
<ClInclude Include="GameLogicStates.h" />
|
<ClInclude Include="GameLogicStates.h" />
|
||||||
<ClInclude Include="GameMode.h" />
|
<ClInclude Include="GameMode.h" />
|
||||||
<ClInclude Include="IAttatchment.h" />
|
<ClInclude Include="IAttatchment.h" />
|
||||||
|
<ClInclude Include="JumpPad.h" />
|
||||||
<ClInclude Include="Level.h" />
|
<ClInclude Include="Level.h" />
|
||||||
<ClInclude Include="LevelLoader\LevelLoader.h" />
|
<ClInclude Include="LevelLoader\LevelLoader.h" />
|
||||||
<ClInclude Include="LevelLoader\Loader.h" />
|
<ClInclude Include="LevelLoader\Loader.h" />
|
||||||
|
@ -206,6 +207,7 @@
|
||||||
<ClCompile Include="Game_LevelData.cpp" />
|
<ClCompile Include="Game_LevelData.cpp" />
|
||||||
<ClCompile Include="Game_PlayerData.cpp" />
|
<ClCompile Include="Game_PlayerData.cpp" />
|
||||||
<ClCompile Include="IAttatchment.cpp" />
|
<ClCompile Include="IAttatchment.cpp" />
|
||||||
|
<ClCompile Include="JumpPad.cpp" />
|
||||||
<ClCompile Include="Level.cpp" />
|
<ClCompile Include="Level.cpp" />
|
||||||
<ClCompile Include="LevelLoader\LevelLoader.cpp" />
|
<ClCompile Include="LevelLoader\LevelLoader.cpp" />
|
||||||
<ClCompile Include="LevelLoader\Loader.cpp" />
|
<ClCompile Include="LevelLoader\Loader.cpp" />
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ShowAllFiles>true</ShowAllFiles>
|
<ShowAllFiles>false</ShowAllFiles>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
|
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#ifndef GAMELOGICSTATES_H
|
#ifndef GAMELOGICSTATES_H
|
||||||
#define GAMELOGICSTATES_H
|
#define GAMELOGICSTATES_H
|
||||||
|
#include "OysterMath.h"
|
||||||
|
|
||||||
namespace GameLogic
|
namespace GameLogic
|
||||||
{
|
{
|
||||||
|
@ -46,6 +47,12 @@ namespace GameLogic
|
||||||
WEAPON_STATE_RELOADING = 2,
|
WEAPON_STATE_RELOADING = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct forcePushData
|
||||||
|
{
|
||||||
|
Oyster::Math::Float3 pushForce;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,10 @@ OBJECT_TYPE Game::LevelData::GetObjectType() const
|
||||||
return ((IObjectData*)this->level)->GetObjectType();
|
return ((IObjectData*)this->level)->GetObjectType();
|
||||||
//return OBJECT_TYPE_UNKNOWN;
|
//return OBJECT_TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
int Game::LevelData::getNrOfDynamicObj()const
|
||||||
|
{
|
||||||
|
return this->level->getNrOfDynamicObj();
|
||||||
|
}
|
||||||
IObjectData* Game::LevelData::GetObjectAt(int ID) const
|
IObjectData* Game::LevelData::GetObjectAt(int ID) const
|
||||||
{
|
{
|
||||||
return this->level->GetObj(ID);
|
return this->level->GetObj(ID);
|
||||||
|
|
|
@ -7,16 +7,25 @@ Game::PlayerData::PlayerData()
|
||||||
{
|
{
|
||||||
//set some stats that are appropriate to a player
|
//set some stats that are appropriate to a player
|
||||||
Oyster::Physics::API::SimpleBodyDescription sbDesc;
|
Oyster::Physics::API::SimpleBodyDescription sbDesc;
|
||||||
sbDesc.centerPosition = Oyster::Math::Float3(0,165,0);
|
sbDesc.centerPosition = Oyster::Math::Float3(0,308,0);
|
||||||
sbDesc.size = Oyster::Math::Float3(4,7,4);
|
sbDesc.size = Oyster::Math::Float3(0.5f,2,1);
|
||||||
|
sbDesc.mass = 70;
|
||||||
|
sbDesc.restitutionCoeff = 0.5;
|
||||||
|
sbDesc.frictionCoeff_Static = 0.4;
|
||||||
|
sbDesc.frictionCoeff_Dynamic = 0.3;
|
||||||
|
sbDesc.rotation = Oyster::Math::Float3(0, Oyster::Math::pi, 0);
|
||||||
|
|
||||||
//create rigid body
|
//create rigid body
|
||||||
Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release();
|
Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release();
|
||||||
|
|
||||||
//create player with this rigid body
|
//create player with this rigid body
|
||||||
this->player = new Player(rigidBody,Object::DefaultCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER);
|
this->player = new Player(rigidBody,Player::PlayerCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER);
|
||||||
this->player->GetRigidBody()->SetCustomTag(this);
|
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)
|
Game::PlayerData::PlayerData(int playerID,int teamID)
|
||||||
{
|
{
|
||||||
|
@ -60,7 +69,7 @@ OBJECT_TYPE Game::PlayerData::GetObjectType() const
|
||||||
{
|
{
|
||||||
return this->player->GetObjectType();
|
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);
|
this->player->Rotate(lookDir);
|
||||||
}
|
}
|
|
@ -20,6 +20,7 @@ namespace GameLogic
|
||||||
~IAttatchment(void);
|
~IAttatchment(void);
|
||||||
|
|
||||||
virtual void UseAttatchment(const WEAPON_FIRE &usage, float dt) = 0;
|
virtual void UseAttatchment(const WEAPON_FIRE &usage, float dt) = 0;
|
||||||
|
virtual void Update(float dt) = 0;
|
||||||
|
|
||||||
private:
|
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
|
|
@ -20,46 +20,148 @@ void Level::InitiateLevel(std::string levelPath)
|
||||||
}
|
}
|
||||||
void Level::InitiateLevel(float radius)
|
void Level::InitiateLevel(float radius)
|
||||||
{
|
{
|
||||||
|
float heading = Utility::Value::Radian(180.0f);
|
||||||
|
float attitude = Utility::Value::Radian(0.0f);
|
||||||
|
float bank = Utility::Value::Radian(0);
|
||||||
|
|
||||||
|
double c1 = cos(heading/2);
|
||||||
|
double s1 = sin(heading/2);
|
||||||
|
double c2 = cos(attitude/2);
|
||||||
|
double s2 = sin(attitude/2);
|
||||||
|
double c3 = cos(bank/2);
|
||||||
|
double s3 = sin(bank/2);
|
||||||
|
double c1c2 = c1*c2;
|
||||||
|
double s1s2 = s1*s2;
|
||||||
|
double w =c1c2*c3 - s1s2*s3;
|
||||||
|
double x =c1c2*s3 + s1s2*c3;
|
||||||
|
double y =s1*c2*c3 + c1*s2*s3;
|
||||||
|
double z =c1*s2*c3 - s1*c2*s3;
|
||||||
|
double angle = 2 * acos(w);
|
||||||
|
|
||||||
|
double norm = x*x+y*y+z*z;
|
||||||
|
if (norm < 0.001) { // when all euler angles are zero angle =0 so
|
||||||
|
// we can set axis to anything to avoid divide by zero
|
||||||
|
x=1;
|
||||||
|
y=z=0;
|
||||||
|
} else {
|
||||||
|
norm = sqrt(norm);
|
||||||
|
x /= norm;
|
||||||
|
y /= norm;
|
||||||
|
z /= norm;
|
||||||
|
}
|
||||||
|
|
||||||
// add level sphere
|
// add level sphere
|
||||||
API::SphericalBodyDescription sbDesc;
|
API::SphericalBodyDescription sbDesc;
|
||||||
sbDesc.centerPosition = Oyster::Math::Float4(0,0,0,1);
|
sbDesc.centerPosition = Oyster::Math::Float4(0,0,0,1);
|
||||||
sbDesc.ignoreGravity = true;
|
sbDesc.ignoreGravity = true;
|
||||||
sbDesc.radius = 150;
|
sbDesc.radius = 300;
|
||||||
sbDesc.mass = 10e12f;
|
sbDesc.mass = 10e12f;
|
||||||
|
sbDesc.frictionCoeff_Static = 0;
|
||||||
|
sbDesc.frictionCoeff_Dynamic = 0;
|
||||||
|
//sbDesc.rotation =
|
||||||
ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release();
|
ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release();
|
||||||
|
|
||||||
ICustomBody::State state;
|
ICustomBody::State state;
|
||||||
rigidBody->GetState(state);
|
rigidBody->GetState(state);
|
||||||
state.SetRestitutionCoeff(0.01);
|
state.SetRestitutionCoeff(0.2);
|
||||||
rigidBody->SetState(state);
|
rigidBody->SetState(state);
|
||||||
|
|
||||||
levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD);
|
levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD);
|
||||||
rigidBody->SetCustomTag(levelObj);
|
rigidBody->SetCustomTag(levelObj);
|
||||||
|
|
||||||
|
//this->dynamicObjects = new DynamicArray< DynamicObject>;
|
||||||
// add box
|
// add box
|
||||||
API::SimpleBodyDescription sbDesc_TestBox;
|
API::SimpleBodyDescription sbDesc_TestBox;
|
||||||
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-5,15,0,0);
|
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10,320,0,0);
|
||||||
sbDesc_TestBox.ignoreGravity = false;
|
sbDesc_TestBox.ignoreGravity = false;
|
||||||
sbDesc_TestBox.mass = 10;
|
|
||||||
sbDesc_TestBox.size = Oyster::Math::Float4(0.5f,0.5f,0.5f,0);
|
|
||||||
|
|
||||||
ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
|
sbDesc_TestBox.mass = 50;
|
||||||
|
sbDesc_TestBox.size = Oyster::Math::Float4(2,2,2,0);
|
||||||
|
|
||||||
|
|
||||||
|
ICustomBody* rigidBody_TestBox;
|
||||||
|
|
||||||
|
int nrOfBoxex = 5;
|
||||||
|
int offset = 0;
|
||||||
|
for(int i =0; i< nrOfBoxex; i ++)
|
||||||
|
{
|
||||||
|
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-20 +( i*7) ,320,20,0);
|
||||||
|
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
|
||||||
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
|
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
|
||||||
|
|
||||||
testBox = new DynamicObject(rigidBody_TestBox, OBJECT_TYPE::OBJECT_TYPE_BOX);
|
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
|
||||||
rigidBody_TestBox->SetCustomTag(testBox);
|
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i]);
|
||||||
rigidBody_TestBox->GetState(state);
|
}
|
||||||
state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,4));
|
offset += nrOfBoxex;
|
||||||
rigidBody_TestBox->SetState(state);
|
for(int i =0; i< nrOfBoxex; i ++)
|
||||||
|
{
|
||||||
|
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-20,320, -20 +( i*7),0);
|
||||||
|
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
|
||||||
|
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
|
||||||
|
|
||||||
|
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
|
||||||
|
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i+offset]);
|
||||||
|
}
|
||||||
|
offset += nrOfBoxex;
|
||||||
|
for(int i =0; i< nrOfBoxex; i ++)
|
||||||
|
{
|
||||||
|
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(20,320,-20 + ( i*7),0);
|
||||||
|
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
|
||||||
|
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
|
||||||
|
|
||||||
|
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
|
||||||
|
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i+offset]);
|
||||||
|
}
|
||||||
|
offset += nrOfBoxex;
|
||||||
|
for(int i =0; i< nrOfBoxex; i ++)
|
||||||
|
{
|
||||||
|
sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-20 +( i*7) ,320,-20,0);
|
||||||
|
rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release();
|
||||||
|
rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel);
|
||||||
|
|
||||||
|
this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
|
||||||
|
rigidBody_TestBox->SetCustomTag(this->dynamicObjects[i+offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// add crystal
|
||||||
|
API::SimpleBodyDescription sbDesc_Crystal;
|
||||||
|
sbDesc_Crystal.centerPosition = Oyster::Math::Float4(10, 305, 0, 0);
|
||||||
|
sbDesc_Crystal.ignoreGravity = false;
|
||||||
|
sbDesc_Crystal.mass = 70;
|
||||||
|
sbDesc_Crystal.size = Oyster::Math::Float4(2,3,2,0);
|
||||||
|
|
||||||
|
ICustomBody* rigidBody_Crystal = API::Instance().CreateRigidBody(sbDesc_Crystal).Release();
|
||||||
|
rigidBody_Crystal->SetSubscription(Level::PhysicsOnMoveLevel);
|
||||||
|
this->dynamicObjects.Push(new DynamicObject(rigidBody_Crystal,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX));
|
||||||
|
rigidBody_Crystal->SetCustomTag(this->dynamicObjects[nrOfBoxex]);
|
||||||
|
|
||||||
|
|
||||||
|
// add house
|
||||||
|
API::SimpleBodyDescription sbDesc_House;
|
||||||
|
//sbDesc_House.centerPosition = Oyster::Math::Float4(212, 212, 0, 0);
|
||||||
|
sbDesc_House.centerPosition = Oyster::Math::Float4(-50, 290, 0, 0);
|
||||||
|
sbDesc_House.ignoreGravity = false;
|
||||||
|
sbDesc_House.rotation = Oyster::Math::Float3(0 ,Utility::Value::Radian(90.0f), 0);
|
||||||
|
sbDesc_House.mass = 70;
|
||||||
|
sbDesc_House.size = Oyster::Math::Float4(40,40,40,0);
|
||||||
|
|
||||||
|
|
||||||
|
ICustomBody* rigidBody_House = API::Instance().CreateRigidBody(sbDesc_House).Release();
|
||||||
|
rigidBody_House->SetSubscription(Level::PhysicsOnMoveLevel);
|
||||||
|
this->staticObjects.Push(new StaticObject(rigidBody_House,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_GENERIC));
|
||||||
|
rigidBody_House->SetCustomTag(this->staticObjects[0]);
|
||||||
|
rigidBody_House->GetState(state);
|
||||||
|
Oyster::Math::Float4x4 world = state.GetOrientation();
|
||||||
|
|
||||||
|
|
||||||
// add gravitation
|
// add gravitation
|
||||||
API::Gravity gravityWell;
|
API::Gravity gravityWell;
|
||||||
gravityWell.gravityType = API::Gravity::GravityType_Well;
|
gravityWell.gravityType = API::Gravity::GravityType_Well;
|
||||||
gravityWell.well.mass = 10e16f;
|
gravityWell.well.mass = 1e17f;
|
||||||
gravityWell.well.position = Oyster::Math::Float4(0,0,0,1);
|
gravityWell.well.position = Oyster::Math::Float4(0,0,0,1);
|
||||||
API::Instance().AddGravity(gravityWell);
|
API::Instance().AddGravity(gravityWell);
|
||||||
}
|
}
|
||||||
|
@ -79,12 +181,18 @@ void Level::RespawnPlayer(Player *player)
|
||||||
this->teamManager.RespawnPlayerRandom(player);
|
this->teamManager.RespawnPlayerRandom(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Level::getNrOfDynamicObj()
|
||||||
|
{
|
||||||
|
return this->dynamicObjects.Size();
|
||||||
|
}
|
||||||
Object* Level::GetObj( int ID) const
|
Object* Level::GetObj( int ID) const
|
||||||
{
|
{
|
||||||
if( ID == 0 )
|
for (int i = 0; i< this->dynamicObjects.Size(); i++)
|
||||||
return (Object*)levelObj;
|
{
|
||||||
else
|
if(this->dynamicObjects[i]->GetID() == ID)
|
||||||
return (Object*)testBox;
|
return this->dynamicObjects[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
void Level::PhysicsOnMoveLevel(const ICustomBody *object)
|
void Level::PhysicsOnMoveLevel(const ICustomBody *object)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,6 +60,7 @@ namespace GameLogic
|
||||||
static Oyster::Physics::ICustomBody::SubscriptMessage LevelCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj);
|
static Oyster::Physics::ICustomBody::SubscriptMessage LevelCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj);
|
||||||
static Oyster::Physics::ICustomBody::SubscriptMessage LevelCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
|
static Oyster::Physics::ICustomBody::SubscriptMessage LevelCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
|
||||||
|
|
||||||
|
int getNrOfDynamicObj();
|
||||||
Object* GetObj( int ID ) const;
|
Object* GetObj( int ID ) const;
|
||||||
static void PhysicsOnMoveLevel(const Oyster::Physics::ICustomBody *object);
|
static void PhysicsOnMoveLevel(const Oyster::Physics::ICustomBody *object);
|
||||||
|
|
||||||
|
@ -71,7 +72,6 @@ namespace GameLogic
|
||||||
GameMode gameMode;
|
GameMode gameMode;
|
||||||
Utility::DynamicMemory::SmartPointer<Oyster::Physics::ICustomBody> rigidBodyLevel;
|
Utility::DynamicMemory::SmartPointer<Oyster::Physics::ICustomBody> rigidBodyLevel;
|
||||||
StaticObject *levelObj;
|
StaticObject *levelObj;
|
||||||
DynamicObject *testBox;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,16 +3,33 @@
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
|
|
||||||
#include "LevelLoader.h"
|
#include "LevelLoader.h"
|
||||||
|
#include "LevelParser.h"
|
||||||
|
|
||||||
using namespace GameLogic;
|
using namespace GameLogic;
|
||||||
using namespace GameLogic::LevelFileLoader;
|
using namespace GameLogic::LevelFileLoader;
|
||||||
|
|
||||||
|
struct LevelLoader::PrivData
|
||||||
std::vector<ObjectTypeHeader> LevelLoader::LoadLevel(std::string fileName)
|
|
||||||
{
|
{
|
||||||
return parser.Parse(fileName);
|
LevelParser parser;
|
||||||
|
std::string folderPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
LevelLoader::LevelLoader()
|
||||||
|
: pData(new PrivData)
|
||||||
|
{
|
||||||
|
pData->folderPath = "Standard path";
|
||||||
|
}
|
||||||
|
|
||||||
|
LevelLoader::~LevelLoader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Utility::DynamicMemory::SmartPointer<ObjectTypeHeader>> LevelLoader::LoadLevel(std::string fileName)
|
||||||
|
{
|
||||||
|
return pData->parser.Parse(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelMetaData LevelLoader::LoadLevelHeader(std::string fileName)
|
LevelMetaData LevelLoader::LoadLevelHeader(std::string fileName)
|
||||||
{
|
{
|
||||||
return parser.ParseHeader(fileName);
|
return pData->parser.ParseHeader(fileName);
|
||||||
}
|
}
|
|
@ -7,9 +7,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <Vector.h>
|
#include "../Misc/Utilities.h"
|
||||||
#include "ObjectDefines.h"
|
#include "ObjectDefines.h"
|
||||||
#include "LevelParser.h"
|
|
||||||
|
|
||||||
namespace GameLogic
|
namespace GameLogic
|
||||||
{
|
{
|
||||||
|
@ -17,15 +16,15 @@ namespace GameLogic
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LevelLoader(){this->parser = GameLogic::LevelFileLoader::LevelParser(); }
|
LevelLoader();
|
||||||
~LevelLoader(){}
|
~LevelLoader();
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Loads the level and objects from file.
|
* Loads the level and objects from file.
|
||||||
* @param fileName: Path to the level-file that you want to load.
|
* @param fileName: Path to the level-file that you want to load.
|
||||||
* @return: Returns all structs with objects and information about the level.
|
* @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.
|
* Just for fast access for the meta information about the level.
|
||||||
|
@ -35,7 +34,8 @@ namespace GameLogic
|
||||||
LevelMetaData LoadLevelHeader(std::string fileName); //.
|
LevelMetaData LoadLevelHeader(std::string fileName); //.
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GameLogic::LevelFileLoader::LevelParser parser;
|
struct PrivData;
|
||||||
|
Utility::DynamicMemory::SmartPointer<PrivData> pData;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
#include "LevelParser.h"
|
#include "LevelParser.h"
|
||||||
|
|
||||||
#include "Loader.h"
|
#include "Loader.h"
|
||||||
|
@ -5,10 +9,11 @@
|
||||||
|
|
||||||
using namespace GameLogic;
|
using namespace GameLogic;
|
||||||
using namespace ::LevelFileLoader;
|
using namespace ::LevelFileLoader;
|
||||||
|
using namespace Utility::DynamicMemory;
|
||||||
|
|
||||||
LevelParser::LevelParser()
|
LevelParser::LevelParser()
|
||||||
{
|
{
|
||||||
formatVersion.formatVersionMajor = 1;
|
formatVersion.formatVersionMajor = 2;
|
||||||
formatVersion.formatVersionMinor = 0;
|
formatVersion.formatVersionMinor = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,49 +21,159 @@ LevelParser::~LevelParser()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ObjectTypeHeader> LevelParser::Parse(std::string filename)
|
std::vector<SmartPointer<ObjectTypeHeader>> LevelParser::Parse(std::string filename)
|
||||||
{
|
{
|
||||||
int bufferSize = 0;
|
int bufferSize = 0;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
|
||||||
std::vector<ObjectTypeHeader> objects;
|
std::vector<SmartPointer<ObjectTypeHeader>> objects;
|
||||||
|
|
||||||
//Read entire level file.
|
//Read entire level file.
|
||||||
Loader loader;
|
Loader loader;
|
||||||
char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize);
|
char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize);
|
||||||
|
|
||||||
//Read format version
|
//Read format version
|
||||||
FormatVersion levelFormatVersion;
|
LevelLoaderInternal::FormatVersion levelFormatVersion;
|
||||||
//ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion));
|
ParseObject(&buffer[counter], &levelFormatVersion, sizeof(levelFormatVersion));
|
||||||
|
counter += sizeof(levelFormatVersion);
|
||||||
if(this->formatVersion != levelFormatVersion)
|
if(this->formatVersion != levelFormatVersion)
|
||||||
{
|
{
|
||||||
//Do something if it's not the same version
|
//Do something if it's not the same version
|
||||||
|
|
||||||
|
//Returns an empty vector, because it will most likely fail to read the level format.
|
||||||
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(counter < bufferSize)
|
while(counter < bufferSize)
|
||||||
{
|
{
|
||||||
//Get typeID
|
//Get typeID
|
||||||
ObjectTypeHeader typeID;
|
ObjectType typeID;
|
||||||
ParseObject(&buffer[counter], &typeID, sizeof(typeID));
|
ParseObject(&buffer[counter], &typeID, sizeof(typeID));
|
||||||
switch((int)typeID.typeID)
|
switch((int)typeID)
|
||||||
{
|
{
|
||||||
case ObjectType_LevelMetaData:
|
case ObjectType_LevelMetaData:
|
||||||
{
|
{
|
||||||
LevelMetaData header;
|
SmartPointer<ObjectTypeHeader> header = new LevelMetaData;
|
||||||
ParseLevelMetaData(&buffer[counter], header, counter);
|
ParseLevelMetaData(&buffer[counter], *(LevelMetaData*)header.Get(), counter);
|
||||||
objects.push_back(header);
|
objects.push_back(header);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ObjectType_Dynamic:
|
//This is by design, static and dynamic is using the same converter. Do not add anything inbetween them.
|
||||||
|
//Unless they are changed to not be the same.
|
||||||
|
case ObjectType_Static: case ObjectType_Dynamic:
|
||||||
{
|
{
|
||||||
ObjectHeader header;
|
//Get specialType.
|
||||||
ParseObject(&buffer[counter], &header, sizeof(header));
|
ObjectSpecialType specialType;
|
||||||
|
ParseObject(&buffer[counter+4], &specialType, sizeof(typeID));
|
||||||
|
|
||||||
|
switch(specialType)
|
||||||
|
{
|
||||||
|
//These three does not have any specail variables at this time.
|
||||||
|
//There for they are using the same 'parser'.
|
||||||
|
case ObjectSpecialType_World:
|
||||||
|
case ObjectSpecialType_Building:
|
||||||
|
case ObjectSpecialType_Damaging:
|
||||||
|
case ObjectSpecialType_Explosive:
|
||||||
|
{
|
||||||
|
ObjectHeader* header = new ObjectHeader;
|
||||||
|
ParseObject(&buffer[counter], *header, counter);
|
||||||
objects.push_back(header);
|
objects.push_back(header);
|
||||||
counter += sizeof(header);
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ObjectSpecialType_JumpPad:
|
||||||
|
{
|
||||||
|
JumpPadAttributes* header = new JumpPadAttributes;
|
||||||
|
ParseObject(&buffer[counter], *header, counter);
|
||||||
|
|
||||||
|
//Read the spec
|
||||||
|
ParseObject(&buffer[counter], header->direction, 16);
|
||||||
|
objects.push_back(header);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ObjectSpecialType_BoostPad:
|
||||||
|
{
|
||||||
|
JumpPadAttributes* header = new JumpPadAttributes;
|
||||||
|
ParseObject(&buffer[counter], *header, counter);
|
||||||
|
|
||||||
|
ParseObject(&buffer[counter], header->direction, 16);
|
||||||
|
objects.push_back(header);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ObjectSpecialType_Portal:
|
||||||
|
{
|
||||||
|
PortalAttributes* header = new PortalAttributes;
|
||||||
|
ParseObject(&buffer[counter], *header, counter);
|
||||||
|
|
||||||
|
ParseObject(&buffer[counter], header->destination, 12);
|
||||||
|
objects.push_back(header);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ObjectSpecialType_SpawnPoint:
|
||||||
|
{
|
||||||
|
SpawnPointAttributes* header = new SpawnPointAttributes;
|
||||||
|
ParseObject(&buffer[counter], *header, counter);
|
||||||
|
|
||||||
|
ParseObject(&buffer[counter], header->spawnPosition, 12);
|
||||||
|
objects.push_back(header);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
//Couldn't find specialType
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ObjectType_Light:
|
||||||
|
{
|
||||||
|
LightType lightType;
|
||||||
|
|
||||||
|
//Get Light type
|
||||||
|
ParseObject(&buffer[counter+4], &lightType, sizeof(lightType));
|
||||||
|
|
||||||
|
//We only support PointLight for now.
|
||||||
|
BasicLight* header = new BasicLight;
|
||||||
|
ParseObject(&buffer[counter], header, sizeof(*header));
|
||||||
|
counter += sizeof(*header);
|
||||||
|
objects.push_back(header);
|
||||||
|
/*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:
|
default:
|
||||||
//Couldn't find typeID. FAIL!!!!!!
|
//Couldn't find typeID. FAIL!!!!!!
|
||||||
break;
|
break;
|
||||||
|
@ -82,30 +197,87 @@ LevelMetaData LevelParser::ParseHeader(std::string filename)
|
||||||
char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize);
|
char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize);
|
||||||
|
|
||||||
//Read format version
|
//Read format version
|
||||||
FormatVersion levelFormatVersion;
|
LevelLoaderInternal::FormatVersion levelFormatVersion;
|
||||||
//ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion));
|
ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion));
|
||||||
|
counter += sizeof(levelFormatVersion);
|
||||||
if(this->formatVersion != levelFormatVersion)
|
if(this->formatVersion != levelFormatVersion)
|
||||||
{
|
{
|
||||||
//Do something if it's not the same version
|
//Do something if it's not the same version
|
||||||
|
|
||||||
|
//Returns an empty levelHeader with ObjectType_Unknown.
|
||||||
|
//Because it will not be able to read another version of the level format.
|
||||||
|
return levelHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Find the header in the returned string.
|
//Find the header in the returned string.
|
||||||
while(counter < bufferSize)
|
while(counter < bufferSize)
|
||||||
{
|
{
|
||||||
ObjectTypeHeader typeID;
|
ObjectType typeID;
|
||||||
ParseObject(&buffer[counter], &typeID, sizeof(typeID));
|
ParseObject(&buffer[counter], &typeID, sizeof(typeID));
|
||||||
|
|
||||||
switch(typeID.typeID)
|
switch(typeID)
|
||||||
{
|
{
|
||||||
case ObjectType_LevelMetaData:
|
case ObjectType_LevelMetaData:
|
||||||
ParseLevelMetaData(&buffer[counter], levelHeader, counter);
|
ParseLevelMetaData(&buffer[counter], levelHeader, counter);
|
||||||
return levelHeader;
|
return levelHeader;
|
||||||
break;
|
break;
|
||||||
case ObjectType_Dynamic:
|
|
||||||
//Do not call parse this object, since we are only interested in the LevelMetaData
|
//This is by design, static and dynamic is using the same converter. Do not add anything inbetween them.
|
||||||
//Only increase the counter size
|
case ObjectType_Static: case ObjectType_Dynamic:
|
||||||
counter += sizeof(ObjectHeader);
|
{
|
||||||
|
ObjectHeader header;
|
||||||
|
ParseObject(&buffer[counter], header, counter);
|
||||||
|
|
||||||
|
switch(header.specialTypeID)
|
||||||
|
{
|
||||||
|
case ObjectSpecialType_JumpPad:
|
||||||
|
counter += sizeof(16);
|
||||||
break;
|
break;
|
||||||
|
case ObjectSpecialType_BoostPad:
|
||||||
|
counter += sizeof(16);
|
||||||
|
break;
|
||||||
|
case ObjectSpecialType_Portal:
|
||||||
|
counter += sizeof(12);
|
||||||
|
break;
|
||||||
|
case ObjectSpecialType_SpawnPoint:
|
||||||
|
counter += sizeof(12);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ObjectType_Light:
|
||||||
|
{
|
||||||
|
LightType lightType;
|
||||||
|
ParseObject(&buffer[counter+4], &lightType, sizeof(lightType));
|
||||||
|
|
||||||
|
//We only support pointlight for now.
|
||||||
|
counter += sizeof(BasicLight);
|
||||||
|
/*
|
||||||
|
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:
|
default:
|
||||||
//Couldn't find typeID. FAIL!!!!!!
|
//Couldn't find typeID. FAIL!!!!!!
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "ObjectDefines.h"
|
#include "ObjectDefines.h"
|
||||||
|
#include "../Misc/Utilities.h"
|
||||||
|
|
||||||
namespace GameLogic
|
namespace GameLogic
|
||||||
{
|
{
|
||||||
|
@ -16,13 +17,13 @@ namespace GameLogic
|
||||||
~LevelParser();
|
~LevelParser();
|
||||||
|
|
||||||
//
|
//
|
||||||
std::vector<ObjectTypeHeader> Parse(std::string filename);
|
std::vector<Utility::DynamicMemory::SmartPointer<ObjectTypeHeader>> Parse(std::string filename);
|
||||||
|
|
||||||
//
|
//
|
||||||
LevelMetaData ParseHeader(std::string filename);
|
LevelMetaData ParseHeader(std::string filename);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FormatVersion formatVersion;
|
LevelLoaderInternal::FormatVersion formatVersion;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,27 @@ namespace GameLogic
|
||||||
ObjectType_LevelMetaData,
|
ObjectType_LevelMetaData,
|
||||||
ObjectType_Static,
|
ObjectType_Static,
|
||||||
ObjectType_Dynamic,
|
ObjectType_Dynamic,
|
||||||
|
ObjectType_Light,
|
||||||
//Etc
|
//Etc
|
||||||
|
|
||||||
ObjectType_NUM_OF_TYPES,
|
ObjectType_NUM_OF_TYPES,
|
||||||
|
|
||||||
ObjectType_Unknown = -1,
|
ObjectType_Unknown = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ObjectSpecialType
|
||||||
|
{
|
||||||
|
ObjectSpecialType_World, //Always the main celestial body
|
||||||
|
ObjectSpecialType_Building,
|
||||||
|
ObjectSpecialType_Damaging,
|
||||||
|
ObjectSpecialType_Explosive,
|
||||||
|
ObjectSpecialType_JumpPad,
|
||||||
|
ObjectSpecialType_BoostPad,
|
||||||
|
ObjectSpecialType_Portal,
|
||||||
|
ObjectSpecialType_SpawnPoint,
|
||||||
|
|
||||||
|
ObjectSpecialType_Count,
|
||||||
|
ObjectSpecialType_Unknown = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum UsePhysics
|
enum UsePhysics
|
||||||
|
@ -27,9 +43,31 @@ namespace GameLogic
|
||||||
UsePhysics_UseFullPhysics,
|
UsePhysics_UseFullPhysics,
|
||||||
UsePhysics_IgnoreGravity,
|
UsePhysics_IgnoreGravity,
|
||||||
UsePhysics_IgnorePhysics,
|
UsePhysics_IgnorePhysics,
|
||||||
|
UsePhysics_IgnoreCollision,
|
||||||
|
|
||||||
UsePhysics_Count,
|
UsePhysics_Count,
|
||||||
UsePhysics_Unknown = -1,
|
UsePhysics_Unknown = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CollisionGeometryType
|
||||||
|
{
|
||||||
|
CollisionGeometryType_Box,
|
||||||
|
CollisionGeometryType_Sphere,
|
||||||
|
CollisionGeometryType_Cylinder,
|
||||||
|
|
||||||
|
CollisionGeometryType_Count,
|
||||||
|
CollisionGeometryType_Unknown = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
//Only supports Pointlight right now.
|
||||||
|
enum LightType
|
||||||
|
{
|
||||||
|
LightType_PointLight,
|
||||||
|
//LightType_DirectionalLight,
|
||||||
|
//LightType_SpotLight,
|
||||||
|
|
||||||
|
LightType_Count,
|
||||||
|
LightType_Unknown = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
//Should this be moved somewhere else?
|
//Should this be moved somewhere else?
|
||||||
|
@ -40,22 +78,43 @@ namespace GameLogic
|
||||||
//Etc
|
//Etc
|
||||||
|
|
||||||
GameMode_Count,
|
GameMode_Count,
|
||||||
GameMode_Unknown = -1,
|
GameMode_Unknown = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WorldSize
|
||||||
|
{
|
||||||
|
WorldSize_Tiny,
|
||||||
|
WorldSize_Small,
|
||||||
|
WorldSize_Medium,
|
||||||
|
WorldSize_Big,
|
||||||
|
WorldSize_Humongous,
|
||||||
|
|
||||||
|
WorldSize_Count,
|
||||||
|
WorldSize_Unknown = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
Structs
|
Structs
|
||||||
*************************************/
|
*************************************/
|
||||||
|
namespace LevelLoaderInternal
|
||||||
|
{
|
||||||
struct FormatVersion
|
struct FormatVersion
|
||||||
{
|
{
|
||||||
int formatVersionMajor;
|
unsigned int formatVersionMajor;
|
||||||
int formatVersionMinor;
|
unsigned int formatVersionMinor;
|
||||||
|
|
||||||
|
FormatVersion()
|
||||||
|
: formatVersionMajor(0), formatVersionMinor(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
FormatVersion(unsigned int major, unsigned int minor)
|
||||||
|
: formatVersionMajor(major), formatVersionMinor(minor)
|
||||||
|
{}
|
||||||
|
|
||||||
bool operator ==(const FormatVersion& obj)
|
bool operator ==(const FormatVersion& obj)
|
||||||
{
|
{
|
||||||
return (this->formatVersionMajor != obj.formatVersionMajor && this->formatVersionMinor != obj.formatVersionMinor);
|
return (this->formatVersionMajor == obj.formatVersionMajor && this->formatVersionMinor == obj.formatVersionMinor);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator !=(const FormatVersion& obj)
|
bool operator !=(const FormatVersion& obj)
|
||||||
|
@ -63,47 +122,150 @@ namespace GameLogic
|
||||||
return !(*this == obj);
|
return !(*this == obj);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
struct ObjectTypeHeader
|
struct ObjectTypeHeader
|
||||||
{
|
{
|
||||||
ObjectType typeID;
|
ObjectType typeID;
|
||||||
|
|
||||||
|
//Unless this is here the object destructor wont be called.
|
||||||
|
virtual ~ObjectTypeHeader(){}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace LevelLoaderInternal
|
||||||
|
{
|
||||||
|
const FormatVersion boundingVolumeVersion(1, 0);
|
||||||
|
|
||||||
|
struct BoundingVolumeBase
|
||||||
|
{
|
||||||
|
float position[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoundingVolumeBox : public BoundingVolumeBase
|
||||||
|
{
|
||||||
|
float size[3];
|
||||||
|
float angularAxis[3];
|
||||||
|
float angle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoundingVolumeSphere : public BoundingVolumeBase
|
||||||
|
{
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoundingVolumeCylinder : public BoundingVolumeBase
|
||||||
|
{
|
||||||
|
float length;
|
||||||
|
float angularAxis[3];
|
||||||
|
float angle;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoundingVolume
|
||||||
|
{
|
||||||
|
CollisionGeometryType geoType;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
LevelLoaderInternal::BoundingVolumeBox box;
|
||||||
|
LevelLoaderInternal::BoundingVolumeSphere sphere;
|
||||||
|
LevelLoaderInternal::BoundingVolumeCylinder cylinder;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PhysicsObject
|
struct PhysicsObject
|
||||||
{
|
{
|
||||||
|
UsePhysics usePhysics;
|
||||||
float mass;
|
float mass;
|
||||||
float elasticity;
|
float inertiaMagnitude[3];
|
||||||
|
float inertiaRotation[3];
|
||||||
float frictionCoeffStatic;
|
float frictionCoeffStatic;
|
||||||
float frictionCoeffDynamic;
|
float frictionCoeffDynamic;
|
||||||
float inertiaTensor[16];
|
float restitutionCoeff;
|
||||||
UsePhysics usePhysics;
|
BoundingVolume boundingVolume;
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
struct LevelMetaData : ObjectTypeHeader
|
struct LevelMetaData : public ObjectTypeHeader
|
||||||
{
|
{
|
||||||
std::string levelName;
|
std::string levelName;
|
||||||
FormatVersion levelVersion;
|
unsigned int levelVersion;
|
||||||
std::string levelDescription;
|
std::string levelDescription;
|
||||||
std::string levelAuthor;
|
std::string levelAuthor;
|
||||||
int maxNumberOfPlayer;
|
unsigned int maxNumberOfPlayer;
|
||||||
float worldSize;
|
WorldSize worldSize;
|
||||||
int overviewPictureID;
|
std::string overviewPicturePath;
|
||||||
std::vector<GameMode> gameModesSupported;
|
std::vector<GameMode> gameModesSupported;
|
||||||
|
|
||||||
|
virtual ~LevelMetaData(){}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObjectHeader : public ObjectTypeHeader
|
struct ObjectHeader : public ObjectTypeHeader, public LevelLoaderInternal::PhysicsObject
|
||||||
{
|
{
|
||||||
|
//Special type id for special objects: portal, jumppad, exploding objects, etc.
|
||||||
|
ObjectSpecialType specialTypeID;
|
||||||
//Model,
|
//Model,
|
||||||
int ModelID;
|
std::string ModelFile;
|
||||||
//Texture
|
|
||||||
int TextureID;
|
|
||||||
//Position
|
//Position
|
||||||
float position[3];
|
float position[3];
|
||||||
//Rotation
|
//Rotation
|
||||||
float rotation[3];
|
float rotation[3];
|
||||||
|
float angle;
|
||||||
//Scale
|
//Scale
|
||||||
float scale[3];
|
float scale[3];
|
||||||
|
|
||||||
|
virtual ~ObjectHeader(){}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
Special objects
|
||||||
|
*************************************/
|
||||||
|
|
||||||
|
struct JumpPadAttributes : public ObjectHeader
|
||||||
|
{
|
||||||
|
float direction[3];
|
||||||
|
float power;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PortalAttributes : public ObjectHeader
|
||||||
|
{
|
||||||
|
float destination[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpawnPointAttributes : public ObjectHeader
|
||||||
|
{
|
||||||
|
float spawnPosition[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
Lights
|
||||||
|
*************************************/
|
||||||
|
|
||||||
|
struct BasicLight : public ObjectTypeHeader
|
||||||
|
{
|
||||||
|
LightType lightType; //Is not used right now
|
||||||
|
float color[3];
|
||||||
|
float position[3];
|
||||||
|
float raduis;
|
||||||
|
float intensity;
|
||||||
|
};
|
||||||
|
/* We only support pointlight right now.
|
||||||
|
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
|
#endif
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "ParseFunctions.h"
|
#include "ParseFunctions.h"
|
||||||
#include "../../../Misc/Packing/Packing.h"
|
#include "../../../Misc/Packing/Packing.h"
|
||||||
|
#include "Loader.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using namespace Oyster::Packing;
|
using namespace Oyster::Packing;
|
||||||
|
@ -20,11 +21,46 @@ namespace GameLogic
|
||||||
memcpy(header, buffer, size);
|
memcpy(header, buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ParseObject(char* buffer, ObjectHeader& header, int& size)
|
||||||
|
{
|
||||||
|
char tempName[128];
|
||||||
|
unsigned int tempSize = 0;
|
||||||
|
int start = 0;
|
||||||
|
|
||||||
|
memcpy(&header.typeID, &buffer[start], 4);
|
||||||
|
start += 4;
|
||||||
|
|
||||||
|
memcpy(&header.specialTypeID, &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;
|
||||||
|
|
||||||
|
//The reset of the object struct
|
||||||
|
//3 float[3], 1 float
|
||||||
|
memcpy(&header.position, &buffer[start], 40);
|
||||||
|
start += 40;
|
||||||
|
|
||||||
|
//Physics struct
|
||||||
|
//2 float[3], 4 float, 1 uint
|
||||||
|
memcpy(&header.usePhysics, &buffer[start], 44);
|
||||||
|
start += 44;
|
||||||
|
|
||||||
|
//Read path for bounding volume
|
||||||
|
ParseBoundingVolume(&buffer[start], header.boundingVolume, start);
|
||||||
|
|
||||||
|
size += start;
|
||||||
|
}
|
||||||
|
|
||||||
void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size)
|
void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size)
|
||||||
{
|
{
|
||||||
int start = 0;
|
int start = 0;
|
||||||
int tempSize;
|
unsigned int tempSize;
|
||||||
char tempName[100];
|
char tempName[128];
|
||||||
|
|
||||||
memcpy(&header.typeID, &buffer[start], 4);
|
memcpy(&header.typeID, &buffer[start], 4);
|
||||||
start += 4;
|
start += 4;
|
||||||
|
@ -36,8 +72,8 @@ namespace GameLogic
|
||||||
header.levelName.assign(&tempName[0], &tempName[tempSize]);
|
header.levelName.assign(&tempName[0], &tempName[tempSize]);
|
||||||
start += tempSize;
|
start += tempSize;
|
||||||
|
|
||||||
memcpy(&header.levelVersion, &buffer[start], 8);
|
memcpy(&header.levelVersion, &buffer[start], 4);
|
||||||
start += 8;
|
start += 4;
|
||||||
|
|
||||||
memcpy(&tempSize, &buffer[start], 4);
|
memcpy(&tempSize, &buffer[start], 4);
|
||||||
start +=4;
|
start +=4;
|
||||||
|
@ -59,9 +95,13 @@ namespace GameLogic
|
||||||
memcpy(&header.worldSize, &buffer[start], 4);
|
memcpy(&header.worldSize, &buffer[start], 4);
|
||||||
start += 4;
|
start += 4;
|
||||||
|
|
||||||
memcpy(&header.overviewPictureID, &buffer[start], 4);
|
memcpy(&tempSize, &buffer[start], 4);
|
||||||
start += 4;
|
start += 4;
|
||||||
|
|
||||||
|
memcpy(&tempName, &buffer[start], tempSize);
|
||||||
|
header.overviewPicturePath.assign(&tempName[0], &tempName[tempSize]);
|
||||||
|
start += tempSize;
|
||||||
|
|
||||||
memcpy(&tempSize, &buffer[start], 4);
|
memcpy(&tempSize, &buffer[start], 4);
|
||||||
start += 4;
|
start += 4;
|
||||||
|
|
||||||
|
@ -76,5 +116,55 @@ namespace GameLogic
|
||||||
|
|
||||||
size += start;
|
size += start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ParseBoundingVolume(char* buffer, LevelLoaderInternal::BoundingVolume& volume, int &size)
|
||||||
|
{
|
||||||
|
int start = 0;
|
||||||
|
int tempSize = 0;
|
||||||
|
char tempName[128];
|
||||||
|
|
||||||
|
memcpy(&tempSize, &buffer[start], 4);
|
||||||
|
start += 4;
|
||||||
|
|
||||||
|
memcpy(&tempName, &buffer[start], tempSize);
|
||||||
|
|
||||||
|
string fileName;
|
||||||
|
fileName.assign(&tempName[0], &tempName[tempSize]);
|
||||||
|
start += tempSize;
|
||||||
|
|
||||||
|
//Läs in filen.
|
||||||
|
int fileLength = 0;
|
||||||
|
Loader loader;
|
||||||
|
char* buf = loader.LoadFile("E:\\Dropbox\\Programming\\Github\\Danbias\\Bin\\Content\\Worlds\\cgf\\"+ fileName, fileLength);
|
||||||
|
|
||||||
|
LevelLoaderInternal::FormatVersion version;
|
||||||
|
memcpy(&version, &buffer[0], sizeof(version));
|
||||||
|
|
||||||
|
memcpy(&volume.geoType, &buf[8], sizeof(volume.geoType));
|
||||||
|
//start += sizeof(volume.geoType);
|
||||||
|
|
||||||
|
switch(volume.geoType)
|
||||||
|
{
|
||||||
|
case CollisionGeometryType_Box:
|
||||||
|
memcpy(&volume.box, &buf[12], sizeof(volume.box));
|
||||||
|
//start += sizeof(volume.box);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CollisionGeometryType_Sphere:
|
||||||
|
memcpy(&volume.sphere, &buf[12], sizeof(volume.sphere));
|
||||||
|
//start += sizeof(volume.sphere);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CollisionGeometryType_Cylinder:
|
||||||
|
memcpy(&volume.cylinder, &buf[12], sizeof(volume.cylinder));
|
||||||
|
//start += sizeof(volume.cylinder);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
size += start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,8 +10,18 @@ namespace GameLogic
|
||||||
{
|
{
|
||||||
namespace LevelFileLoader
|
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, void *header, int size);
|
||||||
|
void ParseObject(char* buffer, ObjectHeader& header, int& size);
|
||||||
void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size);
|
void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size);
|
||||||
|
void ParseBoundingVolume(char* buffer, LevelLoaderInternal::BoundingVolume& volume, int &size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@ Object::Object()
|
||||||
|
|
||||||
this->type = OBJECT_TYPE::OBJECT_TYPE_UNKNOWN;
|
this->type = OBJECT_TYPE::OBJECT_TYPE_UNKNOWN;
|
||||||
this->objectID = GID();
|
this->objectID = GID();
|
||||||
this->getState = this->rigidBody->GetState();
|
this->currPhysicsState = this->rigidBody->GetState();
|
||||||
this->setState = this->getState;
|
this->newPhysicsState = this->currPhysicsState;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::Object(OBJECT_TYPE type)
|
Object::Object(OBJECT_TYPE type)
|
||||||
|
@ -34,8 +34,8 @@ Object::Object(OBJECT_TYPE type)
|
||||||
Oyster::Physics::API::Instance().AddObject(rigidBody);
|
Oyster::Physics::API::Instance().AddObject(rigidBody);
|
||||||
this->type = type;
|
this->type = type;
|
||||||
this->objectID = GID();
|
this->objectID = GID();
|
||||||
this->getState = this->rigidBody->GetState();
|
this->currPhysicsState = this->rigidBody->GetState();
|
||||||
this->setState = this->getState;
|
this->newPhysicsState = this->currPhysicsState;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::Object(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type)
|
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->rigidBody = rigidBody;
|
||||||
this->type = type;
|
this->type = type;
|
||||||
this->objectID = GID();
|
this->objectID = GID();
|
||||||
this->getState = this->rigidBody->GetState();
|
this->currPhysicsState = this->rigidBody->GetState();
|
||||||
this->setState = this->getState;
|
this->newPhysicsState = this->currPhysicsState;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::Object(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type)
|
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->type = type;
|
||||||
this->objectID = GID();
|
this->objectID = GID();
|
||||||
this->getState = this->rigidBody->GetState();
|
this->currPhysicsState = this->rigidBody->GetState();
|
||||||
this->setState = this->getState;
|
this->newPhysicsState = this->currPhysicsState;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::Object(Oyster::Physics::ICustomBody *rigidBody ,void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type)
|
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->type = type;
|
||||||
this->objectID = GID();
|
this->objectID = GID();
|
||||||
this->getState = this->rigidBody->GetState();
|
this->currPhysicsState = this->rigidBody->GetState();
|
||||||
this->setState = this->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)
|
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->type = type;
|
||||||
this->objectID = GID();
|
this->objectID = GID();
|
||||||
this->getState = this->rigidBody->GetState();
|
this->currPhysicsState = this->rigidBody->GetState();
|
||||||
this->setState = this->getState;
|
this->newPhysicsState = this->currPhysicsState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::ApplyLinearImpulse(Oyster::Math::Float3 force)
|
void Object::ApplyLinearImpulse(Oyster::Math::Float3 force)
|
||||||
{
|
{
|
||||||
setState.ApplyLinearImpulse(force);
|
newPhysicsState.ApplyLinearImpulse(force);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,19 +119,80 @@ Oyster::Physics::ICustomBody* Object::GetRigidBody()
|
||||||
void Object::BeginFrame()
|
void Object::BeginFrame()
|
||||||
{
|
{
|
||||||
|
|
||||||
this->rigidBody->SetState(this->setState);
|
|
||||||
|
|
||||||
|
if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum())
|
||||||
|
{
|
||||||
|
//error
|
||||||
|
int i =0 ;
|
||||||
|
}
|
||||||
|
if(currPhysicsState.GetCenterPosition() !=currPhysicsState.GetCenterPosition())
|
||||||
|
{
|
||||||
|
//error
|
||||||
|
int i =0 ;
|
||||||
|
}
|
||||||
|
if(currPhysicsState.GetAngularAxis() !=currPhysicsState.GetAngularAxis())
|
||||||
|
{
|
||||||
|
//error
|
||||||
|
int i =0 ;
|
||||||
|
}
|
||||||
|
this->rigidBody->SetState(this->newPhysicsState);
|
||||||
}
|
}
|
||||||
// update physic
|
// update physic
|
||||||
void Object::EndFrame()
|
void Object::EndFrame()
|
||||||
{
|
{
|
||||||
|
if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum())
|
||||||
|
{
|
||||||
|
//error
|
||||||
|
int i =0 ;
|
||||||
|
}
|
||||||
|
this->currPhysicsState = this->rigidBody->GetState();
|
||||||
|
if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum())
|
||||||
|
{
|
||||||
|
//error
|
||||||
|
int i =0 ;
|
||||||
|
}
|
||||||
|
if(currPhysicsState.GetGravityNormal() !=currPhysicsState.GetGravityNormal())
|
||||||
|
{
|
||||||
|
//error
|
||||||
|
int i =0 ;
|
||||||
|
}
|
||||||
|
|
||||||
Oyster::Math::Float4x4 rotMatrix = setState.GetOrientation(); //Oyster::Math3D::RotationMatrix(rot, axis);
|
|
||||||
//Oyster::Math3D::SnapAxisYToNormal_UsingNlerp(rotMatrix, -setState.GetGravityNormal());
|
|
||||||
//setState.SetOrientation(rotMatrix);
|
|
||||||
|
|
||||||
this->getState = this->rigidBody->GetState();
|
if(currPhysicsState.GetGravityNormal()!= Float3::null)
|
||||||
this->setState = this->getState;
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
Oyster::Math::Float3 pos = currPhysicsState.GetCenterPosition();
|
||||||
|
Oyster::Math::Float3 up = -currPhysicsState.GetGravityNormal();
|
||||||
|
//300, 0,0,
|
||||||
|
//1,0,0
|
||||||
|
|
||||||
|
if( pos.GetLength() < 303.5f)
|
||||||
|
{
|
||||||
|
Oyster::Math::Float moveUp = 303.5 - pos.GetLength();
|
||||||
|
up *= moveUp;
|
||||||
|
|
||||||
|
currPhysicsState.SetCenterPosition(pos + up);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum())
|
||||||
|
{
|
||||||
|
//error
|
||||||
|
int i =0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->newPhysicsState = this->currPhysicsState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::setBeforeCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter))
|
void Object::setBeforeCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter))
|
||||||
|
|
|
@ -35,24 +35,26 @@ namespace GameLogic
|
||||||
Oyster::Physics::ICustomBody* GetRigidBody();
|
Oyster::Physics::ICustomBody* GetRigidBody();
|
||||||
void ApplyLinearImpulse(Oyster::Math::Float3 force);
|
void ApplyLinearImpulse(Oyster::Math::Float3 force);
|
||||||
|
|
||||||
void BeginFrame();
|
virtual void BeginFrame();
|
||||||
void EndFrame();
|
virtual void EndFrame();
|
||||||
|
|
||||||
void setBeforeCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter));
|
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));
|
void setAfterCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss));
|
||||||
|
|
||||||
static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj);
|
static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj);
|
||||||
|
static Oyster::Physics::ICustomBody::SubscriptMessage DefaultCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
|
||||||
private:
|
private:
|
||||||
OBJECT_TYPE type;
|
OBJECT_TYPE type;
|
||||||
int objectID;
|
int objectID;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Oyster::Physics::ICustomBody *rigidBody;
|
Oyster::Physics::ICustomBody *rigidBody;
|
||||||
Oyster::Physics::ICustomBody::State setState;
|
Oyster::Physics::ICustomBody::State newPhysicsState;
|
||||||
Oyster::Physics::ICustomBody::State getState;
|
Oyster::Physics::ICustomBody::State currPhysicsState;
|
||||||
|
|
||||||
static const Game* gameInstance;
|
static const Game* gameInstance;
|
||||||
|
Oyster::Math::Float3 currLook;
|
||||||
|
Oyster::Math::Float3 newLook;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
using namespace GameLogic;
|
using namespace GameLogic;
|
||||||
using namespace Oyster::Physics;
|
using namespace Oyster::Physics;
|
||||||
|
const int MOVE_FORCE = 500;
|
||||||
Player::Player()
|
Player::Player()
|
||||||
:DynamicObject()
|
:DynamicObject()
|
||||||
{
|
{
|
||||||
|
@ -58,6 +58,26 @@ Player::~Player(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::BeginFrame()
|
||||||
|
{
|
||||||
|
weapon->Update(0.002f);
|
||||||
|
Object::BeginFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::EndFrame()
|
||||||
|
{
|
||||||
|
// snap to axis
|
||||||
|
Object::EndFrame();
|
||||||
|
// rotate
|
||||||
|
|
||||||
|
Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1];
|
||||||
|
Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ;
|
||||||
|
|
||||||
|
currPhysicsState.AddRotation(deltaAxis);
|
||||||
|
dx = 0;
|
||||||
|
this->newPhysicsState = this->currPhysicsState;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::Move(const PLAYER_MOVEMENT &movement)
|
void Player::Move(const PLAYER_MOVEMENT &movement)
|
||||||
{
|
{
|
||||||
switch(movement)
|
switch(movement)
|
||||||
|
@ -86,24 +106,32 @@ void Player::Move(const PLAYER_MOVEMENT &movement)
|
||||||
|
|
||||||
void Player::MoveForward()
|
void Player::MoveForward()
|
||||||
{
|
{
|
||||||
setState.ApplyLinearImpulse(this->lookDir * (20 * this->gameInstance->GetFrameTime()));
|
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
|
||||||
|
//Oyster::Math::Float3 forward = lookDir;
|
||||||
|
newPhysicsState.ApplyLinearImpulse(forward * (MOVE_FORCE * this->gameInstance->GetFrameTime()));
|
||||||
}
|
}
|
||||||
void Player::MoveBackwards()
|
void Player::MoveBackwards()
|
||||||
{
|
{
|
||||||
setState.ApplyLinearImpulse(-this->lookDir * 20 * this->gameInstance->GetFrameTime());
|
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
|
||||||
|
//Oyster::Math::Float3 forward = lookDir;
|
||||||
|
newPhysicsState.ApplyLinearImpulse(-forward * MOVE_FORCE * this->gameInstance->GetFrameTime());
|
||||||
}
|
}
|
||||||
void Player::MoveRight()
|
void Player::MoveRight()
|
||||||
{
|
{
|
||||||
//Do cross product with forward vector and negative gravity vector
|
//Do cross product with forward vector and negative gravity vector
|
||||||
Oyster::Math::Float3 r = (-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)this->lookDir);
|
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
|
||||||
setState.ApplyLinearImpulse(r * 20 * this->gameInstance->GetFrameTime());
|
//Oyster::Math::Float3 forward = lookDir;
|
||||||
|
Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward);
|
||||||
|
newPhysicsState.ApplyLinearImpulse(-r * MOVE_FORCE * this->gameInstance->GetFrameTime());
|
||||||
|
|
||||||
}
|
}
|
||||||
void Player::MoveLeft()
|
void Player::MoveLeft()
|
||||||
{
|
{
|
||||||
//Do cross product with forward vector and negative gravity vector
|
//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
|
Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2];
|
||||||
setState.ApplyLinearImpulse(-r * 20 * this->gameInstance->GetFrameTime());
|
//Oyster::Math::Float3 forward = lookDir;
|
||||||
|
Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); //Still get zero
|
||||||
|
newPhysicsState.ApplyLinearImpulse(r * MOVE_FORCE * this->gameInstance->GetFrameTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::UseWeapon(const WEAPON_FIRE &usage)
|
void Player::UseWeapon(const WEAPON_FIRE &usage)
|
||||||
|
@ -113,31 +141,28 @@ void Player::UseWeapon(const WEAPON_FIRE &usage)
|
||||||
|
|
||||||
void Player::Respawn(Oyster::Math::Float3 spawnPoint)
|
void Player::Respawn(Oyster::Math::Float3 spawnPoint)
|
||||||
{
|
{
|
||||||
|
|
||||||
this->life = 100;
|
this->life = 100;
|
||||||
this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE;
|
this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE;
|
||||||
this->lookDir = Oyster::Math::Float4(1,0,0);
|
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::Float4 up(0,1,0,0);//-setState.GetGravityNormal();
|
this->lookDir = lookDir.xyz;
|
||||||
Oyster::Math::Float4 pos = setState.GetCenterPosition();
|
this->dx = lookDir.w;
|
||||||
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;
|
|
||||||
|
|
||||||
//this->setState.AddRotation(Oyster::Math::Float4(x, y));
|
|
||||||
//this->setState.SetRotation();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::Jump()
|
void Player::Jump()
|
||||||
{
|
{
|
||||||
|
Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1];
|
||||||
|
newPhysicsState.ApplyLinearImpulse(up * MOVE_FORCE * this->gameInstance->GetFrameTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::IsWalking()
|
bool Player::IsWalking()
|
||||||
|
@ -155,11 +180,11 @@ bool Player::IsIdle()
|
||||||
|
|
||||||
Oyster::Math::Float3 Player::GetPosition() const
|
Oyster::Math::Float3 Player::GetPosition() const
|
||||||
{
|
{
|
||||||
return (Oyster::Math::Float3)getState.GetCenterPosition();
|
return (Oyster::Math::Float3)currPhysicsState.GetCenterPosition();
|
||||||
}
|
}
|
||||||
Oyster::Math::Float4x4 Player::GetOrientation() const
|
Oyster::Math::Float4x4 Player::GetOrientation() const
|
||||||
{
|
{
|
||||||
return this->getState.GetOrientation();
|
return this->currPhysicsState.GetOrientation();
|
||||||
}
|
}
|
||||||
Oyster::Math::Float3 Player::GetLookDir() const
|
Oyster::Math::Float3 Player::GetLookDir() const
|
||||||
{
|
{
|
||||||
|
@ -177,5 +202,13 @@ PLAYER_STATE Player::GetState() const
|
||||||
void Player::DamageLife(int damage)
|
void Player::DamageLife(int damage)
|
||||||
{
|
{
|
||||||
this->life -= 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 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
|
* Collision function for player, this is to be sent to physics through the subscribe function with the rigidbody
|
||||||
|
@ -71,6 +71,12 @@ namespace GameLogic
|
||||||
|
|
||||||
void DamageLife(int damage);
|
void DamageLife(int damage);
|
||||||
|
|
||||||
|
void BeginFrame();
|
||||||
|
void EndFrame();
|
||||||
|
static Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj);
|
||||||
|
static Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Jump();
|
void Jump();
|
||||||
|
|
||||||
|
@ -80,6 +86,7 @@ namespace GameLogic
|
||||||
Weapon *weapon;
|
Weapon *weapon;
|
||||||
PLAYER_STATE playerState;
|
PLAYER_STATE playerState;
|
||||||
Oyster::Math::Float3 lookDir;
|
Oyster::Math::Float3 lookDir;
|
||||||
|
Oyster::Math::Float dx;
|
||||||
|
|
||||||
bool hasTakenDamage;
|
bool hasTakenDamage;
|
||||||
float invincibleCooldown;
|
float invincibleCooldown;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "StaticObject.h"
|
#include "StaticObject.h"
|
||||||
|
#include "CollisionManager.h"
|
||||||
|
|
||||||
using namespace GameLogic;
|
using namespace GameLogic;
|
||||||
|
|
||||||
|
@ -17,7 +18,8 @@ StaticObject::StaticObject(OBJECT_TYPE type)
|
||||||
StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type)
|
StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type)
|
||||||
:Object(rigidBody,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)
|
StaticObject::StaticObject(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type)
|
||||||
|
|
|
@ -126,3 +126,8 @@ void Weapon::SelectAttatchment(int socketID)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Weapon::Update(float dt)
|
||||||
|
{
|
||||||
|
selectedAttatchment->Update(dt);
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ namespace GameLogic
|
||||||
~Weapon(void);
|
~Weapon(void);
|
||||||
|
|
||||||
void Use(const WEAPON_FIRE &usage, float dt);
|
void Use(const WEAPON_FIRE &usage, float dt);
|
||||||
|
void Update(float dt);
|
||||||
|
|
||||||
void AddNewAttatchment(IAttatchment *attatchment, Player *owner);
|
void AddNewAttatchment(IAttatchment *attatchment, Player *owner);
|
||||||
void SwitchAttatchment(IAttatchment *attatchment, int socketID, Player *owner);
|
void SwitchAttatchment(IAttatchment *attatchment, int socketID, Player *owner);
|
||||||
|
|
|
@ -69,6 +69,7 @@ namespace GameLogic
|
||||||
float lookDirX;
|
float lookDirX;
|
||||||
float lookDirY;
|
float lookDirY;
|
||||||
float lookDirZ;
|
float lookDirZ;
|
||||||
|
float deltaX;
|
||||||
|
|
||||||
Protocol_PlayerLook()
|
Protocol_PlayerLook()
|
||||||
{
|
{
|
||||||
|
@ -78,6 +79,7 @@ namespace GameLogic
|
||||||
this->protocol[1].type = Oyster::Network::NetAttributeType_Float;
|
this->protocol[1].type = Oyster::Network::NetAttributeType_Float;
|
||||||
this->protocol[2].type = Oyster::Network::NetAttributeType_Float;
|
this->protocol[2].type = Oyster::Network::NetAttributeType_Float;
|
||||||
this->protocol[3].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)
|
Protocol_PlayerLook(Oyster::Network::CustomNetProtocol& p)
|
||||||
|
@ -85,12 +87,14 @@ namespace GameLogic
|
||||||
lookDirX = p[1].value.netFloat;
|
lookDirX = p[1].value.netFloat;
|
||||||
lookDirY = p[2].value.netFloat;
|
lookDirY = p[2].value.netFloat;
|
||||||
lookDirZ = p[3].value.netFloat;
|
lookDirZ = p[3].value.netFloat;
|
||||||
|
deltaX = p[4].value.netFloat;
|
||||||
}
|
}
|
||||||
const Protocol_PlayerLook& operator=(Oyster::Network::CustomNetProtocol& val)
|
const Protocol_PlayerLook& operator=(Oyster::Network::CustomNetProtocol& val)
|
||||||
{
|
{
|
||||||
lookDirX = val[1].value.netFloat;
|
lookDirX = val[1].value.netFloat;
|
||||||
lookDirY = val[2].value.netFloat;
|
lookDirY = val[2].value.netFloat;
|
||||||
lookDirZ = val[3].value.netFloat;
|
lookDirZ = val[3].value.netFloat;
|
||||||
|
deltaX = val[4].value.netFloat;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -99,6 +103,8 @@ namespace GameLogic
|
||||||
this->protocol[1].value = lookDirX;
|
this->protocol[1].value = lookDirX;
|
||||||
this->protocol[2].value = lookDirY;
|
this->protocol[2].value = lookDirY;
|
||||||
this->protocol[3].value = lookDirZ;
|
this->protocol[3].value = lookDirZ;
|
||||||
|
this->protocol[4].value = deltaX;
|
||||||
|
|
||||||
|
|
||||||
return &protocol;
|
return &protocol;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +142,9 @@ namespace GameLogic
|
||||||
|
|
||||||
struct Protocol_PlayerShot :public Oyster::Network::CustomProtocolObject
|
struct Protocol_PlayerShot :public Oyster::Network::CustomProtocolObject
|
||||||
{
|
{
|
||||||
bool hasShot;
|
bool primaryPressed;
|
||||||
|
bool secondaryPressed;
|
||||||
|
bool utilityPressed;
|
||||||
|
|
||||||
Protocol_PlayerShot()
|
Protocol_PlayerShot()
|
||||||
{
|
{
|
||||||
|
@ -144,19 +152,27 @@ namespace GameLogic
|
||||||
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
|
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
|
||||||
|
|
||||||
this->protocol[1].type = Oyster::Network::NetAttributeType_Bool;
|
this->protocol[1].type = Oyster::Network::NetAttributeType_Bool;
|
||||||
|
this->protocol[2].type = Oyster::Network::NetAttributeType_Bool;
|
||||||
|
this->protocol[3].type = Oyster::Network::NetAttributeType_Bool;
|
||||||
}
|
}
|
||||||
Protocol_PlayerShot(Oyster::Network::CustomNetProtocol& p)
|
Protocol_PlayerShot(Oyster::Network::CustomNetProtocol& p)
|
||||||
{
|
{
|
||||||
hasShot = p[1].value.netBool;
|
primaryPressed = p[1].value.netBool;
|
||||||
|
secondaryPressed = p[2].value.netBool;
|
||||||
|
utilityPressed = p[3].value.netBool;
|
||||||
}
|
}
|
||||||
const Protocol_PlayerShot& operator=(Oyster::Network::CustomNetProtocol& val)
|
const Protocol_PlayerShot& operator=(Oyster::Network::CustomNetProtocol& val)
|
||||||
{
|
{
|
||||||
hasShot = val[1].value.netBool;
|
primaryPressed = val[1].value.netBool;
|
||||||
|
secondaryPressed = val[2].value.netBool;
|
||||||
|
utilityPressed = val[3].value.netBool;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Oyster::Network::CustomNetProtocol* GetProtocol() override
|
Oyster::Network::CustomNetProtocol* GetProtocol() override
|
||||||
{
|
{
|
||||||
this->protocol[1].value = hasShot;
|
this->protocol[1].value = primaryPressed;
|
||||||
|
this->protocol[2].value = secondaryPressed;
|
||||||
|
this->protocol[3].value = utilityPressed;
|
||||||
return &protocol;
|
return &protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,6 +200,9 @@
|
||||||
<ProjectReference Include="..\..\OysterMath\OysterMath.vcxproj">
|
<ProjectReference Include="..\..\OysterMath\OysterMath.vcxproj">
|
||||||
<Project>{f10cbc03-9809-4cba-95d8-327c287b18ee}</Project>
|
<Project>{f10cbc03-9809-4cba-95d8-327c287b18ee}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\GameLogic\GameLogic.vcxproj">
|
||||||
|
<Project>{b1195bb9-b3a5-47f0-906c-8dea384d1520}</Project>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
@ -86,12 +86,14 @@ namespace DanBias
|
||||||
if(dynamic_cast<IPlayerData*> (movedObject))
|
if(dynamic_cast<IPlayerData*> (movedObject))
|
||||||
{
|
{
|
||||||
IPlayerData* temp = (IPlayerData*)movedObject;
|
IPlayerData* temp = (IPlayerData*)movedObject;
|
||||||
temp->GetID();
|
|
||||||
|
int id = temp->GetID();
|
||||||
Oyster::Math::Float4x4 world = temp->GetOrientation();
|
Oyster::Math::Float4x4 world = temp->GetOrientation();
|
||||||
|
|
||||||
Protocol_ObjectPosition p(world, 2);
|
Protocol_ObjectPosition p(world, id);
|
||||||
GameSession::gameSession->Send(*p.GetProtocol());
|
GameSession::gameSession->Send(*p.GetProtocol());
|
||||||
}
|
}
|
||||||
|
|
||||||
GameLogic::IObjectData* obj = NULL;
|
GameLogic::IObjectData* obj = NULL;
|
||||||
if(dynamic_cast<GameLogic::ILevelData*>(movedObject))
|
if(dynamic_cast<GameLogic::ILevelData*>(movedObject))
|
||||||
{
|
{
|
||||||
|
@ -100,27 +102,31 @@ namespace DanBias
|
||||||
{
|
{
|
||||||
if(obj->GetObjectType() == OBJECT_TYPE_WORLD)
|
if(obj->GetObjectType() == OBJECT_TYPE_WORLD)
|
||||||
{
|
{
|
||||||
obj->GetID();
|
int id = obj->GetID();
|
||||||
Oyster::Math::Float4x4 world =obj->GetOrientation();
|
Oyster::Math::Float4x4 world =obj->GetOrientation();
|
||||||
|
|
||||||
Protocol_ObjectPosition p(world, 0);
|
Protocol_ObjectPosition p(world, id);
|
||||||
GameSession::gameSession->Send(*p.GetProtocol());
|
//GameSession::gameSession->Send(*p.GetProtocol());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(1);
|
int count = ((GameLogic::ILevelData*)movedObject)->getNrOfDynamicObj();
|
||||||
|
for( int i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(i+1);
|
||||||
if(obj)
|
if(obj)
|
||||||
{
|
{
|
||||||
if(obj->GetObjectType() == OBJECT_TYPE_BOX)
|
if(obj->GetObjectType() == OBJECT_TYPE_BOX)
|
||||||
{
|
{
|
||||||
obj->GetID();
|
int id = obj->GetID();
|
||||||
Oyster::Math::Float4x4 world = obj->GetOrientation();
|
Oyster::Math::Float4x4 world = obj->GetOrientation();
|
||||||
Protocol_ObjectPosition p(world, 1);
|
Protocol_ObjectPosition p(world, id);
|
||||||
GameSession::gameSession->Send(*p.GetProtocol());
|
GameSession::gameSession->Send(*p.GetProtocol());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,10 +176,11 @@ namespace DanBias
|
||||||
}
|
}
|
||||||
void GameSession::Gameplay_PlayerLookDir ( Protocol_PlayerLook& p, DanBias::GameClient* c )
|
void GameSession::Gameplay_PlayerLookDir ( Protocol_PlayerLook& p, DanBias::GameClient* c )
|
||||||
{
|
{
|
||||||
Oyster::Math3D::Float3 lookDir;
|
Oyster::Math3D::Float4 lookDir;
|
||||||
lookDir.x = p.lookDirX;
|
lookDir.x = p.lookDirX;
|
||||||
lookDir.y = p.lookDirY;
|
lookDir.y = p.lookDirY;
|
||||||
lookDir.z = p.lookDirZ;
|
lookDir.z = p.lookDirZ;
|
||||||
|
lookDir.w = p.deltaX;
|
||||||
c->GetPlayer()->Rotate(lookDir);
|
c->GetPlayer()->Rotate(lookDir);
|
||||||
}
|
}
|
||||||
void GameSession::Gameplay_PlayerChangeWeapon ( Protocol_PlayerChangeWeapon& p, DanBias::GameClient* c )
|
void GameSession::Gameplay_PlayerChangeWeapon ( Protocol_PlayerChangeWeapon& p, DanBias::GameClient* c )
|
||||||
|
@ -182,7 +189,10 @@ namespace DanBias
|
||||||
}
|
}
|
||||||
void GameSession::Gameplay_PlayerShot ( Protocol_PlayerShot& p, DanBias::GameClient* c )
|
void GameSession::Gameplay_PlayerShot ( Protocol_PlayerShot& p, DanBias::GameClient* c )
|
||||||
{
|
{
|
||||||
c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS);
|
if(p.secondaryPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_SECONDARY_PRESS);
|
||||||
|
if(p.primaryPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS);
|
||||||
|
|
||||||
|
if(p.utilityPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_UTILLITY_PRESS);
|
||||||
}
|
}
|
||||||
void GameSession::Gameplay_PlayerJump ( Protocol_PlayerJump& p, DanBias::GameClient* c )
|
void GameSession::Gameplay_PlayerJump ( Protocol_PlayerJump& p, DanBias::GameClient* c )
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,7 +57,7 @@ int WINAPI WinMain( HINSTANCE hinst, HINSTANCE prevInst, PSTR cmdLine, int cmdSh
|
||||||
return cmdShow;
|
return cmdShow;
|
||||||
}
|
}
|
||||||
|
|
||||||
serverThread = std::thread(ServerFnc);
|
//serverThread = std::thread(ServerFnc);
|
||||||
|
|
||||||
Sleep(200);
|
Sleep(200);
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef)
|
||||||
data.next = NULL;
|
data.next = NULL;
|
||||||
data.prev = NULL;
|
data.prev = NULL;
|
||||||
data.customBodyRef = customBodyRef;
|
data.customBodyRef = customBodyRef;
|
||||||
|
data.limbo = false;
|
||||||
this->mapReferences.insert(std::pair <ICustomBody*, unsigned int> (data.customBodyRef, this->leafData.size()));
|
this->mapReferences.insert(std::pair <ICustomBody*, unsigned int> (data.customBodyRef, this->leafData.size()));
|
||||||
this->leafData.push_back(data);
|
this->leafData.push_back(data);
|
||||||
|
|
||||||
|
@ -64,6 +65,33 @@ void Octree::MoveToUpdateQueue(UniquePointer< ICustomBody > customBodyRef)
|
||||||
this->updateQueue.push_back(&this->leafData[this->mapReferences[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)
|
void Octree::DestroyObject(UniquePointer< ICustomBody > customBodyRef)
|
||||||
{
|
{
|
||||||
std::map<const ICustomBody*, unsigned int>::iterator it = this->mapReferences.find(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++)
|
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);
|
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++)
|
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);
|
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++)
|
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);
|
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++)
|
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 );
|
hitAction( this->GetCustomBody(i), args );
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ namespace Oyster
|
||||||
|
|
||||||
::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef;
|
::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef;
|
||||||
|
|
||||||
|
bool limbo;
|
||||||
|
|
||||||
unsigned int queueRef;
|
unsigned int queueRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,6 +50,10 @@ namespace Oyster
|
||||||
|
|
||||||
void MoveToUpdateQueue(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
|
void MoveToUpdateQueue(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
|
||||||
|
|
||||||
|
void MoveToLimbo(const ICustomBody* customBodyRef);
|
||||||
|
bool IsInLimbo(const ICustomBody* customBodyRef);
|
||||||
|
void ReleaseFromLimbo(const ICustomBody* customBodyRef);
|
||||||
|
|
||||||
void DestroyObject(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
|
void DestroyObject(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
|
||||||
|
|
||||||
std::vector<ICustomBody*>& Sample(ICustomBody* customBodyRef, std::vector<ICustomBody*>& updateList);
|
std::vector<ICustomBody*>& Sample(ICustomBody* customBodyRef, std::vector<ICustomBody*>& updateList);
|
||||||
|
@ -66,6 +72,7 @@ namespace Oyster
|
||||||
private:
|
private:
|
||||||
std::vector < Data > leafData;
|
std::vector < Data > leafData;
|
||||||
std::vector < Data* > updateQueue;
|
std::vector < Data* > updateQueue;
|
||||||
|
std::vector < Data* > limbo;
|
||||||
|
|
||||||
std::map< const ICustomBody*, unsigned int > mapReferences;
|
std::map< const ICustomBody*, unsigned int > mapReferences;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ API_Impl API_instance;
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
void OnPossibleCollision( Octree& worldScene, unsigned int protoTempRef, unsigned int deuterTempRef )
|
void OnPossibleCollision( Octree& worldScene, unsigned int protoTempRef, unsigned int deuterTempRef )
|
||||||
{ /** @todo TODO: OnPossibleCollision is a temporary solution .*/
|
{
|
||||||
auto proto = worldScene.GetCustomBody( protoTempRef );
|
auto proto = worldScene.GetCustomBody( protoTempRef );
|
||||||
auto deuter = worldScene.GetCustomBody( deuterTempRef );
|
auto deuter = worldScene.GetCustomBody( deuterTempRef );
|
||||||
|
|
||||||
|
@ -26,11 +26,41 @@ namespace
|
||||||
ICustomBody::State protoState; proto->GetState( protoState );
|
ICustomBody::State protoState; proto->GetState( protoState );
|
||||||
ICustomBody::State deuterState; deuter->GetState( deuterState );
|
ICustomBody::State deuterState; deuter->GetState( deuterState );
|
||||||
|
|
||||||
Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact.xyz ),
|
// calc from perspective of deuter.
|
||||||
deuterG = deuterState.GetLinearMomentum( worldPointOfContact.xyz );
|
Float4 normal = (worldPointOfContact - Float4(deuterState.GetCenterPosition(), 1.0f )).GetNormalized(); // Init value is only borrowed
|
||||||
|
if( normal.Dot(normal) > 0.0f )
|
||||||
|
{
|
||||||
|
deuter->GetNormalAt( worldPointOfContact, normal );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // special case: deuter is completly contained within proto or they have overlapping centers.
|
||||||
|
|
||||||
|
normal = Float4( protoState.GetCenterPosition() - deuterState.GetCenterPosition(), 0.0f );
|
||||||
|
if( normal.Dot(normal) == 0.0f )
|
||||||
|
{ // they have overlapping centers. Rebound at least
|
||||||
|
// calculate and store time interpolation value, for later rebound.
|
||||||
|
proto->SetTimeOfContact( worldPointOfContact );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// borrowing the negated normal of proto.
|
||||||
|
proto->GetNormalAt( worldPointOfContact, normal );
|
||||||
|
normal = -normal;
|
||||||
|
}
|
||||||
|
normal.Normalize();
|
||||||
|
|
||||||
|
Float4 protoG = Float4(protoState.GetLinearMomentum( worldPointOfContact.xyz ), 0),
|
||||||
|
deuterG = Float4(deuterState.GetLinearMomentum( worldPointOfContact.xyz ), 0);
|
||||||
|
|
||||||
|
if( normal != normal ) // debug: trap
|
||||||
|
const char *breakpoint = "This should never happen";
|
||||||
|
|
||||||
|
if( protoG != protoG ) // debug: trap
|
||||||
|
const char *breakpoint = "This should never happen";
|
||||||
|
|
||||||
|
if( deuterG != deuterG ) // debug: trap
|
||||||
|
const char *breakpoint = "This should never happen";
|
||||||
|
|
||||||
// calc from perspective of deuter
|
|
||||||
Float4 normal; deuter->GetNormalAt( worldPointOfContact, normal );
|
|
||||||
Float protoG_Magnitude = protoG.Dot( normal ),
|
Float protoG_Magnitude = protoG.Dot( normal ),
|
||||||
deuterG_Magnitude = deuterG.Dot( normal );
|
deuterG_Magnitude = deuterG.Dot( normal );
|
||||||
|
|
||||||
|
@ -60,6 +90,20 @@ namespace
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PLayerHAck
|
||||||
|
if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_player_collision_response )
|
||||||
|
{
|
||||||
|
Float3 linearMomentum = protoState.GetLinearMomentum();
|
||||||
|
Float3 up = -protoState.GetGravityNormal();
|
||||||
|
Float3 upForce = (linearMomentum.Dot(up) * up);
|
||||||
|
|
||||||
|
Float3 noBounceForce = linearMomentum - upForce;
|
||||||
|
protoState.SetLinearMomentum(noBounceForce);
|
||||||
|
proto->SetState(protoState);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// calculate and store time interpolation value, for later rebound.
|
||||||
|
proto->SetTimeOfContact( worldPointOfContact );
|
||||||
|
|
||||||
// bounce
|
// bounce
|
||||||
Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(),
|
Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(),
|
||||||
|
@ -68,9 +112,25 @@ namespace
|
||||||
|
|
||||||
|
|
||||||
// calc from perspective of proto
|
// calc from perspective of proto
|
||||||
|
|
||||||
|
normal = (worldPointOfContact - Float4(protoState.GetCenterPosition(), 1.0f )).GetNormalized();
|
||||||
|
if( normal.Dot(normal) > 0.0f )
|
||||||
|
{
|
||||||
proto->GetNormalAt( worldPointOfContact, normal );
|
proto->GetNormalAt( worldPointOfContact, normal );
|
||||||
protoG_Magnitude = protoG.Dot( normal ),
|
protoG_Magnitude = protoG.Dot( normal );
|
||||||
deuterG_Magnitude = deuterG.Dot( normal );
|
deuterG_Magnitude = deuterG.Dot( normal );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // special case: proto is completly contained within deuter.
|
||||||
|
// borrowing the negated normal of deuter.
|
||||||
|
deuter->GetNormalAt( worldPointOfContact, normal );
|
||||||
|
normal = -normal;
|
||||||
|
protoG_Magnitude = -protoG_Magnitude;
|
||||||
|
deuterG_Magnitude = -deuterG_Magnitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( normal != normal ) // debug: trap
|
||||||
|
const char *breakpoint = "This should never happen";
|
||||||
|
|
||||||
// bounce
|
// bounce
|
||||||
Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(),
|
Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(),
|
||||||
|
@ -79,9 +139,13 @@ namespace
|
||||||
|
|
||||||
Float4 bounce = Average( bounceD, bounceP );
|
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() );
|
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 );
|
proto->SetState( protoState );
|
||||||
|
|
||||||
Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() );
|
Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() );
|
||||||
|
@ -184,10 +248,13 @@ void API_Impl::Update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( gravityImpulse != gravityImpulse ) // debug: trap
|
||||||
|
const char *breakpoint = "This should never happen";
|
||||||
|
|
||||||
if( gravityImpulse != Float4::null )
|
if( gravityImpulse != Float4::null )
|
||||||
{
|
{
|
||||||
state.ApplyLinearImpulse( gravityImpulse.xyz );
|
state.ApplyLinearImpulse( gravityImpulse.xyz );
|
||||||
(*proto)->SetGravityNormal( gravityImpulse.GetNormalized().xyz );
|
state.SetGravityNormal( gravityImpulse.GetNormalized().xyz );
|
||||||
(*proto)->SetState( state );
|
(*proto)->SetState( state );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,24 +265,27 @@ void API_Impl::Update()
|
||||||
proto = updateList.begin();
|
proto = updateList.begin();
|
||||||
for( ; proto != updateList.end(); ++proto )
|
for( ; proto != updateList.end(); ++proto )
|
||||||
{
|
{
|
||||||
Float3 lM = state.GetLinearMomentum() + state.GetLinearImpulse();
|
(*proto)->GetState( state );
|
||||||
|
Float3 lM = state.GetLinearMomentum();
|
||||||
|
|
||||||
if( lM.x < this->epsilon )
|
//LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp(state.SetOrientation(, Float4(state.GetGravityNormal(), 0.0f), 1.0f);
|
||||||
|
|
||||||
|
|
||||||
|
if( abs(lM.x) < this->epsilon )
|
||||||
{
|
{
|
||||||
state.SetLinearMomentum( Float3(0, lM.y, lM.z) );
|
state.linearMomentum.x = 0;
|
||||||
state.SetLinearImpulse( Float3(0, lM.y, lM.z) );
|
|
||||||
}
|
}
|
||||||
if( lM.y < this->epsilon )
|
if( abs(lM.y) < this->epsilon )
|
||||||
{
|
{
|
||||||
state.SetLinearMomentum( Float3(lM.x, 0, lM.z) );
|
state.linearMomentum.y = 0;
|
||||||
state.SetLinearImpulse( Float3(lM.x, 0, lM.z) );
|
|
||||||
}
|
}
|
||||||
if( lM.z < this->epsilon )
|
if( abs(lM.z) < this->epsilon )
|
||||||
{
|
{
|
||||||
state.SetLinearMomentum( Float3(lM.x, lM.y, 0) );
|
state.linearMomentum.z = 0;
|
||||||
state.SetLinearImpulse( Float3(lM.x, lM.y, 0) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(*proto)->SetState( state );
|
||||||
|
|
||||||
switch( (*proto)->Update(this->updateFrameLength) )
|
switch( (*proto)->Update(this->updateFrameLength) )
|
||||||
{
|
{
|
||||||
case UpdateState_altered:
|
case UpdateState_altered:
|
||||||
|
@ -230,17 +300,16 @@ void API_Impl::Update()
|
||||||
|
|
||||||
bool API_Impl::IsInLimbo( const ICustomBody* objRef )
|
bool API_Impl::IsInLimbo( const ICustomBody* objRef )
|
||||||
{
|
{
|
||||||
//! @todo TODO: implement stub
|
return this->worldScene.IsInLimbo( objRef );
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::MoveToLimbo( const ICustomBody* objRef )
|
void API_Impl::MoveToLimbo( const ICustomBody* objRef )
|
||||||
{
|
{
|
||||||
/** @todo TODO: Fix this function.*/
|
this->worldScene.MoveToLimbo( objRef );
|
||||||
}
|
}
|
||||||
void API_Impl::ReleaseFromLimbo( const ICustomBody* 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 )
|
void API_Impl::AddObject( ::Utility::DynamicMemory::UniquePointer<ICustomBody> handle )
|
||||||
|
|
|
@ -49,6 +49,12 @@ SimpleRigidBody::SimpleRigidBody()
|
||||||
this->onCollision = Default::EventAction_BeforeCollisionResponse;
|
this->onCollision = Default::EventAction_BeforeCollisionResponse;
|
||||||
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
|
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
|
||||||
this->onMovement = Default::EventAction_Move;
|
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->scene = nullptr;
|
||||||
this->customTag = nullptr;
|
this->customTag = nullptr;
|
||||||
this->ignoreGravity = this->isForwarded = false;
|
this->ignoreGravity = this->isForwarded = false;
|
||||||
|
@ -56,9 +62,13 @@ SimpleRigidBody::SimpleRigidBody()
|
||||||
|
|
||||||
SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
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.centerPos = desc.centerPosition;
|
||||||
this->rigid.SetSize( desc.size );
|
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.SetMass_KeepMomentum( desc.mass );
|
||||||
this->rigid.SetMomentOfInertia_KeepMomentum( desc.inertiaTensor );
|
this->rigid.SetMomentOfInertia_KeepMomentum( desc.inertiaTensor );
|
||||||
this->deltaPos = Float4::null;
|
this->deltaPos = Float4::null;
|
||||||
|
@ -66,6 +76,11 @@ SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc )
|
||||||
|
|
||||||
this->gravityNormal = Float3::null;
|
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 )
|
if( desc.subscription_onCollision )
|
||||||
{
|
{
|
||||||
this->onCollision = desc.subscription_onCollision;
|
this->onCollision = desc.subscription_onCollision;
|
||||||
|
@ -128,7 +143,7 @@ SimpleRigidBody::State & SimpleRigidBody::GetState( SimpleRigidBody::State &targ
|
||||||
void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
|
void SimpleRigidBody::SetState( const SimpleRigidBody::State &state )
|
||||||
{
|
{
|
||||||
this->rigid.centerPos = state.GetCenterPosition();
|
this->rigid.centerPos = state.GetCenterPosition();
|
||||||
//this->rigid.SetRotation( state.GetRotation() ); //! HACK: @todo Rotation temporary disabled
|
this->rigid.axis = state.GetAngularAxis();
|
||||||
this->rigid.boundingReach = state.GetReach();
|
this->rigid.boundingReach = state.GetReach();
|
||||||
this->rigid.momentum_Linear = state.GetLinearMomentum();
|
this->rigid.momentum_Linear = state.GetLinearMomentum();
|
||||||
this->rigid.momentum_Angular = state.GetAngularMomentum();
|
this->rigid.momentum_Angular = state.GetAngularMomentum();
|
||||||
|
@ -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 );
|
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
|
Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.GetMagnitude() );
|
return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.GetMagnitude() );
|
||||||
|
@ -290,21 +325,50 @@ void * SimpleRigidBody::GetCustomTag() const
|
||||||
// return this->rigid.GetLinearVelocity();
|
// return this->rigid.GetLinearVelocity();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
UpdateState SimpleRigidBody::Update( Float timeStepLength )
|
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 );
|
||||||
|
timeStepLength *= 2.0f - this->collisionRebound.timeOfContact; // compensate for rebounded time
|
||||||
|
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 );
|
unsigned char resting = 0;
|
||||||
this->deltaPos = Float4::null;
|
if( this->rigid.momentum_Linear.Dot(this->rigid.momentum_Linear) <= (Constant::epsilon * Constant::epsilon) )
|
||||||
this->deltaAxis = Float4::null;
|
{
|
||||||
this->isForwarded = false;
|
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 );
|
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;
|
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 ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Intersects( const ICustomBody &object, ::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::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::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;
|
::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::Physics3D::RigidBody rigid;
|
||||||
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
||||||
::Oyster::Math::Float3 gravityNormal;
|
::Oyster::Math::Float3 gravityNormal;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct { ::Oyster::Math::Float3 center, axis, reach; } previousSpatial;
|
||||||
|
::Oyster::Math::Float timeOfContact;
|
||||||
|
} collisionRebound;
|
||||||
|
|
||||||
EventAction_BeforeCollisionResponse onCollision;
|
EventAction_BeforeCollisionResponse onCollision;
|
||||||
EventAction_AfterCollisionResponse onCollisionResponse;
|
EventAction_AfterCollisionResponse onCollisionResponse;
|
||||||
EventAction_Move onMovement;
|
EventAction_Move onMovement;
|
||||||
|
|
||||||
Octree *scene;
|
Octree *scene;
|
||||||
void *customTag;
|
void *customTag;
|
||||||
bool ignoreGravity, isForwarded;
|
bool ignoreGravity, isForwarded;
|
||||||
|
|
|
@ -11,11 +11,17 @@ using namespace ::Utility::Value;
|
||||||
SphericalRigidBody::SphericalRigidBody()
|
SphericalRigidBody::SphericalRigidBody()
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody();
|
this->rigid = RigidBody();
|
||||||
this->rigid.SetMass_KeepMomentum( 10.0f );
|
this->rigid.SetMass_KeepMomentum( 16.0f );
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
this->onCollision = Default::EventAction_BeforeCollisionResponse;
|
this->onCollision = Default::EventAction_BeforeCollisionResponse;
|
||||||
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
|
this->onCollisionResponse = Default::EventAction_AfterCollisionResponse;
|
||||||
this->onMovement = Default::EventAction_Move;
|
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->scene = nullptr;
|
||||||
this->customTag = nullptr;
|
this->customTag = nullptr;
|
||||||
this->ignoreGravity = this->isForwarded = false;
|
this->ignoreGravity = this->isForwarded = false;
|
||||||
|
@ -24,9 +30,12 @@ SphericalRigidBody::SphericalRigidBody()
|
||||||
SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc )
|
SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc )
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody();
|
this->rigid = RigidBody();
|
||||||
//this->rigid.SetRotation( desc.rotation );
|
this->rigid.SetRotation( desc.rotation );
|
||||||
this->rigid.centerPos = desc.centerPosition;
|
this->rigid.centerPos = desc.centerPosition;
|
||||||
this->rigid.boundingReach = Float4( desc.radius, desc.radius, desc.radius, 0.0f );
|
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.SetMass_KeepMomentum( desc.mass );
|
||||||
this->rigid.SetMomentOfInertia_KeepMomentum( MomentOfInertia::Sphere(desc.mass, desc.radius) );
|
this->rigid.SetMomentOfInertia_KeepMomentum( MomentOfInertia::Sphere(desc.mass, desc.radius) );
|
||||||
this->deltaPos = Float4::null;
|
this->deltaPos = Float4::null;
|
||||||
|
@ -34,6 +43,11 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des
|
||||||
|
|
||||||
this->gravityNormal = Float3::null;
|
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 )
|
if( desc.subscription_onCollision )
|
||||||
{
|
{
|
||||||
this->onCollision = desc.subscription_onCollision;
|
this->onCollision = desc.subscription_onCollision;
|
||||||
|
@ -64,6 +78,11 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des
|
||||||
this->scene = nullptr;
|
this->scene = nullptr;
|
||||||
this->customTag = nullptr;
|
this->customTag = nullptr;
|
||||||
this->ignoreGravity = desc.ignoreGravity;
|
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() {}
|
SphericalRigidBody::~SphericalRigidBody() {}
|
||||||
|
@ -94,7 +113,7 @@ SphericalRigidBody::State & SphericalRigidBody::GetState( SphericalRigidBody::St
|
||||||
void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
|
void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
|
||||||
{
|
{
|
||||||
this->rigid.centerPos = state.GetCenterPosition();
|
this->rigid.centerPos = state.GetCenterPosition();
|
||||||
//this->rigid.SetRotation( state.GetRotation() ); //! HACK: @todo Rotation temporary disabled
|
this->rigid.axis = state.GetAngularAxis();
|
||||||
this->rigid.boundingReach = state.GetReach();
|
this->rigid.boundingReach = state.GetReach();
|
||||||
this->rigid.momentum_Linear = state.GetLinearMomentum();
|
this->rigid.momentum_Linear = state.GetLinearMomentum();
|
||||||
this->rigid.momentum_Angular = state.GetAngularMomentum();
|
this->rigid.momentum_Angular = state.GetAngularMomentum();
|
||||||
|
@ -105,6 +124,7 @@ void SphericalRigidBody::SetState( const SphericalRigidBody::State &state )
|
||||||
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
|
this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic();
|
||||||
this->rigid.SetMass_KeepMomentum( state.GetMass() );
|
this->rigid.SetMass_KeepMomentum( state.GetMass() );
|
||||||
this->rigid.SetMomentOfInertia_KeepMomentum( state.GetMomentOfInertia() );
|
this->rigid.SetMomentOfInertia_KeepMomentum( state.GetMomentOfInertia() );
|
||||||
|
this->rigid.gravityNormal = state.GetGravityNormal();
|
||||||
|
|
||||||
if( state.IsForwarded() )
|
if( state.IsForwarded() )
|
||||||
{
|
{
|
||||||
|
@ -164,6 +184,17 @@ bool SphericalRigidBody::Intersects( const ICustomBody &object, Float4 &worldPoi
|
||||||
return object.Intersects( Sphere(this->rigid.centerPos, this->rigid.boundingReach.x), worldPointOfContact );
|
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
|
Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.x );
|
return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.x );
|
||||||
|
@ -218,18 +249,48 @@ void * SphericalRigidBody::GetCustomTag() const
|
||||||
|
|
||||||
UpdateState SphericalRigidBody::Update( Float timeStepLength )
|
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 );
|
||||||
|
timeStepLength *= 2.0f - this->collisionRebound.timeOfContact; // compensate for rebounded time
|
||||||
|
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 );
|
unsigned char resting = 0;
|
||||||
this->deltaPos = Float4::null;
|
if( this->rigid.momentum_Linear.Dot(this->rigid.momentum_Linear) <= (Constant::epsilon * Constant::epsilon) )
|
||||||
this->deltaAxis = Float4::null;
|
{
|
||||||
this->isForwarded = false;
|
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 );
|
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;
|
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 ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Intersects( const ICustomBody &object, ::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::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::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;
|
::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::Physics3D::RigidBody rigid;
|
||||||
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
::Oyster::Math::Float4 deltaPos, deltaAxis;
|
||||||
::Oyster::Math::Float3 gravityNormal;
|
::Oyster::Math::Float3 gravityNormal;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct { ::Oyster::Math::Float3 center, axis, reach; } previousSpatial;
|
||||||
|
::Oyster::Math::Float timeOfContact;
|
||||||
|
} collisionRebound;
|
||||||
|
|
||||||
EventAction_BeforeCollisionResponse onCollision;
|
EventAction_BeforeCollisionResponse onCollision;
|
||||||
EventAction_AfterCollisionResponse onCollisionResponse;
|
EventAction_AfterCollisionResponse onCollisionResponse;
|
||||||
EventAction_Move onMovement;
|
EventAction_Move onMovement;
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace Oyster
|
||||||
namespace Constant
|
namespace Constant
|
||||||
{
|
{
|
||||||
const float gravity_constant = (const float)6.67284e-11; //!< The _big_G_! ( N(m/kg)^2 ) Used in real gravityforcefields.
|
const float gravity_constant = (const float)6.67284e-11; //!< The _big_G_! ( N(m/kg)^2 ) Used in real gravityforcefields.
|
||||||
const float epsilon = (const float)1.0e-7;
|
const float epsilon = (const float)1.0e-3;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PHYSICS_DLL_USAGE API
|
class PHYSICS_DLL_USAGE API
|
||||||
|
@ -242,7 +242,8 @@ namespace Oyster
|
||||||
{
|
{
|
||||||
SubscriptMessage_none,
|
SubscriptMessage_none,
|
||||||
SubscriptMessage_kineticLoss,
|
SubscriptMessage_kineticLoss,
|
||||||
SubscriptMessage_ignore_collision_response
|
SubscriptMessage_ignore_collision_response,
|
||||||
|
SubscriptMessage_player_collision_response
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SubscriptMessage (*EventAction_BeforeCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter );
|
typedef SubscriptMessage (*EventAction_BeforeCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter );
|
||||||
|
@ -322,6 +323,11 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
|
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.
|
* Required by Engine's Collision Search.
|
||||||
* @param targetMem: Provided memory that written into and then returned.
|
* @param targetMem: Provided memory that written into and then returned.
|
||||||
|
|
|
@ -49,6 +49,9 @@ namespace Oyster { namespace Physics { namespace Formula
|
||||||
::Oyster::Math::Float4 relativeMomentum = momB - momA;
|
::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();
|
tanFriction.Normalize();
|
||||||
|
|
||||||
::Oyster::Math::Float magnitudeFriction = -relativeMomentum.Dot( tanFriction );
|
::Oyster::Math::Float magnitudeFriction = -relativeMomentum.Dot( tanFriction );
|
||||||
|
@ -64,11 +67,14 @@ namespace Oyster { namespace Physics { namespace Formula
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
::Oyster::Math::Float dynamicFriction = 0.5f * ( dFA + dFB );
|
::Oyster::Math::Float dynamicFriction = 0.5f * ( dFA + dFB );
|
||||||
frictionImpulse = -i*tanFriction*dynamicFriction;
|
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()
|
inline SimpleBodyDescription::SimpleBodyDescription()
|
||||||
{
|
{
|
||||||
this->rotation = ::Oyster::Math::Float4x4::identity;
|
this->rotation = ::Oyster::Math::Float3::null;
|
||||||
this->centerPosition = ::Oyster::Math::Float3::null;
|
this->centerPosition = ::Oyster::Math::Float3::null;
|
||||||
this->size = ::Oyster::Math::Float3( 1.0f );
|
this->size = ::Oyster::Math::Float3( 1.0f );
|
||||||
this->mass = 6.0f;
|
this->mass = 6.0f;
|
||||||
|
@ -28,7 +28,7 @@ namespace Oyster
|
||||||
|
|
||||||
inline SphericalBodyDescription::SphericalBodyDescription()
|
inline SphericalBodyDescription::SphericalBodyDescription()
|
||||||
{
|
{
|
||||||
this->rotation = ::Oyster::Math::Float4x4::identity;
|
this->rotation = ::Oyster::Math::Float3::null;
|
||||||
this->centerPosition = ::Oyster::Math::Float3::null;
|
this->centerPosition = ::Oyster::Math::Float3::null;
|
||||||
this->radius = 0.5f;
|
this->radius = 0.5f;
|
||||||
this->mass = 10.0f;
|
this->mass = 10.0f;
|
||||||
|
@ -124,7 +124,7 @@ namespace Oyster
|
||||||
|
|
||||||
inline const ::Oyster::Math::Float3 & CustomBodyState::GetAngularAxis() const
|
inline const ::Oyster::Math::Float3 & CustomBodyState::GetAngularAxis() const
|
||||||
{
|
{
|
||||||
return ::Utility::Value::Radian(this->angularAxis);
|
return this->angularAxis;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ::Oyster::Math::Float4x4 CustomBodyState::GetRotation() const
|
inline ::Oyster::Math::Float4x4 CustomBodyState::GetRotation() const
|
||||||
|
@ -159,7 +159,12 @@ namespace Oyster
|
||||||
|
|
||||||
inline ::Oyster::Math::Float3 CustomBodyState::GetLinearMomentum( const ::Oyster::Math::Float3 &at ) const
|
inline ::Oyster::Math::Float3 CustomBodyState::GetLinearMomentum( const ::Oyster::Math::Float3 &at ) const
|
||||||
{
|
{
|
||||||
return this->linearMomentum + ::Oyster::Physics3D::Formula::TangentialLinearMomentum( this->angularMomentum, at - this->centerPos );
|
::Oyster::Math::Float3 offset = at - this->centerPos;
|
||||||
|
if( offset.Dot(offset) > 0.0f )
|
||||||
|
{
|
||||||
|
return this->linearMomentum + ::Oyster::Physics3D::Formula::TangentialLinearMomentum( this->angularMomentum, offset );
|
||||||
|
}
|
||||||
|
return this->linearMomentum;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const ::Oyster::Math::Float3 & CustomBodyState::GetAngularMomentum() const
|
inline const ::Oyster::Math::Float3 & CustomBodyState::GetAngularMomentum() const
|
||||||
|
@ -317,10 +322,14 @@ namespace Oyster
|
||||||
inline void CustomBodyState::ApplyImpulse( const ::Oyster::Math::Float3 &j, const ::Oyster::Math::Float3 &at, const ::Oyster::Math::Float3 &normal )
|
inline void CustomBodyState::ApplyImpulse( const ::Oyster::Math::Float3 &j, const ::Oyster::Math::Float3 &at, const ::Oyster::Math::Float3 &normal )
|
||||||
{
|
{
|
||||||
::Oyster::Math::Float3 offset = at - this->centerPos;
|
::Oyster::Math::Float3 offset = at - this->centerPos;
|
||||||
|
if( offset.Dot(offset) > 0.0f )
|
||||||
|
{
|
||||||
::Oyster::Math::Float3 deltaAngularImpulse = ::Oyster::Physics3D::Formula::AngularMomentum( j, offset );
|
::Oyster::Math::Float3 deltaAngularImpulse = ::Oyster::Physics3D::Formula::AngularMomentum( j, offset );
|
||||||
this->linearImpulse += j - ::Oyster::Physics3D::Formula::TangentialLinearMomentum( deltaAngularImpulse, offset );
|
|
||||||
|
|
||||||
|
this->linearImpulse -= ::Oyster::Physics3D::Formula::TangentialLinearMomentum( deltaAngularImpulse, offset );
|
||||||
this->angularImpulse += deltaAngularImpulse;
|
this->angularImpulse += deltaAngularImpulse;
|
||||||
|
}
|
||||||
|
this->linearImpulse += j;
|
||||||
this->isDisturbed = true;
|
this->isDisturbed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Oyster { namespace Physics
|
||||||
{
|
{
|
||||||
struct SimpleBodyDescription
|
struct SimpleBodyDescription
|
||||||
{
|
{
|
||||||
::Oyster::Math::Float4x4 rotation;
|
::Oyster::Math::Float3 rotation;
|
||||||
::Oyster::Math::Float3 centerPosition;
|
::Oyster::Math::Float3 centerPosition;
|
||||||
::Oyster::Math::Float3 size;
|
::Oyster::Math::Float3 size;
|
||||||
::Oyster::Math::Float mass;
|
::Oyster::Math::Float mass;
|
||||||
|
@ -29,7 +29,7 @@ namespace Oyster { namespace Physics
|
||||||
|
|
||||||
struct SphericalBodyDescription
|
struct SphericalBodyDescription
|
||||||
{
|
{
|
||||||
::Oyster::Math::Float4x4 rotation;
|
::Oyster::Math::Float3 rotation;
|
||||||
::Oyster::Math::Float3 centerPosition;
|
::Oyster::Math::Float3 centerPosition;
|
||||||
::Oyster::Math::Float radius;
|
::Oyster::Math::Float radius;
|
||||||
::Oyster::Math::Float mass;
|
::Oyster::Math::Float mass;
|
||||||
|
@ -115,11 +115,13 @@ namespace Oyster { namespace Physics
|
||||||
bool IsDisturbed() const;
|
bool IsDisturbed() const;
|
||||||
bool IsForwarded() const;
|
bool IsForwarded() const;
|
||||||
|
|
||||||
|
::Oyster::Math::Float3 linearMomentum;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::Oyster::Math::Float mass, restitutionCoeff, staticFrictionCoeff, kineticFrictionCoeff;
|
::Oyster::Math::Float mass, restitutionCoeff, staticFrictionCoeff, kineticFrictionCoeff;
|
||||||
::Oyster::Physics3D::MomentOfInertia inertiaTensor;
|
::Oyster::Physics3D::MomentOfInertia inertiaTensor;
|
||||||
::Oyster::Math::Float3 reach, centerPos, angularAxis;
|
::Oyster::Math::Float3 reach, centerPos, angularAxis;
|
||||||
::Oyster::Math::Float3 linearMomentum, angularMomentum;
|
::Oyster::Math::Float3 angularMomentum;
|
||||||
::Oyster::Math::Float3 linearImpulse, angularImpulse;
|
::Oyster::Math::Float3 linearImpulse, angularImpulse;
|
||||||
::Oyster::Math::Float3 deltaPos, deltaAxis; // Forwarding data sum
|
::Oyster::Math::Float3 deltaPos, deltaAxis; // Forwarding data sum
|
||||||
::Oyster::Math::Float3 gravityNormal;
|
::Oyster::Math::Float3 gravityNormal;
|
||||||
|
|
|
@ -315,6 +315,14 @@ namespace Utility
|
||||||
{
|
{
|
||||||
using ::std::numeric_limits;
|
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>
|
template<typename ValueType>
|
||||||
inline ValueType Abs( const ValueType &value )
|
inline ValueType Abs( const ValueType &value )
|
||||||
{ return value < 0 ? value * -1 : value; }
|
{ return value < 0 ? value * -1 : value; }
|
||||||
|
|
|
@ -16,11 +16,15 @@
|
||||||
#include "../../Misc/Utilities.h"
|
#include "../../Misc/Utilities.h"
|
||||||
#include "../../Misc/Thread/IThreadObject.h"
|
#include "../../Misc/Thread/IThreadObject.h"
|
||||||
#include "../../Misc/Thread/OysterThread.h"
|
#include "../../Misc/Thread/OysterThread.h"
|
||||||
|
#include "../../Misc/Packing/Packing.h"
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
using namespace Oyster::Network;
|
using namespace Oyster::Network;
|
||||||
using namespace Oyster::Thread;
|
using namespace Oyster::Thread;
|
||||||
using namespace Utility::DynamicMemory;
|
using namespace Utility::DynamicMemory;
|
||||||
using namespace Utility::Container;
|
using namespace Utility::Container;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
PrivateData
|
PrivateData
|
||||||
|
@ -35,6 +39,7 @@ struct NetworkClient::PrivateData : public IThreadObject
|
||||||
Translator translator;
|
Translator translator;
|
||||||
OysterThread thread;
|
OysterThread thread;
|
||||||
|
|
||||||
|
OysterByte recieveBuffer;
|
||||||
|
|
||||||
//Message queue for sending and recieving
|
//Message queue for sending and recieving
|
||||||
ThreadSafeQueue<CustomNetProtocol> sendQueue;
|
ThreadSafeQueue<CustomNetProtocol> sendQueue;
|
||||||
|
@ -82,6 +87,7 @@ struct NetworkClient::PrivateData : public IThreadObject
|
||||||
CustomNetProtocol p = this->sendQueue.Pop();
|
CustomNetProtocol p = this->sendQueue.Pop();
|
||||||
this->translator.Pack(temp, p);
|
this->translator.Pack(temp, p);
|
||||||
errorCode = this->connection.Send(temp);
|
errorCode = this->connection.Send(temp);
|
||||||
|
|
||||||
if(errorCode != 0)
|
if(errorCode != 0)
|
||||||
{
|
{
|
||||||
CEA parg;
|
CEA parg;
|
||||||
|
@ -103,6 +109,10 @@ struct NetworkClient::PrivateData : public IThreadObject
|
||||||
|
|
||||||
if(errorCode == 0 && temp.GetSize())
|
if(errorCode == 0 && temp.GetSize())
|
||||||
{
|
{
|
||||||
|
HandleRecievedData(temp);
|
||||||
|
|
||||||
|
|
||||||
|
/* Replaced with EmptyOutbufferedQueue() and HandleRecievedData(OysterByte)
|
||||||
CustomNetProtocol protocol;
|
CustomNetProtocol protocol;
|
||||||
bool ok = this->translator.Unpack(protocol, temp);
|
bool ok = this->translator.Unpack(protocol, temp);
|
||||||
|
|
||||||
|
@ -114,7 +124,8 @@ struct NetworkClient::PrivateData : public IThreadObject
|
||||||
parg.data.protocol = protocol;
|
parg.data.protocol = protocol;
|
||||||
NetEvent<NetworkClient*, NetworkClient::ClientEventArgs> e = { this->parent, parg };
|
NetEvent<NetworkClient*, NetworkClient::ClientEventArgs> e = { this->parent, parg };
|
||||||
this->recieveQueue.Push(e);
|
this->recieveQueue.Push(e);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
//else
|
//else
|
||||||
//{
|
//{
|
||||||
|
@ -127,6 +138,76 @@ struct NetworkClient::PrivateData : public IThreadObject
|
||||||
|
|
||||||
return errorCode;
|
return errorCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleRecievedData(OysterByte& data)
|
||||||
|
{
|
||||||
|
//Loop through all packages that was recieved and add them to the queue.
|
||||||
|
unsigned int size = 0;
|
||||||
|
|
||||||
|
Oyster::Network::OysterByte msg;
|
||||||
|
|
||||||
|
//If there is part of a message in the buffer.
|
||||||
|
if(recieveBuffer.GetSize() > 0)
|
||||||
|
{
|
||||||
|
//cout << "the buffer size: " << recvBuffer.GetSize() <<endl;
|
||||||
|
unsigned int temp = recieveBuffer.GetSize();
|
||||||
|
size = Oyster::Packing::Unpacki(recieveBuffer);
|
||||||
|
|
||||||
|
if(temp + data.GetSize() > size)
|
||||||
|
{
|
||||||
|
msg = recieveBuffer;
|
||||||
|
recieveBuffer.Clear();
|
||||||
|
size -= msg.GetSize();
|
||||||
|
msg.AppendPartOfArray(data, 0, size);
|
||||||
|
UnpackMessageAndAddToQueue(msg);
|
||||||
|
}
|
||||||
|
else if(temp + data.GetSize() == size)
|
||||||
|
{
|
||||||
|
msg = recieveBuffer;
|
||||||
|
recieveBuffer.Clear();
|
||||||
|
size -= msg.GetSize();
|
||||||
|
msg += data;
|
||||||
|
UnpackMessageAndAddToQueue(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
recieveBuffer += data;
|
||||||
|
size = data.GetSize();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = size; i < data.GetSize(); i += size)
|
||||||
|
{
|
||||||
|
size = Oyster::Packing::Unpacki(&data.GetByteArray()[i]);
|
||||||
|
if(i+size > data.GetSize())
|
||||||
|
{
|
||||||
|
//Add it to the recvBuffer instead.
|
||||||
|
recieveBuffer.AppendPartOfArray(data, i, data.GetSize());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
msg.Clear();
|
||||||
|
msg.AppendPartOfArray(data, i, i+size);
|
||||||
|
UnpackMessageAndAddToQueue(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnpackMessageAndAddToQueue(OysterByte& msg)
|
||||||
|
{
|
||||||
|
CustomNetProtocol protocol;
|
||||||
|
bool ok = this->translator.Unpack(protocol, msg);
|
||||||
|
|
||||||
|
//Check if the protocol was unpacked correctly
|
||||||
|
if(ok)
|
||||||
|
{
|
||||||
|
CEA parg;
|
||||||
|
parg.type = CEA::EventType_ProtocolRecieved;
|
||||||
|
parg.data.protocol = protocol;
|
||||||
|
NetEvent<NetworkClient*, NetworkClient::ClientEventArgs> e = { this->parent, parg };
|
||||||
|
this->recieveQueue.Push(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
unsigned int NetworkClient::PrivateData::currID = 0;
|
unsigned int NetworkClient::PrivateData::currID = 0;
|
||||||
|
|
||||||
|
|
|
@ -84,8 +84,8 @@ namespace Oyster
|
||||||
*/
|
*/
|
||||||
std::string GetLanAddress();
|
std::string GetLanAddress();
|
||||||
|
|
||||||
/**
|
/** Returns the port the server is listening on.
|
||||||
*
|
* @return Returns the port the server has been initiated with.
|
||||||
*/
|
*/
|
||||||
int NetworkServer::GetPort();
|
int NetworkServer::GetPort();
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "NetworkAPI_Preprocessor.h"
|
#include "NetworkAPI_Preprocessor.h"
|
||||||
#include "NetworkServerEventStruct.h"
|
#include "NetworkServerEventStruct.h"
|
||||||
#include "NetworkClient.h"
|
#include "NetworkClient.h"
|
||||||
#include "Utilities.h"
|
#include "..\Misc\Utilities.h"
|
||||||
#include "DynamicArray.h"
|
#include "DynamicArray.h"
|
||||||
|
|
||||||
namespace Oyster
|
namespace Oyster
|
||||||
|
|
|
@ -48,7 +48,7 @@ void OysterByte::Resize(unsigned int cap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int OysterByte::GetSize()
|
unsigned int OysterByte::GetSize()
|
||||||
{
|
{
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ unsigned char* OysterByte::GetByteArray()
|
||||||
|
|
||||||
void OysterByte::AddSize(unsigned int size)
|
void OysterByte::AddSize(unsigned int size)
|
||||||
{
|
{
|
||||||
int newCapacity = this->size + size;
|
unsigned int newCapacity = this->size + size;
|
||||||
|
|
||||||
if(newCapacity >= capacity)
|
if(newCapacity >= capacity)
|
||||||
{
|
{
|
||||||
|
@ -81,6 +81,32 @@ void OysterByte::SetSize(unsigned int size)
|
||||||
this->size = size;
|
this->size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OysterByte::AppendPartOfArray(OysterByte& source, unsigned int startIndex, unsigned int endIndex)
|
||||||
|
{
|
||||||
|
if(startIndex < 0 && startIndex >= endIndex)
|
||||||
|
return;
|
||||||
|
if(endIndex > source.size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned int totalSize = endIndex - startIndex;
|
||||||
|
totalSize += size;
|
||||||
|
|
||||||
|
//Make sure the new data can fit in the array.
|
||||||
|
if(totalSize > capacity)
|
||||||
|
{
|
||||||
|
IncreaseCapacity(totalSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Copy over new data.
|
||||||
|
for(unsigned int i = size; i < totalSize; i++)
|
||||||
|
{
|
||||||
|
byteArray[i] = source.byteArray[startIndex++];
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set the new size
|
||||||
|
size = totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
OysterByte& OysterByte::operator =(const OysterByte& obj)
|
OysterByte& OysterByte::operator =(const OysterByte& obj)
|
||||||
{
|
{
|
||||||
delete[] this->byteArray;
|
delete[] this->byteArray;
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace Oyster
|
||||||
//Resizes the array with, it does not keep anything in it.
|
//Resizes the array with, it does not keep anything in it.
|
||||||
void Resize(unsigned int cap);
|
void Resize(unsigned int cap);
|
||||||
|
|
||||||
int GetSize();
|
unsigned int GetSize();
|
||||||
unsigned char* GetByteArray();
|
unsigned char* GetByteArray();
|
||||||
|
|
||||||
void AddSize(unsigned int size);
|
void AddSize(unsigned int size);
|
||||||
|
@ -34,6 +34,9 @@ namespace Oyster
|
||||||
//Only sets the private variable 'size'
|
//Only sets the private variable 'size'
|
||||||
void SetSize(unsigned int size);
|
void SetSize(unsigned int size);
|
||||||
|
|
||||||
|
//Copies over a part of the addFrom array and adds it to the end of this array.
|
||||||
|
void AppendPartOfArray(OysterByte& source, unsigned int startIndex, unsigned int endIndex);
|
||||||
|
|
||||||
OysterByte& operator =(const OysterByte& obj);
|
OysterByte& operator =(const OysterByte& obj);
|
||||||
|
|
||||||
operator char*();
|
operator char*();
|
||||||
|
|
|
@ -11,27 +11,6 @@
|
||||||
#include "Quaternion.h"
|
#include "Quaternion.h"
|
||||||
#include <math.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
|
// x2
|
||||||
|
|
||||||
template<typename ScalarType>
|
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) );
|
(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
|
namespace LinearAlgebra
|
||||||
{
|
{
|
||||||
// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
|
||||||
|
@ -325,6 +367,12 @@ namespace LinearAlgebra2D
|
||||||
|
|
||||||
namespace LinearAlgebra3D
|
namespace LinearAlgebra3D
|
||||||
{
|
{
|
||||||
|
template<typename ScalarType>
|
||||||
|
inline ::LinearAlgebra::Vector3<ScalarType> WorldAxisOf( const ::LinearAlgebra::Quaternion<ScalarType> &rotation, const ::LinearAlgebra::Vector3<ScalarType> &localAxis )
|
||||||
|
{
|
||||||
|
return (rotation*localAxis*rotation.GetConjugate()).imaginary;
|
||||||
|
}
|
||||||
|
|
||||||
// All Matrix to AngularAxis conversions here is incorrect
|
// All Matrix to AngularAxis conversions here is incorrect
|
||||||
//template<typename ScalarType>
|
//template<typename ScalarType>
|
||||||
//inline ::LinearAlgebra::Vector4<ScalarType> AngularAxis( const ::LinearAlgebra::Matrix3x3<ScalarType> &rotationMatrix )
|
//inline ::LinearAlgebra::Vector4<ScalarType> AngularAxis( const ::LinearAlgebra::Matrix3x3<ScalarType> &rotationMatrix )
|
||||||
|
@ -741,6 +789,23 @@ namespace LinearAlgebra3D
|
||||||
inline ::LinearAlgebra::Vector4<ScalarType> NormalProjection( const ::LinearAlgebra::Vector4<ScalarType> &vector, const ::LinearAlgebra::Vector4<ScalarType> &normalizedAxis )
|
inline ::LinearAlgebra::Vector4<ScalarType> NormalProjection( const ::LinearAlgebra::Vector4<ScalarType> &vector, const ::LinearAlgebra::Vector4<ScalarType> &normalizedAxis )
|
||||||
{ return normalizedAxis * ( vector.Dot(normalizedAxis) ); }
|
{ return normalizedAxis * ( vector.Dot(normalizedAxis) ); }
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
::LinearAlgebra::Vector4<ScalarType> & SnapAngularAxis( ::LinearAlgebra::Vector4<ScalarType> &startAngularAxis, const ::LinearAlgebra::Vector4<ScalarType> &localStartNormal, const ::LinearAlgebra::Vector4<ScalarType> &worldEndNormal, ::LinearAlgebra::Vector4<ScalarType> &targetMem = ::LinearAlgebra::Vector4<ScalarType>() )
|
||||||
|
{
|
||||||
|
::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( ::Utility::Value::Clamp(worldStartNormal.Dot(worldEndNormal), (ScalarType)0, (ScalarType)1) );
|
||||||
|
return targetMem += startAngularAxis;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ScalarType>
|
||||||
|
::LinearAlgebra::Vector3<ScalarType> & SnapAngularAxis( ::LinearAlgebra::Vector3<ScalarType> &startAngularAxis, const ::LinearAlgebra::Vector3<ScalarType> &localStartNormal, const ::LinearAlgebra::Vector3<ScalarType> &worldEndNormal, ::LinearAlgebra::Vector3<ScalarType> &targetMem = ::LinearAlgebra::Vector3<ScalarType>() )
|
||||||
|
{
|
||||||
|
return targetMem = SnapAngularAxis( ::LinearAlgebra::Vector4<ScalarType>(startAngularAxis, (ScalarType)0),
|
||||||
|
::LinearAlgebra::Vector4<ScalarType>(localStartNormal, (ScalarType)0),
|
||||||
|
::LinearAlgebra::Vector4<ScalarType>(worldEndNormal, (ScalarType)0) ).xyz;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
template<typename ScalarType>
|
||||||
::LinearAlgebra::Matrix4x4<ScalarType> & SnapAxisYToNormal_UsingNlerp( ::LinearAlgebra::Matrix4x4<ScalarType> &rotation, const ::LinearAlgebra::Vector4<ScalarType> &normalizedAxis )
|
::LinearAlgebra::Matrix4x4<ScalarType> & SnapAxisYToNormal_UsingNlerp( ::LinearAlgebra::Matrix4x4<ScalarType> &rotation, const ::LinearAlgebra::Vector4<ScalarType> &normalizedAxis )
|
||||||
{
|
{
|
||||||
|
@ -772,11 +837,42 @@ namespace LinearAlgebra3D
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ScalarType>
|
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[0] = ::LinearAlgebra::Nlerp( start.v[0], end.v[0], t );
|
||||||
targetMem.v[1] = ::LinearAlgebra::Nlerp( start.v[1], end.v[1], 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 );
|
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 );
|
targetMem.v[3] = ::LinearAlgebra::Lerp( start.v[3], end.v[3], t );
|
||||||
return targetMem;
|
return targetMem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -322,8 +322,12 @@ namespace Oyster { namespace Math3D //! Oyster's native math library specialized
|
||||||
|
|
||||||
using ::LinearAlgebra3D::SnapAxisYToNormal_UsingNlerp;
|
using ::LinearAlgebra3D::SnapAxisYToNormal_UsingNlerp;
|
||||||
using ::LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp;
|
using ::LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp;
|
||||||
|
using ::LinearAlgebra3D::InterpolateRotation_UsingNonRigidNlerp;
|
||||||
|
using ::LinearAlgebra3D::InterpolateRotation_UsingRigidNlerp;
|
||||||
using ::LinearAlgebra3D::InterpolateOrientation_UsingNonRigidNlerp;
|
using ::LinearAlgebra3D::InterpolateOrientation_UsingNonRigidNlerp;
|
||||||
|
using ::LinearAlgebra3D::InterpolateOrientation_UsingRigidNlerp;
|
||||||
using ::LinearAlgebra3D::InterpolateOrientation_UsingSlerp;
|
using ::LinearAlgebra3D::InterpolateOrientation_UsingSlerp;
|
||||||
|
using ::LinearAlgebra3D::SnapAngularAxis;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -93,3 +93,26 @@ bool Box::Contains( const ICollideable &target ) const
|
||||||
default: return false;
|
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,7 +9,9 @@
|
||||||
#include "OysterMath.h"
|
#include "OysterMath.h"
|
||||||
#include "ICollideable.h"
|
#include "ICollideable.h"
|
||||||
|
|
||||||
namespace Oyster { namespace Collision3D
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Collision3D
|
||||||
{
|
{
|
||||||
class Box : public ICollideable
|
class Box : public ICollideable
|
||||||
{
|
{
|
||||||
|
@ -37,7 +39,18 @@ namespace Oyster { namespace Collision3D
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) 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
|
#endif
|
|
@ -77,3 +77,15 @@ bool BoxAxisAligned::Contains( const ICollideable &target ) const
|
||||||
//}
|
//}
|
||||||
return false;
|
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 ) const;
|
||||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) 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();
|
Float4x4 m = vp.GetTranspose();
|
||||||
|
|
||||||
// left
|
// 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.phasing = lp.normal.GetMagnitude();
|
||||||
lp.normal /= lp.phasing;
|
lp.normal /= lp.phasing;
|
||||||
lp.phasing = (m.v[3].w + m.v[0].w) / lp.phasing;
|
lp.phasing = (m.v[3].w + m.v[0].w) / lp.phasing;
|
||||||
|
|
||||||
// right
|
// 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.phasing = rp.normal.GetMagnitude();
|
||||||
rp.normal /= rp.phasing;
|
rp.normal /= rp.phasing;
|
||||||
rp.phasing = (m.v[3].w - m.v[0].w) / rp.phasing;
|
rp.phasing = (m.v[3].w - m.v[0].w) / rp.phasing;
|
||||||
|
|
||||||
// bottom
|
// 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.phasing = bp.normal.GetMagnitude();
|
||||||
bp.normal /= bp.phasing;
|
bp.normal /= bp.phasing;
|
||||||
bp.phasing = (m.v[3].w + m.v[1].w) / bp.phasing;
|
bp.phasing = (m.v[3].w + m.v[1].w) / bp.phasing;
|
||||||
|
|
||||||
// top
|
// 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.phasing = tp.normal.GetMagnitude();
|
||||||
tp.normal /= tp.phasing;
|
tp.normal /= tp.phasing;
|
||||||
tp.phasing = (m.v[3].w - m.v[1].w) / tp.phasing;
|
tp.phasing = (m.v[3].w - m.v[1].w) / tp.phasing;
|
||||||
|
|
||||||
// near leftHanded DirectX
|
// near leftHanded DirectX
|
||||||
np.normal = m.v[2].xyz;
|
np.normal = Float4(m.v[2].xyz,0);
|
||||||
np.phasing = np.normal.GetMagnitude();
|
np.phasing = np.normal.GetMagnitude();
|
||||||
np.normal /= np.phasing;
|
np.normal /= np.phasing;
|
||||||
np.phasing = m.v[2].w / np.phasing;
|
np.phasing = m.v[2].w / np.phasing;
|
||||||
|
|
||||||
// far lefthanded
|
// 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.phasing = fp.normal.GetMagnitude();
|
||||||
fp.normal /= fp.phasing;
|
fp.normal /= fp.phasing;
|
||||||
fp.phasing = (m.v[3].w - m.v[2].w) / 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()
|
::Oyster::Math::Float3 Frustrum::ExtractForwad()
|
||||||
{
|
{
|
||||||
return this->bottomPlane.normal.xyz;
|
return this->bottomPlane.normal.xyz;
|
||||||
|
|
|
@ -42,6 +42,8 @@ namespace Oyster { namespace Collision3D
|
||||||
bool Intersects( const ICollideable &target, Oyster::Math::Float4 &worldPointOfContact ) const;
|
bool Intersects( const ICollideable &target, Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
|
|
||||||
|
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||||
|
|
||||||
::Oyster::Math::Float3 ExtractForwad();
|
::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, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0;
|
||||||
virtual bool Intersects( const ICollideable &target ) const = 0;
|
virtual bool Intersects( const ICollideable &target ) const = 0;
|
||||||
virtual bool Contains( 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
|
#endif
|
|
@ -76,3 +76,15 @@ bool Line::Intersects( const ICollideable &target, Float4 &worldPointOfContact )
|
||||||
|
|
||||||
bool Line::Contains( const ICollideable &target ) const
|
bool Line::Contains( const ICollideable &target ) const
|
||||||
{ /* TODO: : */ return false; }
|
{ /* 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 ) const;
|
||||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
|
|
||||||
|
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
|
|
@ -784,7 +784,7 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
if( Intersect(box, sphere) )
|
if( Intersect(box, sphere) )
|
||||||
{
|
{
|
||||||
Float distance;
|
Float distance;
|
||||||
Ray ray( box.center, sphere.center - box.center );
|
Ray ray( box.center, (sphere.center - box.center).Normalize() );
|
||||||
|
|
||||||
Intersect( sphere, ray, distance );
|
Intersect( sphere, ray, distance );
|
||||||
worldPointOfContact = ray.origin + ray.direction*distance;
|
worldPointOfContact = ray.origin + ray.direction*distance;
|
||||||
|
@ -1061,4 +1061,47 @@ namespace Oyster { namespace Collision3D { namespace Utility
|
||||||
return container.normal == -plane.normal;
|
return container.normal == -plane.normal;
|
||||||
return false;
|
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 BoxAxisAligned &box );
|
||||||
// bool Contains( const Frustrum &container, const Box &box );
|
// bool Contains( const Frustrum &container, const Box &box );
|
||||||
// bool Contains( const Frustrum &container, const Frustrum &frustrum );
|
// 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
|
#endif
|
|
@ -27,9 +27,6 @@
|
||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Universe.h">
|
|
||||||
<Filter>Header Files\Collision</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Box.h">
|
<ClInclude Include="Box.h">
|
||||||
<Filter>Header Files\Collision</Filter>
|
<Filter>Header Files\Collision</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -81,6 +78,9 @@
|
||||||
<ClInclude Include="Inertia.h">
|
<ClInclude Include="Inertia.h">
|
||||||
<Filter>Header Files\Physics</Filter>
|
<Filter>Header Files\Physics</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Universe.h">
|
||||||
|
<Filter>Header Files\Collision</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Box.cpp">
|
<ClCompile Include="Box.cpp">
|
||||||
|
|
|
@ -84,3 +84,15 @@ bool Plane::Contains( const ICollideable &target ) const
|
||||||
default: return false;
|
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 ) const;
|
||||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) 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;
|
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 ) const;
|
||||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) 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;
|
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 ) const;
|
||||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
|
|
||||||
|
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,11 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength )
|
||||||
{ // by Dan Andersson: Euler leap frog update when Runga Kutta is not needed
|
{ // by Dan Andersson: Euler leap frog update when Runga Kutta is not needed
|
||||||
|
|
||||||
// updating the linear
|
// 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
|
// ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G
|
||||||
this->centerPos += ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear );
|
this->centerPos += ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear );
|
||||||
|
|
||||||
|
@ -143,7 +148,12 @@ Float3 RigidBody::GetVelocity_Angular() const
|
||||||
|
|
||||||
Float3 RigidBody::GetLinearMomentum( const Float3 &atWorldPos ) const
|
Float3 RigidBody::GetLinearMomentum( const Float3 &atWorldPos ) const
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
return this->momentum_Linear + Formula::TangentialLinearMomentum( this->momentum_Angular, atWorldPos - this->centerPos );
|
Float3 offset = atWorldPos - this->centerPos;
|
||||||
|
if( offset.Dot(offset) > 0.0f )
|
||||||
|
{
|
||||||
|
return this->momentum_Linear + Formula::TangentialLinearMomentum( this->momentum_Angular, offset );
|
||||||
|
}
|
||||||
|
return this->momentum_Linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::SetMomentOfInertia_KeepVelocity( const MomentOfInertia &localTensorI )
|
void RigidBody::SetMomentOfInertia_KeepVelocity( const MomentOfInertia &localTensorI )
|
||||||
|
@ -176,6 +186,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 )
|
void RigidBody::SetMomentum_Linear( const Float3 &worldG, const Float3 &atWorldPos )
|
||||||
{ // by Dan Andersson
|
{ // by Dan Andersson
|
||||||
Float3 worldOffset = atWorldPos - this->centerPos;
|
Float3 worldOffset = atWorldPos - this->centerPos;
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace Oyster { namespace Physics3D
|
||||||
void SetMass_KeepMomentum( const ::Oyster::Math::Float &m );
|
void SetMass_KeepMomentum( const ::Oyster::Math::Float &m );
|
||||||
|
|
||||||
//void SetOrientation( const ::Oyster::Math::Float4x4 &o );
|
//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 SetSize( const ::Oyster::Math::Float3 &widthHeight );
|
||||||
|
|
||||||
void SetMomentum_Linear( const ::Oyster::Math::Float3 &worldG, const ::Oyster::Math::Float3 &atWorldPos );
|
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;
|
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,7 +9,9 @@
|
||||||
#include "OysterMath.h"
|
#include "OysterMath.h"
|
||||||
#include "ICollideable.h"
|
#include "ICollideable.h"
|
||||||
|
|
||||||
namespace Oyster { namespace Collision3D
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Collision3D
|
||||||
{
|
{
|
||||||
class Sphere : public ICollideable
|
class Sphere : public ICollideable
|
||||||
{
|
{
|
||||||
|
@ -31,7 +33,18 @@ namespace Oyster { namespace Collision3D
|
||||||
bool Intersects( const ICollideable &target ) const;
|
bool Intersects( const ICollideable &target ) const;
|
||||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) 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
|
#endif
|
|
@ -79,3 +79,8 @@ bool Universe::Contains( const ICollideable &target ) const
|
||||||
{ // universe contains everything
|
{ // universe contains everything
|
||||||
return true;
|
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 ) const;
|
||||||
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const;
|
||||||
bool Contains( const ICollideable &target ) const;
|
bool Contains( const ICollideable &target ) const;
|
||||||
|
|
||||||
|
::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const;
|
||||||
};
|
};
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue