From 0a04c1c9f10148d1c7186e82801df0199b5eaf8b Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Thu, 30 Jan 2014 14:52:40 +0100 Subject: [PATCH 01/74] Added document --- ...erp rotation axis towards new up normal.odt | Bin 0 -> 134706 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Code/Dokumentation/Other/Slerp rotation axis towards new up normal.odt diff --git a/Code/Dokumentation/Other/Slerp rotation axis towards new up normal.odt b/Code/Dokumentation/Other/Slerp rotation axis towards new up normal.odt new file mode 100644 index 0000000000000000000000000000000000000000..6ed3d36f51b494b356eb5568f89382f220f29af9 GIT binary patch literal 134706 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 z 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 b^1e92x&7I#9-JQB15*g3G#YwN3iAI07eDVX literal 0 HcmV?d00001 From 4167b6a93b431c5fbfab4172d9e46e7116e547cc Mon Sep 17 00:00:00 2001 From: Sam Mario Svensson Date: Thu, 30 Jan 2014 15:02:02 +0100 Subject: [PATCH 02/74] GL- merge fix --- Code/Game/aDanBiasGameLauncher/Launcher.cpp | 2 +- Code/Network/NetworkAPI/NetworkSession.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Game/aDanBiasGameLauncher/Launcher.cpp b/Code/Game/aDanBiasGameLauncher/Launcher.cpp index e13baff1..f05f021d 100644 --- a/Code/Game/aDanBiasGameLauncher/Launcher.cpp +++ b/Code/Game/aDanBiasGameLauncher/Launcher.cpp @@ -57,7 +57,7 @@ int WINAPI WinMain( HINSTANCE hinst, HINSTANCE prevInst, PSTR cmdLine, int cmdSh return cmdShow; } - serverThread = std::thread(ServerFnc); + //serverThread = std::thread(ServerFnc); Sleep(200); diff --git a/Code/Network/NetworkAPI/NetworkSession.h b/Code/Network/NetworkAPI/NetworkSession.h index b44f5c61..2ef1130c 100644 --- a/Code/Network/NetworkAPI/NetworkSession.h +++ b/Code/Network/NetworkAPI/NetworkSession.h @@ -13,7 +13,7 @@ #include "NetworkAPI_Preprocessor.h" #include "NetworkServerEventStruct.h" #include "NetworkClient.h" -#include "Utilities.h" +#include "..\Misc\Utilities.h" #include "DynamicArray.h" namespace Oyster From ae6a570a122460e5877ab48d6898fa9d17075671 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Thu, 30 Jan 2014 15:12:53 +0100 Subject: [PATCH 03/74] GL - trying to make walking nice --- Code/Game/DanBiasGame/GameClientState/GameState.cpp | 13 +++++++------ Code/Game/GameLogic/CollisionManager.cpp | 5 ++++- Code/Game/GameLogic/Game_PlayerData.cpp | 4 ++-- Code/Game/GameLogic/Level.cpp | 6 +++--- Code/Game/GameLogic/Player.cpp | 10 +++++----- .../Shader/HLSL/Deffered Shaders/LightPass.hlsl | 4 +++- .../Shader/HLSL/Deffered Shaders/PostPass.hlsl | 2 ++ 7 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index 00fc2599..c5fb9d66 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -81,10 +81,11 @@ bool GameState::LoadModels(std::wstring mapFile) C_Object* obj; translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0,0,0)); Oyster::Math3D::Float4x4 scale = Oyster::Math3D::Float4x4::identity; - scale.v[0].x = 8; - scale.v[1].y = 8; - scale.v[2].z = 8; - modelData.world = translate; //modelData.world * translate + scale.v[0].x = 0.2; + scale.v[1].y = 0.2; + scale.v[2].z = 0.2; + scale.v[3].w = 1; + modelData.world = translate ;//modelData.world * translate modelData.modelPath = L"world_earth.dan"; modelData.id = 0; @@ -94,7 +95,7 @@ bool GameState::LoadModels(std::wstring mapFile) // add box model modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(-5,175,0)); + translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(-5,15,0)); modelData.world = modelData.world * translate; modelData.modelPath = L"box.dan"; modelData.id = 1; @@ -132,7 +133,7 @@ bool GameState::InitCamera(Oyster::Math::Float3 startPos) camera->LookAt(pos, dir, up); 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); Oyster::Graphics::API::SetProjection(privData->proj); camera->UpdateViewMatrix(); diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 19f25dd3..76ca668a 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -81,8 +81,11 @@ using namespace GameLogic; void AttatchmentMassDriver::ForcePushAction(Oyster::Physics::ICustomBody *obj, void *args) { - Oyster::Math::Float3 pushForce = Oyster::Math::Float4(1,0,0) * (1); + Oyster::Math::Float3 pushForce = Oyster::Math::Float4(1,0,0) * (500); Oyster::Physics::ICustomBody::State state; + Object *realObj = (Object*)obj->GetCustomTag(); + if(realObj->GetType() == OBJECT_TYPE_PLAYER || realObj->GetType() == OBJECT_TYPE_WORLD) + return; state = obj->GetState(); state.ApplyLinearImpulse(pushForce); obj->SetState(state); diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index b3c6ef26..8dc29957 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -7,9 +7,9 @@ Game::PlayerData::PlayerData() { //set some stats that are appropriate to a player Oyster::Physics::API::SimpleBodyDescription sbDesc; - sbDesc.centerPosition = Oyster::Math::Float3(0,165,0); + sbDesc.centerPosition = Oyster::Math::Float3(0,350,0); sbDesc.size = Oyster::Math::Float3(4,7,4); - + sbDesc.mass = 10; //create rigid body Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index f631979d..8b2f3bf8 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -25,7 +25,7 @@ void Level::InitiateLevel(float radius) API::SphericalBodyDescription sbDesc; sbDesc.centerPosition = Oyster::Math::Float4(0,0,0,1); sbDesc.ignoreGravity = true; - sbDesc.radius = 150; + sbDesc.radius = 300; sbDesc.mass = 10e12f; ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release(); @@ -39,7 +39,7 @@ void Level::InitiateLevel(float radius) rigidBody->SetCustomTag(levelObj); - // add box + // add box API::SimpleBodyDescription sbDesc_TestBox; sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-5,15,0,0); sbDesc_TestBox.ignoreGravity = false; @@ -59,7 +59,7 @@ void Level::InitiateLevel(float radius) // add gravitation API::Gravity gravityWell; gravityWell.gravityType = API::Gravity::GravityType_Well; - gravityWell.well.mass = 10e16f; + gravityWell.well.mass = 1e15f; gravityWell.well.position = Oyster::Math::Float4(0,0,0,1); API::Instance().AddGravity(gravityWell); } diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 45ae8f65..ea36b284 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -86,24 +86,24 @@ void Player::Move(const PLAYER_MOVEMENT &movement) void Player::MoveForward() { - setState.ApplyLinearImpulse(this->lookDir * (20 * this->gameInstance->GetFrameTime())); + setState.ApplyLinearImpulse(this->lookDir * (2000 * this->gameInstance->GetFrameTime())); } void Player::MoveBackwards() { - setState.ApplyLinearImpulse(-this->lookDir * 20 * this->gameInstance->GetFrameTime()); + setState.ApplyLinearImpulse(-this->lookDir * 2000 * this->gameInstance->GetFrameTime()); } void Player::MoveRight() { //Do cross product with forward vector and negative gravity vector Oyster::Math::Float3 r = (-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)this->lookDir); - setState.ApplyLinearImpulse(r * 20 * this->gameInstance->GetFrameTime()); + setState.ApplyLinearImpulse(r * 2000 * this->gameInstance->GetFrameTime()); } void Player::MoveLeft() { //Do cross product with forward vector and negative gravity vector Oyster::Math::Float3 r = -(-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)this->lookDir); //Still get zero - setState.ApplyLinearImpulse(-r * 20 * this->gameInstance->GetFrameTime()); + setState.ApplyLinearImpulse(-r * 2000 * this->gameInstance->GetFrameTime()); } void Player::UseWeapon(const WEAPON_FIRE &usage) @@ -123,7 +123,7 @@ void Player::Rotate(const Oyster::Math3D::Float3 lookDir) { this->lookDir = lookDir; - Oyster::Math::Float4 up(0,1,0,0);//-setState.GetGravityNormal(); + Oyster::Math::Float4 up = -setState.GetGravityNormal(); Oyster::Math::Float4 pos = setState.GetCenterPosition(); Oyster::Math::Float4x4 world = Oyster::Math3D::OrientationMatrix_LookAtDirection(lookDir, up.xyz, pos.xyz); // cant set rotation diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl index 98b2887e..1efb94c6 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/LightPass.hlsl @@ -27,7 +27,9 @@ void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID ) Shaded.Specular += light.Specular; } - Diffuse[DTid.xy] = float4(Shaded.Diffuse * DiffuseGlow[DTid.xy].xyz,1); + //Diffuse[DTid.xy] = float4(Shaded.Diffuse * DiffuseGlow[DTid.xy].xyz,1); + Diffuse[DTid.xy] = float4(DiffuseGlow[DTid.xy].xyz,1); + Specular[DTid.xy] = float4(Shaded.Specular, 1); diff --git a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl index 2aaf2051..3e03dfcd 100644 --- a/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl +++ b/Code/OysterGraphics/Shader/HLSL/Deffered Shaders/PostPass.hlsl @@ -8,5 +8,7 @@ RWTexture2D Output; void main( uint3 DTid : SV_DispatchThreadID ) { Output[DTid.xy] = Diffuse[DTid.xy] + Specular[DTid.xy] + Diffuse[DTid.xy] * Ambient[DTid.xy/4].w;// + float4(Ambient[DTid.xy/4].xyz,1); GLOW + //Output[DTid.xy] = Diffuse[DTid.xy] + Diffuse[DTid.xy] * Ambient[DTid.xy/4].w;// + float4(Ambient[DTid.xy/4].xyz,1); GLOW + //Output[DTid.xy] = Diffuse[DTid.xy]; } \ No newline at end of file From 0aa39275e38f67f34262d0410c8a197cfa7deb29 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Thu, 30 Jan 2014 15:20:35 +0100 Subject: [PATCH 04/74] GL - only client with server update server. Update recieverfunction --- Code/Game/DanBiasGame/DanBiasGame_Impl.cpp | 16 ++++++++++------ .../GameClientState/GameClientState.h | 1 + .../DanBiasGame/GameClientState/GameState.cpp | 1 - .../DanBiasGame/GameClientState/LobbyState.cpp | 2 +- .../DanBiasGame/GameClientState/LoginState.cpp | 2 +- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp index 64526c0b..de790e8a 100644 --- a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp +++ b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp @@ -8,6 +8,7 @@ #include "GameClientState\LoginState.h" #include #include "NetworkClient.h" +#include #include "../WindowManager/WindowShell.h" #include "L_inputClass.h" @@ -38,6 +39,7 @@ namespace DanBias InputClass* inputObj; Utility::WinTimer* timer; GameRecieverObject* recieverObj; + bool serverOwner; } data; #pragma endregion @@ -62,13 +64,8 @@ namespace DanBias return DanBiasClientReturn_Error; 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 m_data->recieverObj->gameClientState = new Client::LoginState(); if(!m_data->recieverObj->gameClientState->Init(m_data->recieverObj)) @@ -133,8 +130,13 @@ namespace DanBias HRESULT DanBiasGame::Update(float deltaTime) { + m_data->recieverObj->Update(); m_data->inputObj->Update(); + if(m_data->serverOwner) + { + DanBias::GameServerAPI::ServerUpdate(); + } DanBias::Client::GameClientState::ClientState state = DanBias::Client::GameClientState::ClientState_Same; state = m_data->recieverObj->gameClientState->Update(deltaTime, m_data->inputObj); @@ -147,6 +149,8 @@ namespace DanBias switch (state) { + case Client::GameClientState::ClientState_LobbyCreated: + m_data->serverOwner = true; case Client::GameClientState::ClientState_Lobby: m_data->recieverObj->gameClientState = new Client::LobbyState(); break; diff --git a/Code/Game/DanBiasGame/GameClientState/GameClientState.h b/Code/Game/DanBiasGame/GameClientState/GameClientState.h index 28a671ba..a369233a 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameClientState.h +++ b/Code/Game/DanBiasGame/GameClientState/GameClientState.h @@ -53,6 +53,7 @@ public: { ClientState_Login, ClientState_Lobby, + ClientState_LobbyCreated, ClientState_Game, ClientState_Same, }; diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index 2e04959d..ee069919 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -144,7 +144,6 @@ bool GameState::InitCamera(Oyster::Math::Float3 startPos) GameClientState::ClientState GameState::Update(float deltaTime, InputClass* KeyInput) { - DanBias::GameServerAPI::ServerUpdate(); switch (privData->state) { case gameStateState_loading: diff --git a/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp b/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp index 260bf1be..938add5f 100644 --- a/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp @@ -87,7 +87,7 @@ GameClientState::ClientState LobbyState::Update(float deltaTime, InputClass* Key // update animation // send data to server // check data from server - DanBias::GameServerAPI::ServerUpdate(); + if( KeyInput->IsKeyPressed(DIK_G)) { diff --git a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp index 8fa4936d..cd1e4663 100644 --- a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp @@ -103,7 +103,7 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key // failed to connect return ClientState_Same; } - return ClientState_Lobby; + return ClientState_LobbyCreated; } // join game if( KeyInput->IsKeyPressed(DIK_J)) From 3b8a8e9c099815977f6772b133d3f1dedc949c58 Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Thu, 30 Jan 2014 23:22:46 +0100 Subject: [PATCH 05/74] Network - Fixed receiving parts of packages. --- Code/Network/NetworkAPI/NetworkClient.cpp | 89 ++++++++++++++++++- .../NetworkDependencies/OysterByte.cpp | 30 ++++++- Code/Network/NetworkDependencies/OysterByte.h | 5 +- 3 files changed, 117 insertions(+), 7 deletions(-) diff --git a/Code/Network/NetworkAPI/NetworkClient.cpp b/Code/Network/NetworkAPI/NetworkClient.cpp index 9539cdeb..fa9ad1af 100644 --- a/Code/Network/NetworkAPI/NetworkClient.cpp +++ b/Code/Network/NetworkAPI/NetworkClient.cpp @@ -16,11 +16,15 @@ #include "../../Misc/Utilities.h" #include "../../Misc/Thread/IThreadObject.h" #include "../../Misc/Thread/OysterThread.h" +#include "../../Misc/Packing/Packing.h" + +#include using namespace Oyster::Network; using namespace Oyster::Thread; using namespace Utility::DynamicMemory; using namespace Utility::Container; +using namespace std; /************************************* PrivateData @@ -35,11 +39,12 @@ struct NetworkClient::PrivateData : public IThreadObject Translator translator; OysterThread thread; + OysterByte recieveBuffer; //Message queue for sending and recieving ThreadSafeQueue sendQueue; ThreadSafeQueue> recieveQueue; - + //ID static unsigned int currID; const unsigned int ID; @@ -66,7 +71,7 @@ struct NetworkClient::PrivateData : public IThreadObject bool DoWork() override { if(!this->connection.IsConnected()) return false; - + Send(); Recv(); @@ -82,6 +87,7 @@ struct NetworkClient::PrivateData : public IThreadObject CustomNetProtocol p = this->sendQueue.Pop(); this->translator.Pack(temp, p); errorCode = this->connection.Send(temp); + if(errorCode != 0) { CEA parg; @@ -103,9 +109,13 @@ struct NetworkClient::PrivateData : public IThreadObject if(errorCode == 0 && temp.GetSize()) { + HandleRecievedData(temp); + + + /* Replaced with EmptyOutbufferedQueue() and HandleRecievedData(OysterByte) CustomNetProtocol protocol; bool ok = this->translator.Unpack(protocol, temp); - + //Check if the protocol was unpacked correctly if(ok) { @@ -114,7 +124,8 @@ struct NetworkClient::PrivateData : public IThreadObject parg.data.protocol = protocol; NetEvent e = { this->parent, parg }; this->recieveQueue.Push(e); - } + }*/ + } //else //{ @@ -127,6 +138,76 @@ struct NetworkClient::PrivateData : public IThreadObject 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() < 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 e = { this->parent, parg }; + this->recieveQueue.Push(e); + } + } }; unsigned int NetworkClient::PrivateData::currID = 0; diff --git a/Code/Network/NetworkDependencies/OysterByte.cpp b/Code/Network/NetworkDependencies/OysterByte.cpp index ac6923a2..7f64a30d 100644 --- a/Code/Network/NetworkDependencies/OysterByte.cpp +++ b/Code/Network/NetworkDependencies/OysterByte.cpp @@ -48,7 +48,7 @@ void OysterByte::Resize(unsigned int cap) } } -int OysterByte::GetSize() +unsigned int OysterByte::GetSize() { return size; } @@ -60,7 +60,7 @@ unsigned char* OysterByte::GetByteArray() void OysterByte::AddSize(unsigned int size) { - int newCapacity = this->size + size; + unsigned int newCapacity = this->size + size; if(newCapacity >= capacity) { @@ -81,6 +81,32 @@ void OysterByte::SetSize(unsigned int 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) { delete[] this->byteArray; diff --git a/Code/Network/NetworkDependencies/OysterByte.h b/Code/Network/NetworkDependencies/OysterByte.h index 4f6f4557..a3c0dfaf 100644 --- a/Code/Network/NetworkDependencies/OysterByte.h +++ b/Code/Network/NetworkDependencies/OysterByte.h @@ -25,7 +25,7 @@ namespace Oyster //Resizes the array with, it does not keep anything in it. void Resize(unsigned int cap); - int GetSize(); + unsigned int GetSize(); unsigned char* GetByteArray(); void AddSize(unsigned int size); @@ -34,6 +34,9 @@ namespace Oyster //Only sets the private variable '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); operator char*(); From 3c1eed0f3f51d1e685c48e087f48900459b7fc87 Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Thu, 30 Jan 2014 23:23:37 +0100 Subject: [PATCH 06/74] GL - Added LanMenuState --- Code/Game/DanBiasGame/DanBiasGame.vcxproj | 2 + Code/Game/DanBiasGame/DanBiasGame_Impl.cpp | 1 + .../GameClientState/LanMenuState.cpp | 164 ++++++++++++++++++ .../GameClientState/LanMenuState.h | 37 ++++ 4 files changed, 204 insertions(+) create mode 100644 Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp create mode 100644 Code/Game/DanBiasGame/GameClientState/LanMenuState.h diff --git a/Code/Game/DanBiasGame/DanBiasGame.vcxproj b/Code/Game/DanBiasGame/DanBiasGame.vcxproj index f1cbf970..01a92481 100644 --- a/Code/Game/DanBiasGame/DanBiasGame.vcxproj +++ b/Code/Game/DanBiasGame/DanBiasGame.vcxproj @@ -204,6 +204,7 @@ + @@ -217,6 +218,7 @@ + diff --git a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp index 64526c0b..522470cc 100644 --- a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp +++ b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp @@ -6,6 +6,7 @@ #include "GameClientState\GameState.h" #include "GameClientState\LobbyState.h" #include "GameClientState\LoginState.h" +#include "GameClientState\LanMenuState.h" #include #include "NetworkClient.h" diff --git a/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp b/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp new file mode 100644 index 00000000..fdb02fa9 --- /dev/null +++ b/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp @@ -0,0 +1,164 @@ +#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 + +using namespace DanBias::Client; + +struct LanMenuState::myData +{ + myData(){} + Oyster::Math3D::Float4x4 view; + Oyster::Math3D::Float4x4 proj; + C_Object* object[2]; + int modelCount; + // 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) +{ + // 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) +{ + +} \ No newline at end of file diff --git a/Code/Game/DanBiasGame/GameClientState/LanMenuState.h b/Code/Game/DanBiasGame/GameClientState/LanMenuState.h new file mode 100644 index 00000000..5182c80c --- /dev/null +++ b/Code/Game/DanBiasGame/GameClientState/LanMenuState.h @@ -0,0 +1,37 @@ +#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); + + 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 \ No newline at end of file From c30db71e94549342613aef5a5bc9f93539698e5a Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Fri, 31 Jan 2014 09:12:15 +0100 Subject: [PATCH 07/74] GL - more testing and changes to the level and using the physics API --- Code/Game/DanBiasGame/GameClientState/GameState.cpp | 2 +- Code/Game/GameLogic/CollisionManager.cpp | 7 +++++++ Code/Game/GameLogic/Game.cpp | 2 +- Code/Game/GameLogic/Game_PlayerData.cpp | 2 +- Code/Game/GameLogic/Level.cpp | 4 ++-- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index c5fb9d66..7a3f69ef 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -95,7 +95,7 @@ bool GameState::LoadModels(std::wstring mapFile) // add box model modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(-5,15,0)); + translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(4,320,0)); modelData.world = modelData.world * translate; modelData.modelPath = L"box.dan"; modelData.id = 1; diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 76ca668a..af7437da 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -84,6 +84,13 @@ using namespace GameLogic; Oyster::Math::Float3 pushForce = Oyster::Math::Float4(1,0,0) * (500); Oyster::Physics::ICustomBody::State state; Object *realObj = (Object*)obj->GetCustomTag(); + if(realObj->GetType() == OBJECT_TYPE_BOX) + { + state = obj->GetState(); + state.SetOrientation(Oyster::Math::Float3(1,0.5,1),Oyster::Math::Float3(1,0.5,1)); + obj->SetState(state); + } + if(realObj->GetType() == OBJECT_TYPE_PLAYER || realObj->GetType() == OBJECT_TYPE_WORLD) return; state = obj->GetState(); diff --git a/Code/Game/GameLogic/Game.cpp b/Code/Game/GameLogic/Game.cpp index 6bb4cdc9..063d173f 100644 --- a/Code/Game/GameLogic/Game.cpp +++ b/Code/Game/GameLogic/Game.cpp @@ -138,7 +138,7 @@ bool Game::NewFrame() if(this->players[i]->player) this->players[i]->player->EndFrame(); } - //gameInstance.onMoveFnc(this->level); + gameInstance.onMoveFnc(this->level); return true; } diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index 8dc29957..1b25b4f2 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -7,7 +7,7 @@ Game::PlayerData::PlayerData() { //set some stats that are appropriate to a player Oyster::Physics::API::SimpleBodyDescription sbDesc; - sbDesc.centerPosition = Oyster::Math::Float3(0,350,0); + sbDesc.centerPosition = Oyster::Math::Float3(0,320,0); sbDesc.size = Oyster::Math::Float3(4,7,4); sbDesc.mass = 10; //create rigid body diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index 8b2f3bf8..af96536c 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -41,7 +41,7 @@ void Level::InitiateLevel(float radius) // add box API::SimpleBodyDescription sbDesc_TestBox; - sbDesc_TestBox.centerPosition = Oyster::Math::Float4(-5,15,0,0); + sbDesc_TestBox.centerPosition = Oyster::Math::Float4(4,320,0,0); sbDesc_TestBox.ignoreGravity = false; sbDesc_TestBox.mass = 10; sbDesc_TestBox.size = Oyster::Math::Float4(0.5f,0.5f,0.5f,0); @@ -52,7 +52,7 @@ void Level::InitiateLevel(float radius) testBox = new DynamicObject(rigidBody_TestBox, OBJECT_TYPE::OBJECT_TYPE_BOX); rigidBody_TestBox->SetCustomTag(testBox); rigidBody_TestBox->GetState(state); - state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,4)); + state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,4000)); rigidBody_TestBox->SetState(state); From e718048f7f7bc871ead0329c7f3b1bae81f21d7d Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Fri, 31 Jan 2014 10:49:52 +0100 Subject: [PATCH 08/74] GL - Lan State --- Code/Game/DanBiasGame/DanBiasGame_Impl.cpp | 16 +++--- .../Game/DanBiasGame/GameClientRecieverFunc.h | 2 + .../GameClientState/GameClientState.h | 1 + .../GameClientState/LanMenuState.cpp | 51 +++++++++++++++++++ .../GameClientState/LanMenuState.h | 2 + .../GameClientState/LoginState.cpp | 5 ++ 6 files changed, 68 insertions(+), 9 deletions(-) diff --git a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp index 3a62ade1..b28a543f 100644 --- a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp +++ b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp @@ -38,7 +38,7 @@ namespace DanBias public: WindowShell* window; InputClass* inputObj; - Utility::WinTimer* timer; + Utility::WinTimer timer; GameRecieverObject* recieverObj; bool serverOwner; @@ -68,12 +68,11 @@ namespace DanBias m_data->serverOwner = false; // Start in lobby state - m_data->recieverObj->gameClientState = new Client::LoginState(); + m_data->recieverObj->gameClientState = new Client::LanMenuState(); if(!m_data->recieverObj->gameClientState->Init(m_data->recieverObj)) return DanBiasClientReturn_Error; - m_data->timer = new Utility::WinTimer(); //why dynamic memory? - m_data->timer->reset(); + m_data->timer.reset(); return DanBiasClientReturn_Sucess; } @@ -82,8 +81,8 @@ namespace DanBias // Main message loop while(m_data->window->Frame()) { - float dt = (float)m_data->timer->getElapsedSeconds(); - m_data->timer->reset(); + float dt = (float)m_data->timer.getElapsedSeconds(); + m_data->timer.reset(); capFrame += dt; if(capFrame > 0.03) @@ -130,8 +129,8 @@ namespace DanBias HRESULT DanBiasGame::Update(float deltaTime) { - - m_data->recieverObj->Update(); + if(m_data->recieverObj->IsConnected()) + m_data->recieverObj->Update(); m_data->inputObj->Update(); if(m_data->serverOwner) @@ -191,7 +190,6 @@ namespace DanBias delete m_data->recieverObj->gameClientState; m_data->recieverObj->Disconnect(); delete m_data->recieverObj; - delete m_data->timer; delete m_data->inputObj; delete m_data; diff --git a/Code/Game/DanBiasGame/GameClientRecieverFunc.h b/Code/Game/DanBiasGame/GameClientRecieverFunc.h index c5293738..2bd8c9a1 100644 --- a/Code/Game/DanBiasGame/GameClientRecieverFunc.h +++ b/Code/Game/DanBiasGame/GameClientRecieverFunc.h @@ -2,6 +2,8 @@ #define DANBIAS_CLIENTRECIEVEROBJECT_H //WTF!? No headers included??? +#include "../DanBiasGame/Include/DanBiasGame.h" +#include "../GameProtocols/GeneralProtocols.h" namespace DanBias { diff --git a/Code/Game/DanBiasGame/GameClientState/GameClientState.h b/Code/Game/DanBiasGame/GameClientState/GameClientState.h index a369233a..378eeefc 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameClientState.h +++ b/Code/Game/DanBiasGame/GameClientState/GameClientState.h @@ -53,6 +53,7 @@ public: { ClientState_Login, ClientState_Lobby, + ClientState_Lan, ClientState_LobbyCreated, ClientState_Game, ClientState_Same, diff --git a/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp b/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp index fdb02fa9..8df39bfa 100644 --- a/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp @@ -5,6 +5,10 @@ #include "C_obj/C_DynamicObj.h" #include "DllInterfaces/GFXAPI.h" +#include "LobbyState.h" +#include "GameState.h" +#include "../GameClientRecieverFunc.h" + #include using namespace DanBias::Client; @@ -16,6 +20,10 @@ struct LanMenuState::myData Oyster::Math3D::Float4x4 proj; C_Object* object[2]; int modelCount; + + GameRecieverObject* recieverObj; + bool serverOwner; + // UI object // game client* }privData; @@ -83,6 +91,49 @@ bool LanMenuState::InitCamera(Oyster::Math::Float3 startPos) } 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)) diff --git a/Code/Game/DanBiasGame/GameClientState/LanMenuState.h b/Code/Game/DanBiasGame/GameClientState/LanMenuState.h index 5182c80c..6b11fd20 100644 --- a/Code/Game/DanBiasGame/GameClientState/LanMenuState.h +++ b/Code/Game/DanBiasGame/GameClientState/LanMenuState.h @@ -17,6 +17,8 @@ namespace DanBias 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); diff --git a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp index cd1e4663..a5188306 100644 --- a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp @@ -88,6 +88,8 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key // send data to server // check data from server + + // create game if( KeyInput->IsKeyPressed(DIK_C)) { @@ -118,6 +120,9 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key } return ClientState_Lobby; } + + + return ClientState_Same; } bool LoginState::Render() From fa7f400c7157f84e02677bcc245c0e9702c4ca49 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Fri, 31 Jan 2014 10:58:03 +0100 Subject: [PATCH 09/74] GL - test this robin --- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 6 +++++- Code/Game/GameLogic/CollisionManager.cpp | 5 ++++- Code/Game/GameLogic/Game_PlayerData.cpp | 4 ++-- Code/Game/GameLogic/Level.cpp | 10 +++++----- Code/Game/GameLogic/Object.h | 1 + Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp | 2 +- 6 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index 7554c879..94efbb71 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -46,7 +46,11 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage, void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float dt) { //Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt); - Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); + + Oyster::Math::Float3 look = owner->GetLookDir(); + Oyster::Math::Float3 up = -owner->GetRigidBody()->GetGravityNormal(); + Oyster::Math::Float3 pos = owner->GetPosition(); + Oyster::Math::Float4x4 aim = Oyster::Math3D::OrientationMatrix_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)); int arg = 0; diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 27aa6db6..196aed09 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -20,7 +20,6 @@ using namespace GameLogic; Player *player = ((Game::PlayerData*)(rigidBodyPlayer->GetCustomTag()))->player; Object *realObj = (Object*)obj->GetCustomTag(); //needs to be changed? - return; switch (realObj->GetObjectType()) { case OBJECT_TYPE::OBJECT_TYPE_GENERIC: @@ -69,6 +68,10 @@ using namespace GameLogic; { 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 Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj) { diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index 18f57212..93fcfba6 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -7,9 +7,9 @@ Game::PlayerData::PlayerData() { //set some stats that are appropriate to a player Oyster::Physics::API::SimpleBodyDescription sbDesc; - sbDesc.centerPosition = Oyster::Math::Float3(0,320,0); + sbDesc.centerPosition = Oyster::Math::Float3(10,350,0); sbDesc.size = Oyster::Math::Float3(4,7,4); - sbDesc.mass = 10; + sbDesc.mass = 70; //create rigid body Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index c0b0685b..e09f9bb0 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -41,18 +41,18 @@ void Level::InitiateLevel(float radius) // add box API::SimpleBodyDescription sbDesc_TestBox; - sbDesc_TestBox.centerPosition = Oyster::Math::Float4(4,320,0,0); + sbDesc_TestBox.centerPosition = Oyster::Math::Float4(0,320,0,0); sbDesc_TestBox.ignoreGravity = false; - sbDesc_TestBox.mass = 10; - sbDesc_TestBox.size = Oyster::Math::Float4(0.5f,0.5f,0.5f,0); + sbDesc_TestBox.mass = 50; + sbDesc_TestBox.size = Oyster::Math::Float4(1,1,1,0); ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); - testBox = new DynamicObject(rigidBody_TestBox, OBJECT_TYPE::OBJECT_TYPE_BOX); + testBox = new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX); rigidBody_TestBox->SetCustomTag(testBox); rigidBody_TestBox->GetState(state); - state.ApplyLinearImpulse(Oyster::Math::Float3(0,20,0)); + state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,0)); rigidBody_TestBox->SetState(state); diff --git a/Code/Game/GameLogic/Object.h b/Code/Game/GameLogic/Object.h index 44b0ca48..d3a3690f 100644 --- a/Code/Game/GameLogic/Object.h +++ b/Code/Game/GameLogic/Object.h @@ -42,6 +42,7 @@ namespace GameLogic 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 DefaultCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); private: OBJECT_TYPE type; int objectID; diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 6f164810..5fa3a982 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -26,7 +26,7 @@ namespace ICustomBody::State protoState; proto->GetState( protoState ); ICustomBody::State deuterState; deuter->GetState( deuterState ); - Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact.xyz ), + Float4 protoG = protoState.GetLinearMomentum(worldPointOfContact.xyz ), deuterG = deuterState.GetLinearMomentum( worldPointOfContact.xyz ); // calc from perspective of deuter From c7bc7281d8502094cfb6b1ded01500713d6e40ff Mon Sep 17 00:00:00 2001 From: Robin Engman Date: Fri, 31 Jan 2014 13:41:06 +0100 Subject: [PATCH 10/74] Prefix for "sinking" objects --- .../Implementation/PhysicsAPI_Impl.cpp | 25 +++++++++++-------- Code/GamePhysics/PhysicsAPI.h | 2 +- Code/GamePhysics/PhysicsStructs.h | 4 ++- Code/OysterPhysics3D/OysterCollision3D.cpp | 4 +-- Code/OysterPhysics3D/RigidBody.cpp | 7 +++++- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 6f164810..30ced129 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -26,7 +26,7 @@ namespace ICustomBody::State protoState; proto->GetState( protoState ); ICustomBody::State deuterState; deuter->GetState( deuterState ); - Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact.xyz ), + Float4 protoG = protoState.GetLinearMomentum(worldPointOfContact.xyz ), deuterG = deuterState.GetLinearMomentum( worldPointOfContact.xyz ); // calc from perspective of deuter @@ -198,24 +198,27 @@ void API_Impl::Update() proto = updateList.begin(); 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.SetLinearImpulse( Float3(0, lM.y, lM.z) ); + state.linearMomentum.x = 0; } - if( lM.y < this->epsilon ) + if( abs(lM.y) < this->epsilon ) { - state.SetLinearMomentum( Float3(lM.x, 0, lM.z) ); - state.SetLinearImpulse( Float3(lM.x, 0, lM.z) ); + state.linearMomentum.y = 0; } - if( lM.z < this->epsilon ) + if( abs(lM.z) < this->epsilon ) { - state.SetLinearMomentum( Float3(lM.x, lM.y, 0) ); - state.SetLinearImpulse( Float3(lM.x, lM.y, 0) ); + state.linearMomentum.z = 0; } + (*proto)->SetState( state ); + switch( (*proto)->Update(this->updateFrameLength) ) { case UpdateState_altered: diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h index 78b65f5e..080b8d30 100644 --- a/Code/GamePhysics/PhysicsAPI.h +++ b/Code/GamePhysics/PhysicsAPI.h @@ -34,7 +34,7 @@ namespace Oyster namespace Constant { 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 diff --git a/Code/GamePhysics/PhysicsStructs.h b/Code/GamePhysics/PhysicsStructs.h index 00c07b2d..aef157a8 100644 --- a/Code/GamePhysics/PhysicsStructs.h +++ b/Code/GamePhysics/PhysicsStructs.h @@ -115,11 +115,13 @@ namespace Oyster { namespace Physics bool IsDisturbed() const; bool IsForwarded() const; + ::Oyster::Math::Float3 linearMomentum; + private: ::Oyster::Math::Float mass, restitutionCoeff, staticFrictionCoeff, kineticFrictionCoeff; ::Oyster::Physics3D::MomentOfInertia inertiaTensor; ::Oyster::Math::Float3 reach, centerPos, angularAxis; - ::Oyster::Math::Float3 linearMomentum, angularMomentum; + ::Oyster::Math::Float3 angularMomentum; ::Oyster::Math::Float3 linearImpulse, angularImpulse; ::Oyster::Math::Float3 deltaPos, deltaAxis; // Forwarding data sum ::Oyster::Math::Float3 gravityNormal; diff --git a/Code/OysterPhysics3D/OysterCollision3D.cpp b/Code/OysterPhysics3D/OysterCollision3D.cpp index 169b5add..89b3af8a 100644 --- a/Code/OysterPhysics3D/OysterCollision3D.cpp +++ b/Code/OysterPhysics3D/OysterCollision3D.cpp @@ -784,8 +784,8 @@ namespace Oyster { namespace Collision3D { namespace Utility if( Intersect(box, sphere) ) { Float distance; - Ray ray( box.center, sphere.center - box.center ); - + Ray ray( box.center, (sphere.center - box.center).Normalize() ); + Intersect( sphere, ray, distance ); worldPointOfContact = ray.origin + ray.direction*distance; return true; diff --git a/Code/OysterPhysics3D/RigidBody.cpp b/Code/OysterPhysics3D/RigidBody.cpp index 0c60c597..f053e8dd 100644 --- a/Code/OysterPhysics3D/RigidBody.cpp +++ b/Code/OysterPhysics3D/RigidBody.cpp @@ -50,7 +50,12 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength ) // updating the linear // 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 ); + Float3 deltaPos = ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear ); + if( deltaPos.GetLength() < 0.001f ) + { + deltaPos = Float3::null; + } + this->centerPos += deltaPos; // updating the angular // dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H From 190f7e28829dfd35e857eb18ae50ef31b4be12a8 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Fri, 31 Jan 2014 13:42:17 +0100 Subject: [PATCH 11/74] SnapAngularAxis introduced --- Code/OysterMath/LinearMath.h | 15 +++++++++++++++ Code/OysterMath/OysterMath.h | 1 + 2 files changed, 16 insertions(+) diff --git a/Code/OysterMath/LinearMath.h b/Code/OysterMath/LinearMath.h index 50bcd36b..2fa66e26 100644 --- a/Code/OysterMath/LinearMath.h +++ b/Code/OysterMath/LinearMath.h @@ -325,6 +325,12 @@ namespace LinearAlgebra2D namespace LinearAlgebra3D { + template + inline ::LinearAlgebra::Vector3 WorldAxisOf( const ::LinearAlgebra::Quaternion &rotation, const ::LinearAlgebra::Vector3 &localAxis ) + { + return (rotation*localAxis*rotation.GetConjugate()).imaginary; + } + // All Matrix to AngularAxis conversions here is incorrect //template //inline ::LinearAlgebra::Vector4 AngularAxis( const ::LinearAlgebra::Matrix3x3 &rotationMatrix ) @@ -741,6 +747,15 @@ namespace LinearAlgebra3D inline ::LinearAlgebra::Vector4 NormalProjection( const ::LinearAlgebra::Vector4 &vector, const ::LinearAlgebra::Vector4 &normalizedAxis ) { return normalizedAxis * ( vector.Dot(normalizedAxis) ); } + template + ::LinearAlgebra::Vector3 & SnapAngularAxis( ::LinearAlgebra::Vector4 &startAngularAxis, const ::LinearAlgebra::Vector4 &localStartNormal, const ::LinearAlgebra::Vector4 &worldEndNormal, ::LinearAlgebra::Vector3 &targetMem = ::LinearAlgebra::Vector3() ) + { + ::LinearAlgebra::Vector4 worldStartNormal( WorldAxisOf(Rotation(startAngularAxis), localStartNormal), (ScalarType)0 ); + targetMem = worldStartNormal.xyz.Cross(worldEndNormal.xyz); + targetMem *= (ScalarType)::std::asin( worldStartNormal.Dot(worldEndNormal) ); + return targetMem; + } + template ::LinearAlgebra::Matrix4x4 & SnapAxisYToNormal_UsingNlerp( ::LinearAlgebra::Matrix4x4 &rotation, const ::LinearAlgebra::Vector4 &normalizedAxis ) { diff --git a/Code/OysterMath/OysterMath.h b/Code/OysterMath/OysterMath.h index 5970face..7e123183 100644 --- a/Code/OysterMath/OysterMath.h +++ b/Code/OysterMath/OysterMath.h @@ -324,6 +324,7 @@ namespace Oyster { namespace Math3D //! Oyster's native math library specialized using ::LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp; using ::LinearAlgebra3D::InterpolateOrientation_UsingNonRigidNlerp; using ::LinearAlgebra3D::InterpolateOrientation_UsingSlerp; + using ::LinearAlgebra3D::SnapAngularAxis; } } #endif \ No newline at end of file From ac635ccaef70d5fd1229141ca8c5a608bbfd1305 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Fri, 31 Jan 2014 13:47:40 +0100 Subject: [PATCH 12/74] SnapAngularAxis fix --- Code/OysterMath/LinearMath.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/OysterMath/LinearMath.h b/Code/OysterMath/LinearMath.h index 2fa66e26..0ec46b5c 100644 --- a/Code/OysterMath/LinearMath.h +++ b/Code/OysterMath/LinearMath.h @@ -748,12 +748,12 @@ namespace LinearAlgebra3D { return normalizedAxis * ( vector.Dot(normalizedAxis) ); } template - ::LinearAlgebra::Vector3 & SnapAngularAxis( ::LinearAlgebra::Vector4 &startAngularAxis, const ::LinearAlgebra::Vector4 &localStartNormal, const ::LinearAlgebra::Vector4 &worldEndNormal, ::LinearAlgebra::Vector3 &targetMem = ::LinearAlgebra::Vector3() ) + ::LinearAlgebra::Vector4 & SnapAngularAxis( ::LinearAlgebra::Vector4 &startAngularAxis, const ::LinearAlgebra::Vector4 &localStartNormal, const ::LinearAlgebra::Vector4 &worldEndNormal, ::LinearAlgebra::Vector4 &targetMem = ::LinearAlgebra::Vector4() ) { ::LinearAlgebra::Vector4 worldStartNormal( WorldAxisOf(Rotation(startAngularAxis), localStartNormal), (ScalarType)0 ); - targetMem = worldStartNormal.xyz.Cross(worldEndNormal.xyz); + targetMem = ::LinearAlgebra::Vector4( worldStartNormal.xyz.Cross(worldEndNormal.xyz), (ScalarType)0); targetMem *= (ScalarType)::std::asin( worldStartNormal.Dot(worldEndNormal) ); - return targetMem; + return targetMem += startAngularAxis; } template From 7a62121fa0f8ea5d0fbdf125f47276100282141c Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Fri, 31 Jan 2014 13:49:09 +0100 Subject: [PATCH 13/74] SnapAngularAxis fix accidently used asin instead of acos --- Code/OysterMath/LinearMath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/OysterMath/LinearMath.h b/Code/OysterMath/LinearMath.h index 0ec46b5c..9ea4bf42 100644 --- a/Code/OysterMath/LinearMath.h +++ b/Code/OysterMath/LinearMath.h @@ -752,7 +752,7 @@ namespace LinearAlgebra3D { ::LinearAlgebra::Vector4 worldStartNormal( WorldAxisOf(Rotation(startAngularAxis), localStartNormal), (ScalarType)0 ); targetMem = ::LinearAlgebra::Vector4( worldStartNormal.xyz.Cross(worldEndNormal.xyz), (ScalarType)0); - targetMem *= (ScalarType)::std::asin( worldStartNormal.Dot(worldEndNormal) ); + targetMem *= (ScalarType)::std::acos( worldStartNormal.Dot(worldEndNormal) ); return targetMem += startAngularAxis; } From 57c230d45848c3233ffc72dd23b7bc9dd0cf0009 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Fri, 31 Jan 2014 13:56:22 +0100 Subject: [PATCH 14/74] GL - will merge with physics --- Code/Game/DanBiasGame/GameClientRecieverFunc.h | 12 ++++++++++++ Code/Game/DanBiasGame/GameClientState/LobbyState.h | 1 + Code/Game/DanBiasGame/GameClientState/LoginState.cpp | 2 +- Code/Game/GameLogic/CollisionManager.cpp | 6 ------ Code/Game/GameLogic/Level.cpp | 2 +- 5 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientRecieverFunc.h b/Code/Game/DanBiasGame/GameClientRecieverFunc.h index 36b831a0..ef65e46a 100644 --- a/Code/Game/DanBiasGame/GameClientRecieverFunc.h +++ b/Code/Game/DanBiasGame/GameClientRecieverFunc.h @@ -100,6 +100,18 @@ namespace DanBias ((Client::GameState*)gameClientState)->Protocol(&protocolData); } break; + case protocol_Lobby_Start: + { + /* + if(dynamic_cast(gameClientState)) + { + gameClientState->Release(); + delete gameClientState; + gameClientState = new Client::GameState(); + gameClientState->Init(m_data->recieverObj); + }*/ + } + break; default: break; diff --git a/Code/Game/DanBiasGame/GameClientState/LobbyState.h b/Code/Game/DanBiasGame/GameClientState/LobbyState.h index 057fc850..6a8d9772 100644 --- a/Code/Game/DanBiasGame/GameClientState/LobbyState.h +++ b/Code/Game/DanBiasGame/GameClientState/LobbyState.h @@ -36,6 +36,7 @@ public: bool Release(); void Protocol(ProtocolStruct* protocol)override; void PlayerJoinProtocol(PlayerName* name); + void GameStarted(); };};}; #endif // ! DANBIAS_CLIENT_GAMECLIENTSTATE_H diff --git a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp index cd1e4663..4d1079bc 100644 --- a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp @@ -109,7 +109,7 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key if( KeyInput->IsKeyPressed(DIK_J)) { // game ip - nwClient->Connect(15151, "194.47.150.56"); + nwClient->Connect(15151, "193.11.184.109"); if (!nwClient->IsConnected()) { diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 196aed09..f343720e 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -87,12 +87,6 @@ using namespace GameLogic; Oyster::Math::Float3 pushForce = Oyster::Math::Float4(1,0,0) * (500); Oyster::Physics::ICustomBody::State state; Object *realObj = (Object*)obj->GetCustomTag(); - if(realObj->GetObjectType() == OBJECT_TYPE_BOX) - { - state = obj->GetState(); - state.SetOrientation(Oyster::Math::Float3(1,0.5,1),Oyster::Math::Float3(1,0.5,1)); - obj->SetState(state); - } if(realObj->GetObjectType() == OBJECT_TYPE_PLAYER || realObj->GetObjectType() == OBJECT_TYPE_WORLD) return; diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index e09f9bb0..e95f95c6 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -44,7 +44,7 @@ void Level::InitiateLevel(float radius) sbDesc_TestBox.centerPosition = Oyster::Math::Float4(0,320,0,0); sbDesc_TestBox.ignoreGravity = false; sbDesc_TestBox.mass = 50; - sbDesc_TestBox.size = Oyster::Math::Float4(1,1,1,0); + sbDesc_TestBox.size = Oyster::Math::Float4(4,4,4,0); ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); From 16a342da49a821c1d0d4aff11a5729073abda907 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Fri, 31 Jan 2014 14:05:52 +0100 Subject: [PATCH 15/74] GL - adjusting in GL, added forcepushData struct for passing args when shooting. connect changes in network --- Code/Game/DanBiasGame/GameClientState/LobbyState.cpp | 4 ++-- Code/Game/DanBiasGame/GameClientState/LoginState.cpp | 2 +- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 8 +++++--- Code/Game/GameLogic/CollisionManager.cpp | 11 ++--------- Code/Game/GameLogic/GameLogicStates.h | 7 +++++++ Code/Game/GameLogic/Game_PlayerData.cpp | 2 +- Code/Game/GameLogic/Level.cpp | 2 +- 7 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp b/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp index 35a5f295..c1cc4ae1 100644 --- a/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp @@ -91,8 +91,8 @@ GameClientState::ClientState LobbyState::Update(float deltaTime, InputClass* Key if( KeyInput->IsKeyPressed(DIK_G)) { - if(!DanBias::GameServerAPI::GameStart()) - return GameClientState::ClientState_Same; + //if(!DanBias::GameServerAPI::GameStart()) + //return GameClientState::ClientState_Same; return ClientState_Game; } diff --git a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp index cd1e4663..4d1079bc 100644 --- a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp @@ -109,7 +109,7 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key if( KeyInput->IsKeyPressed(DIK_J)) { // game ip - nwClient->Connect(15151, "194.47.150.56"); + nwClient->Connect(15151, "193.11.184.109"); if (!nwClient->IsConnected()) { diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index 7554c879..839293d9 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -1,5 +1,6 @@ #include "AttatchmentMassDriver.h" #include "PhysicsAPI.h" +#include "GameLogicStates.h" using namespace GameLogic; @@ -45,13 +46,14 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage, ********************************************************/ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float dt) { - //Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt); + Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt); Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); 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; + forcePushData args; + args.pushForce = pushForce; - Oyster::Physics::API::Instance().ApplyEffect(hitFrustum,&arg,ForcePushAction); + Oyster::Physics::API::Instance().ApplyEffect(hitFrustum,&args,ForcePushAction); } /******************************************************** diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 27aa6db6..512be3d6 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -81,20 +81,13 @@ using namespace GameLogic; void AttatchmentMassDriver::ForcePushAction(Oyster::Physics::ICustomBody *obj, void *args) { - Oyster::Math::Float3 pushForce = Oyster::Math::Float4(1,0,0) * (500); Oyster::Physics::ICustomBody::State state; Object *realObj = (Object*)obj->GetCustomTag(); - if(realObj->GetObjectType() == OBJECT_TYPE_BOX) - { - state = obj->GetState(); - state.SetOrientation(Oyster::Math::Float3(1,0.5,1),Oyster::Math::Float3(1,0.5,1)); - obj->SetState(state); - } if(realObj->GetObjectType() == OBJECT_TYPE_PLAYER || realObj->GetObjectType() == OBJECT_TYPE_WORLD) return; + state = obj->GetState(); - state.ApplyLinearImpulse(pushForce); + state.ApplyLinearImpulse(((forcePushData*)(args))->pushForce); obj->SetState(state); - //((Object*)obj->GetCustomTag())->ApplyLinearImpulse(pushForce); } \ No newline at end of file diff --git a/Code/Game/GameLogic/GameLogicStates.h b/Code/Game/GameLogic/GameLogicStates.h index 2b0d0b8b..00c2e7ff 100644 --- a/Code/Game/GameLogic/GameLogicStates.h +++ b/Code/Game/GameLogic/GameLogicStates.h @@ -1,5 +1,6 @@ #ifndef GAMELOGICSTATES_H #define GAMELOGICSTATES_H +#include "OysterMath.h" namespace GameLogic { @@ -46,6 +47,12 @@ namespace GameLogic WEAPON_STATE_RELOADING = 2, }; + struct forcePushData + { + Oyster::Math::Float3 pushForce; + }; + + }; diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index 18f57212..72f9ea1f 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -9,7 +9,7 @@ Game::PlayerData::PlayerData() Oyster::Physics::API::SimpleBodyDescription sbDesc; sbDesc.centerPosition = Oyster::Math::Float3(0,320,0); sbDesc.size = Oyster::Math::Float3(4,7,4); - sbDesc.mass = 10; + sbDesc.mass = 90; //create rigid body Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index c0b0685b..78633444 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -44,7 +44,7 @@ void Level::InitiateLevel(float radius) sbDesc_TestBox.centerPosition = Oyster::Math::Float4(4,320,0,0); sbDesc_TestBox.ignoreGravity = false; sbDesc_TestBox.mass = 10; - sbDesc_TestBox.size = Oyster::Math::Float4(0.5f,0.5f,0.5f,0); + sbDesc_TestBox.size = Oyster::Math::Float4(4,4,4,0); ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); From b753387649ba6eec14ca1d6514ce5ab0cd94274d Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Fri, 31 Jan 2014 14:14:20 +0100 Subject: [PATCH 16/74] asd --- .merge_file_a01532 | 171 ++++++++++++++++++ .merge_file_a04876 | 93 ++++++++++ .merge_file_a05028 | 66 +++++++ .merge_file_a06880 | 171 ++++++++++++++++++ .merge_file_a07272 | 98 ++++++++++ .merge_file_a07484 | 81 +++++++++ .merge_file_a07992 | 93 ++++++++++ .merge_file_a08280 | 66 +++++++ .merge_file_a08532 | 96 ++++++++++ .merge_file_a08608 | 166 +++++++++++++++++ .merge_file_a09540 | 100 ++++++++++ .merge_file_a11072 | 70 +++++++ .merge_file_a11132 | 70 +++++++ .merge_file_a11320 | 103 +++++++++++ .merge_file_a11560 | 74 ++++++++ Code/Game/DanBiasGame/DanBiasGame_Impl.cpp | 15 +- .../Game/DanBiasGame/GameClientRecieverFunc.h | 6 +- .../GameClientState/GameClientState.h | 1 + .../GameClientState/LanMenuState.cpp | 51 ++++++ .../GameClientState/LanMenuState.h | 2 + Code/Game/GameLogic/Object.h | 1 + .../Implementation/PhysicsAPI_Impl.cpp | 2 +- Code/Misc/EventHandler/EventButton.cpp | 0 Code/Misc/EventHandler/EventButton.h | 0 .../EventHandler/EventButtonCollection.cpp | 25 +++ .../Misc/EventHandler/EventButtonCollection.h | 31 ++++ Code/Misc/EventHandler/EventHandler.cpp | 37 ++++ Code/Misc/EventHandler/EventHandler.h | 35 ++++ Code/Misc/Misc.vcxproj | 6 + Code/Misc/Misc.vcxproj.filters | 18 ++ 30 files changed, 1737 insertions(+), 11 deletions(-) create mode 100644 .merge_file_a01532 create mode 100644 .merge_file_a04876 create mode 100644 .merge_file_a05028 create mode 100644 .merge_file_a06880 create mode 100644 .merge_file_a07272 create mode 100644 .merge_file_a07484 create mode 100644 .merge_file_a07992 create mode 100644 .merge_file_a08280 create mode 100644 .merge_file_a08532 create mode 100644 .merge_file_a08608 create mode 100644 .merge_file_a09540 create mode 100644 .merge_file_a11072 create mode 100644 .merge_file_a11132 create mode 100644 .merge_file_a11320 create mode 100644 .merge_file_a11560 create mode 100644 Code/Misc/EventHandler/EventButton.cpp create mode 100644 Code/Misc/EventHandler/EventButton.h create mode 100644 Code/Misc/EventHandler/EventButtonCollection.cpp create mode 100644 Code/Misc/EventHandler/EventButtonCollection.h create mode 100644 Code/Misc/EventHandler/EventHandler.cpp create mode 100644 Code/Misc/EventHandler/EventHandler.h diff --git a/.merge_file_a01532 b/.merge_file_a01532 new file mode 100644 index 00000000..0a50fbd0 --- /dev/null +++ b/.merge_file_a01532 @@ -0,0 +1,171 @@ +#include "LoginState.h" +#include "DllInterfaces/GFXAPI.h" +#include "OysterMath.h" +#include "C_obj/C_Player.h" +#include "C_obj/C_StaticObj.h" +#include "C_obj/C_DynamicObj.h" +#include + +using namespace DanBias::Client; + +struct LoginState::myData +{ + myData(){} + Oyster::Math3D::Float4x4 view; + Oyster::Math3D::Float4x4 proj; + C_Object* object[2]; + int modelCount; + // UI object + // game client* +}privData; + +LoginState::LoginState(void) +{ + +} + +LoginState::~LoginState(void) +{ + +} + +bool LoginState::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 LoginState::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 LoginState::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 LoginState::Update(float deltaTime, InputClass* KeyInput) +{ + // picking + // mouse events + // different menus + // play sounds + // update animation + // send data to server + // check data from server + + + + // 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_LobbyCreated; + } + // join game + if( KeyInput->IsKeyPressed(DIK_J)) + { + // game ip + nwClient->Connect(15151, "193.11.184.109"); + + if (!nwClient->IsConnected()) + { + // failed to connect + return ClientState_Same; + } + return ClientState_Lobby; + } + + + + return ClientState_Same; +} +bool LoginState::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 LoginState::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 LoginState::Protocol(ProtocolStruct* protocol) +{ + if((PlayerName*)protocol) + PlayerJoinProtocol((PlayerName*)protocol); + +} +void LoginState::PlayerJoinProtocol(PlayerName* name) +{ + +} \ No newline at end of file diff --git a/.merge_file_a04876 b/.merge_file_a04876 new file mode 100644 index 00000000..c0b0685b --- /dev/null +++ b/.merge_file_a04876 @@ -0,0 +1,93 @@ +#include "Level.h" +#include "CollisionManager.h" + +using namespace GameLogic; +using namespace Utility::DynamicMemory; +using namespace Oyster::Physics; + + +Level::Level(void) +{ + +} +Level::~Level(void) +{ +} + +void Level::InitiateLevel(std::string levelPath) +{ + +} +void Level::InitiateLevel(float radius) +{ + + // add level sphere + API::SphericalBodyDescription sbDesc; + sbDesc.centerPosition = Oyster::Math::Float4(0,0,0,1); + sbDesc.ignoreGravity = true; + sbDesc.radius = 300; + sbDesc.mass = 10e12f; + + ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release(); + + ICustomBody::State state; + rigidBody->GetState(state); + state.SetRestitutionCoeff(0.01); + rigidBody->SetState(state); + + levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD); + rigidBody->SetCustomTag(levelObj); + + + // add box + API::SimpleBodyDescription sbDesc_TestBox; + sbDesc_TestBox.centerPosition = Oyster::Math::Float4(4,320,0,0); + 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(); + rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); + + testBox = new DynamicObject(rigidBody_TestBox, OBJECT_TYPE::OBJECT_TYPE_BOX); + rigidBody_TestBox->SetCustomTag(testBox); + rigidBody_TestBox->GetState(state); + state.ApplyLinearImpulse(Oyster::Math::Float3(0,20,0)); + rigidBody_TestBox->SetState(state); + + + // add gravitation + API::Gravity gravityWell; + gravityWell.gravityType = API::Gravity::GravityType_Well; + gravityWell.well.mass = 1e15f; + gravityWell.well.position = Oyster::Math::Float4(0,0,0,1); + API::Instance().AddGravity(gravityWell); +} + +void Level::AddPlayerToTeam(Player *player, int teamID) +{ + this->teamManager.AddPlayerToTeam(player,teamID); +} + +void Level::CreateTeam(int teamSize) +{ + this->teamManager.CreateTeam(teamSize); +} + +void Level::RespawnPlayer(Player *player) +{ + this->teamManager.RespawnPlayerRandom(player); +} + +Object* Level::GetObj( int ID) const +{ + if( ID == 0 ) + return (Object*)levelObj; + else + return (Object*)testBox; +} +void Level::PhysicsOnMoveLevel(const ICustomBody *object) +{ + // function call from physics update when object was moved + Object* temp = (Object*)object->GetCustomTag(); +} diff --git a/.merge_file_a05028 b/.merge_file_a05028 new file mode 100644 index 00000000..93fcfba6 --- /dev/null +++ b/.merge_file_a05028 @@ -0,0 +1,66 @@ +#include "Game.h" +#include "Player.h" + +using namespace GameLogic; + +Game::PlayerData::PlayerData() +{ + //set some stats that are appropriate to a player + Oyster::Physics::API::SimpleBodyDescription sbDesc; + sbDesc.centerPosition = Oyster::Math::Float3(10,350,0); + sbDesc.size = Oyster::Math::Float3(4,7,4); + sbDesc.mass = 70; + //create rigid body + Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); + + //create player with this rigid body + this->player = new Player(rigidBody,Object::DefaultCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER); + this->player->GetRigidBody()->SetCustomTag(this); + +} +Game::PlayerData::PlayerData(int playerID,int teamID) +{ + this->player = new Player(); +} +Game::PlayerData::~PlayerData() +{ + delete this->player; +} + +void Game::PlayerData::Move(const PLAYER_MOVEMENT &movement) +{ + this->player->Move(movement); +} +void Game::PlayerData::UseWeapon(const WEAPON_FIRE &usage) +{ + this->player->UseWeapon(usage); +} +Oyster::Math::Float3 Game::PlayerData::GetPosition() +{ + return this->player->GetPosition(); +} +Oyster::Math::Float4x4 Game::PlayerData::GetOrientation() +{ + return this->player->GetOrientation(); +} +PLAYER_STATE Game::PlayerData::GetState() const +{ + return this->player->GetState(); +} +int Game::PlayerData::GetID() const +{ + return this->player->GetID(); +} +int Game::PlayerData::GetTeamID() const +{ + return this->player->GetTeamID(); +} + +OBJECT_TYPE Game::PlayerData::GetObjectType() const +{ + return this->player->GetObjectType(); +} +void Game::PlayerData::Rotate(const Oyster::Math3D::Float3 lookDir) +{ + this->player->Rotate(lookDir); +} \ No newline at end of file diff --git a/.merge_file_a06880 b/.merge_file_a06880 new file mode 100644 index 00000000..a5188306 --- /dev/null +++ b/.merge_file_a06880 @@ -0,0 +1,171 @@ +#include "LoginState.h" +#include "DllInterfaces/GFXAPI.h" +#include "OysterMath.h" +#include "C_obj/C_Player.h" +#include "C_obj/C_StaticObj.h" +#include "C_obj/C_DynamicObj.h" +#include + +using namespace DanBias::Client; + +struct LoginState::myData +{ + myData(){} + Oyster::Math3D::Float4x4 view; + Oyster::Math3D::Float4x4 proj; + C_Object* object[2]; + int modelCount; + // UI object + // game client* +}privData; + +LoginState::LoginState(void) +{ + +} + +LoginState::~LoginState(void) +{ + +} + +bool LoginState::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 LoginState::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 LoginState::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 LoginState::Update(float deltaTime, InputClass* KeyInput) +{ + // picking + // mouse events + // different menus + // play sounds + // update animation + // send data to server + // check data from server + + + + // 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_LobbyCreated; + } + // 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 LoginState::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 LoginState::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 LoginState::Protocol(ProtocolStruct* protocol) +{ + if((PlayerName*)protocol) + PlayerJoinProtocol((PlayerName*)protocol); + +} +void LoginState::PlayerJoinProtocol(PlayerName* name) +{ + +} \ No newline at end of file diff --git a/.merge_file_a07272 b/.merge_file_a07272 new file mode 100644 index 00000000..93c41976 --- /dev/null +++ b/.merge_file_a07272 @@ -0,0 +1,98 @@ +#include "Level.h" +#include "CollisionManager.h" + +using namespace GameLogic; +using namespace Utility::DynamicMemory; +using namespace Oyster::Physics; + + +Level::Level(void) +{ + +} +Level::~Level(void) +{ +} + +void Level::InitiateLevel(std::string levelPath) +{ + +} +void Level::InitiateLevel(float radius) +{ + + // add level sphere + API::SphericalBodyDescription sbDesc; + sbDesc.centerPosition = Oyster::Math::Float4(0,0,0,1); + sbDesc.ignoreGravity = true; + sbDesc.radius = 300; + sbDesc.mass = 10e12f; + + ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release(); + + ICustomBody::State state; + rigidBody->GetState(state); + state.SetRestitutionCoeff(0.01); + rigidBody->SetState(state); + + levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD); + rigidBody->SetCustomTag(levelObj); + + + // add box + API::SimpleBodyDescription sbDesc_TestBox; + sbDesc_TestBox.centerPosition = Oyster::Math::Float4(0,320,0,0); + sbDesc_TestBox.ignoreGravity = false; +<<<<<<< .merge_file_a07272 + sbDesc_TestBox.mass = 10; + sbDesc_TestBox.size = Oyster::Math::Float4(4,4,4,0); +======= + sbDesc_TestBox.mass = 50; + sbDesc_TestBox.size = Oyster::Math::Float4(1,1,1,0); +>>>>>>> .merge_file_a07992 + + ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); + rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); + + testBox = new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX); + rigidBody_TestBox->SetCustomTag(testBox); + rigidBody_TestBox->GetState(state); + state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,0)); + rigidBody_TestBox->SetState(state); + + + // add gravitation + API::Gravity gravityWell; + gravityWell.gravityType = API::Gravity::GravityType_Well; + gravityWell.well.mass = 1e15f; + gravityWell.well.position = Oyster::Math::Float4(0,0,0,1); + API::Instance().AddGravity(gravityWell); +} + +void Level::AddPlayerToTeam(Player *player, int teamID) +{ + this->teamManager.AddPlayerToTeam(player,teamID); +} + +void Level::CreateTeam(int teamSize) +{ + this->teamManager.CreateTeam(teamSize); +} + +void Level::RespawnPlayer(Player *player) +{ + this->teamManager.RespawnPlayerRandom(player); +} + +Object* Level::GetObj( int ID) const +{ + if( ID == 0 ) + return (Object*)levelObj; + else + return (Object*)testBox; +} +void Level::PhysicsOnMoveLevel(const ICustomBody *object) +{ + // function call from physics update when object was moved + Object* temp = (Object*)object->GetCustomTag(); +} diff --git a/.merge_file_a07484 b/.merge_file_a07484 new file mode 100644 index 00000000..f0a2a4d6 --- /dev/null +++ b/.merge_file_a07484 @@ -0,0 +1,81 @@ +#include "AttatchmentMassDriver.h" +#include "PhysicsAPI.h" +#include "GameLogicStates.h" + +using namespace GameLogic; + + + +AttatchmentMassDriver::AttatchmentMassDriver(void) +{ + this->owner = 0; +} + +AttatchmentMassDriver::AttatchmentMassDriver(Player &owner) +{ + + this->owner = &owner; +} + + +AttatchmentMassDriver::~AttatchmentMassDriver(void) +{ + +} + +/******************************************************** +* Uses the attatchment and will from here switch case the different WEAPON_FIRE's that are to be used +********************************************************/ +void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage, float dt) +{ + //switch case to determin what functionallity to use in the attatchment + switch (usage) + { + case WEAPON_FIRE::WEAPON_USE_PRIMARY_PRESS: + ForcePush(usage,dt); + break; + case WEAPON_FIRE::WEAPON_USE_SECONDARY_PRESS: + ForcePull(usage,dt); + break; + } + +} + +/******************************************************** +* Pushes objects in a cone in front of the weapon when fired +********************************************************/ +void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float dt) +{ +<<<<<<< .merge_file_a07484 + Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt); + Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); +======= + //Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt); + + Oyster::Math::Float3 look = owner->GetLookDir(); + Oyster::Math::Float3 up = -owner->GetRigidBody()->GetGravityNormal(); + Oyster::Math::Float3 pos = owner->GetPosition(); + Oyster::Math::Float4x4 aim = Oyster::Math3D::OrientationMatrix_LookAtDirection(owner->GetLookDir(), -owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); +>>>>>>> .merge_file_a11560 + 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); +} + +/******************************************************** +* 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) +{ + Oyster::Physics::Struct::CustomBodyState state = this->owner->GetRigidBody()->GetState(); + + //do something with state + state.ApplyLinearImpulse(Oyster::Math::Float3(this->owner->GetLookDir()) * (500 * dt)); + + this->owner->GetRigidBody()->SetState(state); +} + + diff --git a/.merge_file_a07992 b/.merge_file_a07992 new file mode 100644 index 00000000..e09f9bb0 --- /dev/null +++ b/.merge_file_a07992 @@ -0,0 +1,93 @@ +#include "Level.h" +#include "CollisionManager.h" + +using namespace GameLogic; +using namespace Utility::DynamicMemory; +using namespace Oyster::Physics; + + +Level::Level(void) +{ + +} +Level::~Level(void) +{ +} + +void Level::InitiateLevel(std::string levelPath) +{ + +} +void Level::InitiateLevel(float radius) +{ + + // add level sphere + API::SphericalBodyDescription sbDesc; + sbDesc.centerPosition = Oyster::Math::Float4(0,0,0,1); + sbDesc.ignoreGravity = true; + sbDesc.radius = 300; + sbDesc.mass = 10e12f; + + ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release(); + + ICustomBody::State state; + rigidBody->GetState(state); + state.SetRestitutionCoeff(0.01); + rigidBody->SetState(state); + + levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD); + rigidBody->SetCustomTag(levelObj); + + + // add box + API::SimpleBodyDescription sbDesc_TestBox; + sbDesc_TestBox.centerPosition = Oyster::Math::Float4(0,320,0,0); + sbDesc_TestBox.ignoreGravity = false; + sbDesc_TestBox.mass = 50; + sbDesc_TestBox.size = Oyster::Math::Float4(1,1,1,0); + + ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); + rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); + + testBox = new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX); + rigidBody_TestBox->SetCustomTag(testBox); + rigidBody_TestBox->GetState(state); + state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,0)); + rigidBody_TestBox->SetState(state); + + + // add gravitation + API::Gravity gravityWell; + gravityWell.gravityType = API::Gravity::GravityType_Well; + gravityWell.well.mass = 1e15f; + gravityWell.well.position = Oyster::Math::Float4(0,0,0,1); + API::Instance().AddGravity(gravityWell); +} + +void Level::AddPlayerToTeam(Player *player, int teamID) +{ + this->teamManager.AddPlayerToTeam(player,teamID); +} + +void Level::CreateTeam(int teamSize) +{ + this->teamManager.CreateTeam(teamSize); +} + +void Level::RespawnPlayer(Player *player) +{ + this->teamManager.RespawnPlayerRandom(player); +} + +Object* Level::GetObj( int ID) const +{ + if( ID == 0 ) + return (Object*)levelObj; + else + return (Object*)testBox; +} +void Level::PhysicsOnMoveLevel(const ICustomBody *object) +{ + // function call from physics update when object was moved + Object* temp = (Object*)object->GetCustomTag(); +} diff --git a/.merge_file_a08280 b/.merge_file_a08280 new file mode 100644 index 00000000..18f57212 --- /dev/null +++ b/.merge_file_a08280 @@ -0,0 +1,66 @@ +#include "Game.h" +#include "Player.h" + +using namespace GameLogic; + +Game::PlayerData::PlayerData() +{ + //set some stats that are appropriate to a player + Oyster::Physics::API::SimpleBodyDescription sbDesc; + sbDesc.centerPosition = Oyster::Math::Float3(0,320,0); + sbDesc.size = Oyster::Math::Float3(4,7,4); + sbDesc.mass = 10; + //create rigid body + Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); + + //create player with this rigid body + this->player = new Player(rigidBody,Object::DefaultCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER); + this->player->GetRigidBody()->SetCustomTag(this); + +} +Game::PlayerData::PlayerData(int playerID,int teamID) +{ + this->player = new Player(); +} +Game::PlayerData::~PlayerData() +{ + delete this->player; +} + +void Game::PlayerData::Move(const PLAYER_MOVEMENT &movement) +{ + this->player->Move(movement); +} +void Game::PlayerData::UseWeapon(const WEAPON_FIRE &usage) +{ + this->player->UseWeapon(usage); +} +Oyster::Math::Float3 Game::PlayerData::GetPosition() +{ + return this->player->GetPosition(); +} +Oyster::Math::Float4x4 Game::PlayerData::GetOrientation() +{ + return this->player->GetOrientation(); +} +PLAYER_STATE Game::PlayerData::GetState() const +{ + return this->player->GetState(); +} +int Game::PlayerData::GetID() const +{ + return this->player->GetID(); +} +int Game::PlayerData::GetTeamID() const +{ + return this->player->GetTeamID(); +} + +OBJECT_TYPE Game::PlayerData::GetObjectType() const +{ + return this->player->GetObjectType(); +} +void Game::PlayerData::Rotate(const Oyster::Math3D::Float3 lookDir) +{ + this->player->Rotate(lookDir); +} \ No newline at end of file diff --git a/.merge_file_a08532 b/.merge_file_a08532 new file mode 100644 index 00000000..019df6f4 --- /dev/null +++ b/.merge_file_a08532 @@ -0,0 +1,96 @@ +#include "PhysicsAPI.h" +#include "Object.h" +#include "DynamicObject.h" +#include "Player.h" +#include "Level.h" +#include "AttatchmentMassDriver.h" +#include "Game.h" + +using namespace Oyster; + +using namespace GameLogic; + + void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss); + void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss); + + //Physics::ICustomBody::SubscriptMessage + void Player::PlayerCollision(Oyster::Physics::ICustomBody *rigidBodyPlayer, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) + { + + Player *player = ((Game::PlayerData*)(rigidBodyPlayer->GetCustomTag()))->player; + Object *realObj = (Object*)obj->GetCustomTag(); //needs to be changed? + + switch (realObj->GetObjectType()) + { + case OBJECT_TYPE::OBJECT_TYPE_GENERIC: + PlayerVObject(*player,*realObj, kineticEnergyLoss); + //return Physics::ICustomBody::SubscriptMessage_none; + break; + + case OBJECT_TYPE::OBJECT_TYPE_BOX: + PlayerVBox(*player,(*(DynamicObject*) realObj), kineticEnergyLoss); + //return Physics::ICustomBody::SubscriptMessage_none; + break; + case OBJECT_TYPE::OBJECT_TYPE_PLAYER: + //return Physics::ICustomBody::SubscriptMessage_none; + break; + case OBJECT_TYPE::OBJECT_TYPE_WORLD: + int test = 5; + break; + } + + //return Physics::ICustomBody::SubscriptMessage_none; + } + + void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss) + { + //use kinetic energyloss of the collision in order too determin how much damage to take + //use as part of the damage algorithm + player.DamageLife(20); + } + + void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss) + { + //Collision between a player and a general static or dynamic object + //use kinetic energyloss of the collision in order too determin how much damage to take + //use as part of the damage algorithm + int damageDone = 0; + int forceThreashHold = 200; + + if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough + { + damageDone = kineticEnergyLoss * 0.10f; + player.DamageLife(damageDone); + } + + } + Oyster::Physics::ICustomBody::SubscriptMessage Object::DefaultCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj) + { + 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 + Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj) + { + return Physics::ICustomBody::SubscriptMessage_ignore_collision_response; + } + Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) + { + return Physics::ICustomBody::SubscriptMessage_ignore_collision_response; + } + + void AttatchmentMassDriver::ForcePushAction(Oyster::Physics::ICustomBody *obj, void *args) + { + 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.ApplyLinearImpulse(((forcePushData*)(args))->pushForce); + obj->SetState(state); + } \ No newline at end of file diff --git a/.merge_file_a08608 b/.merge_file_a08608 new file mode 100644 index 00000000..cd1e4663 --- /dev/null +++ b/.merge_file_a08608 @@ -0,0 +1,166 @@ +#include "LoginState.h" +#include "DllInterfaces/GFXAPI.h" +#include "OysterMath.h" +#include "C_obj/C_Player.h" +#include "C_obj/C_StaticObj.h" +#include "C_obj/C_DynamicObj.h" +#include + +using namespace DanBias::Client; + +struct LoginState::myData +{ + myData(){} + Oyster::Math3D::Float4x4 view; + Oyster::Math3D::Float4x4 proj; + C_Object* object[2]; + int modelCount; + // UI object + // game client* +}privData; + +LoginState::LoginState(void) +{ + +} + +LoginState::~LoginState(void) +{ + +} + +bool LoginState::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 LoginState::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 LoginState::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 LoginState::Update(float deltaTime, InputClass* KeyInput) +{ + // picking + // mouse events + // different menus + // play sounds + // update animation + // send data to server + // check data from server + + // 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_LobbyCreated; + } + // 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 LoginState::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 LoginState::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 LoginState::Protocol(ProtocolStruct* protocol) +{ + if((PlayerName*)protocol) + PlayerJoinProtocol((PlayerName*)protocol); + +} +void LoginState::PlayerJoinProtocol(PlayerName* name) +{ + +} \ No newline at end of file diff --git a/.merge_file_a09540 b/.merge_file_a09540 new file mode 100644 index 00000000..27aa6db6 --- /dev/null +++ b/.merge_file_a09540 @@ -0,0 +1,100 @@ +#include "PhysicsAPI.h" +#include "Object.h" +#include "DynamicObject.h" +#include "Player.h" +#include "Level.h" +#include "AttatchmentMassDriver.h" +#include "Game.h" + +using namespace Oyster; + +using namespace GameLogic; + + void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss); + void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss); + + //Physics::ICustomBody::SubscriptMessage + void Player::PlayerCollision(Oyster::Physics::ICustomBody *rigidBodyPlayer, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) + { + + Player *player = ((Game::PlayerData*)(rigidBodyPlayer->GetCustomTag()))->player; + Object *realObj = (Object*)obj->GetCustomTag(); //needs to be changed? + + return; + switch (realObj->GetObjectType()) + { + case OBJECT_TYPE::OBJECT_TYPE_GENERIC: + PlayerVObject(*player,*realObj, kineticEnergyLoss); + //return Physics::ICustomBody::SubscriptMessage_none; + break; + + case OBJECT_TYPE::OBJECT_TYPE_BOX: + PlayerVBox(*player,(*(DynamicObject*) realObj), kineticEnergyLoss); + //return Physics::ICustomBody::SubscriptMessage_none; + break; + case OBJECT_TYPE::OBJECT_TYPE_PLAYER: + //return Physics::ICustomBody::SubscriptMessage_none; + break; + case OBJECT_TYPE::OBJECT_TYPE_WORLD: + int test = 5; + break; + } + + //return Physics::ICustomBody::SubscriptMessage_none; + } + + void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss) + { + //use kinetic energyloss of the collision in order too determin how much damage to take + //use as part of the damage algorithm + player.DamageLife(20); + } + + void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss) + { + //Collision between a player and a general static or dynamic object + //use kinetic energyloss of the collision in order too determin how much damage to take + //use as part of the damage algorithm + int damageDone = 0; + int forceThreashHold = 200; + + if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough + { + damageDone = kineticEnergyLoss * 0.10f; + player.DamageLife(damageDone); + } + + } + Oyster::Physics::ICustomBody::SubscriptMessage Object::DefaultCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj) + { + return Physics::ICustomBody::SubscriptMessage_none; + } + //Oyster::Physics::ICustomBody::SubscriptMessage + Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj) + { + return Physics::ICustomBody::SubscriptMessage_ignore_collision_response; + } + Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) + { + return Physics::ICustomBody::SubscriptMessage_ignore_collision_response; + } + + void AttatchmentMassDriver::ForcePushAction(Oyster::Physics::ICustomBody *obj, void *args) + { + Oyster::Math::Float3 pushForce = Oyster::Math::Float4(1,0,0) * (500); + Oyster::Physics::ICustomBody::State state; + Object *realObj = (Object*)obj->GetCustomTag(); + if(realObj->GetObjectType() == OBJECT_TYPE_BOX) + { + state = obj->GetState(); + state.SetOrientation(Oyster::Math::Float3(1,0.5,1),Oyster::Math::Float3(1,0.5,1)); + obj->SetState(state); + } + + if(realObj->GetObjectType() == OBJECT_TYPE_PLAYER || realObj->GetObjectType() == OBJECT_TYPE_WORLD) + return; + state = obj->GetState(); + state.ApplyLinearImpulse(pushForce); + obj->SetState(state); + //((Object*)obj->GetCustomTag())->ApplyLinearImpulse(pushForce); + } \ No newline at end of file diff --git a/.merge_file_a11072 b/.merge_file_a11072 new file mode 100644 index 00000000..4f47006e --- /dev/null +++ b/.merge_file_a11072 @@ -0,0 +1,70 @@ +#include "Game.h" +#include "Player.h" + +using namespace GameLogic; + +Game::PlayerData::PlayerData() +{ + //set some stats that are appropriate to a player + Oyster::Physics::API::SimpleBodyDescription sbDesc; + sbDesc.centerPosition = Oyster::Math::Float3(10,350,0); + sbDesc.size = Oyster::Math::Float3(4,7,4); +<<<<<<< .merge_file_a11072 + sbDesc.mass = 90; +======= + sbDesc.mass = 70; +>>>>>>> .merge_file_a05028 + //create rigid body + Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); + + //create player with this rigid body + this->player = new Player(rigidBody,Object::DefaultCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER); + this->player->GetRigidBody()->SetCustomTag(this); + +} +Game::PlayerData::PlayerData(int playerID,int teamID) +{ + this->player = new Player(); +} +Game::PlayerData::~PlayerData() +{ + delete this->player; +} + +void Game::PlayerData::Move(const PLAYER_MOVEMENT &movement) +{ + this->player->Move(movement); +} +void Game::PlayerData::UseWeapon(const WEAPON_FIRE &usage) +{ + this->player->UseWeapon(usage); +} +Oyster::Math::Float3 Game::PlayerData::GetPosition() +{ + return this->player->GetPosition(); +} +Oyster::Math::Float4x4 Game::PlayerData::GetOrientation() +{ + return this->player->GetOrientation(); +} +PLAYER_STATE Game::PlayerData::GetState() const +{ + return this->player->GetState(); +} +int Game::PlayerData::GetID() const +{ + return this->player->GetID(); +} +int Game::PlayerData::GetTeamID() const +{ + return this->player->GetTeamID(); +} + +OBJECT_TYPE Game::PlayerData::GetObjectType() const +{ + return this->player->GetObjectType(); +} +void Game::PlayerData::Rotate(const Oyster::Math3D::Float3 lookDir) +{ + this->player->Rotate(lookDir); +} \ No newline at end of file diff --git a/.merge_file_a11132 b/.merge_file_a11132 new file mode 100644 index 00000000..7554c879 --- /dev/null +++ b/.merge_file_a11132 @@ -0,0 +1,70 @@ +#include "AttatchmentMassDriver.h" +#include "PhysicsAPI.h" + +using namespace GameLogic; + + + +AttatchmentMassDriver::AttatchmentMassDriver(void) +{ + this->owner = 0; +} + +AttatchmentMassDriver::AttatchmentMassDriver(Player &owner) +{ + + this->owner = &owner; +} + + +AttatchmentMassDriver::~AttatchmentMassDriver(void) +{ + +} + +/******************************************************** +* Uses the attatchment and will from here switch case the different WEAPON_FIRE's that are to be used +********************************************************/ +void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage, float dt) +{ + //switch case to determin what functionallity to use in the attatchment + switch (usage) + { + case WEAPON_FIRE::WEAPON_USE_PRIMARY_PRESS: + ForcePush(usage,dt); + break; + case WEAPON_FIRE::WEAPON_USE_SECONDARY_PRESS: + ForcePull(usage,dt); + break; + } + +} + +/******************************************************** +* Pushes objects in a cone in front of the weapon when fired +********************************************************/ +void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float dt) +{ + //Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt); + Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); + 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); +} + +/******************************************************** +* 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) +{ + Oyster::Physics::Struct::CustomBodyState state = this->owner->GetRigidBody()->GetState(); + + //do something with state + state.ApplyLinearImpulse(Oyster::Math::Float3(this->owner->GetLookDir()) * (500 * dt)); + + this->owner->GetRigidBody()->SetState(state); +} + + diff --git a/.merge_file_a11320 b/.merge_file_a11320 new file mode 100644 index 00000000..196aed09 --- /dev/null +++ b/.merge_file_a11320 @@ -0,0 +1,103 @@ +#include "PhysicsAPI.h" +#include "Object.h" +#include "DynamicObject.h" +#include "Player.h" +#include "Level.h" +#include "AttatchmentMassDriver.h" +#include "Game.h" + +using namespace Oyster; + +using namespace GameLogic; + + void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss); + void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss); + + //Physics::ICustomBody::SubscriptMessage + void Player::PlayerCollision(Oyster::Physics::ICustomBody *rigidBodyPlayer, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) + { + + Player *player = ((Game::PlayerData*)(rigidBodyPlayer->GetCustomTag()))->player; + Object *realObj = (Object*)obj->GetCustomTag(); //needs to be changed? + + switch (realObj->GetObjectType()) + { + case OBJECT_TYPE::OBJECT_TYPE_GENERIC: + PlayerVObject(*player,*realObj, kineticEnergyLoss); + //return Physics::ICustomBody::SubscriptMessage_none; + break; + + case OBJECT_TYPE::OBJECT_TYPE_BOX: + PlayerVBox(*player,(*(DynamicObject*) realObj), kineticEnergyLoss); + //return Physics::ICustomBody::SubscriptMessage_none; + break; + case OBJECT_TYPE::OBJECT_TYPE_PLAYER: + //return Physics::ICustomBody::SubscriptMessage_none; + break; + case OBJECT_TYPE::OBJECT_TYPE_WORLD: + int test = 5; + break; + } + + //return Physics::ICustomBody::SubscriptMessage_none; + } + + void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss) + { + //use kinetic energyloss of the collision in order too determin how much damage to take + //use as part of the damage algorithm + player.DamageLife(20); + } + + void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss) + { + //Collision between a player and a general static or dynamic object + //use kinetic energyloss of the collision in order too determin how much damage to take + //use as part of the damage algorithm + int damageDone = 0; + int forceThreashHold = 200; + + if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough + { + damageDone = kineticEnergyLoss * 0.10f; + player.DamageLife(damageDone); + } + + } + Oyster::Physics::ICustomBody::SubscriptMessage Object::DefaultCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj) + { + 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 + Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj) + { + return Physics::ICustomBody::SubscriptMessage_ignore_collision_response; + } + Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) + { + return Physics::ICustomBody::SubscriptMessage_ignore_collision_response; + } + + void AttatchmentMassDriver::ForcePushAction(Oyster::Physics::ICustomBody *obj, void *args) + { + Oyster::Math::Float3 pushForce = Oyster::Math::Float4(1,0,0) * (500); + Oyster::Physics::ICustomBody::State state; + Object *realObj = (Object*)obj->GetCustomTag(); + if(realObj->GetObjectType() == OBJECT_TYPE_BOX) + { + state = obj->GetState(); + state.SetOrientation(Oyster::Math::Float3(1,0.5,1),Oyster::Math::Float3(1,0.5,1)); + obj->SetState(state); + } + + if(realObj->GetObjectType() == OBJECT_TYPE_PLAYER || realObj->GetObjectType() == OBJECT_TYPE_WORLD) + return; + state = obj->GetState(); + state.ApplyLinearImpulse(pushForce); + obj->SetState(state); + //((Object*)obj->GetCustomTag())->ApplyLinearImpulse(pushForce); + } \ No newline at end of file diff --git a/.merge_file_a11560 b/.merge_file_a11560 new file mode 100644 index 00000000..94efbb71 --- /dev/null +++ b/.merge_file_a11560 @@ -0,0 +1,74 @@ +#include "AttatchmentMassDriver.h" +#include "PhysicsAPI.h" + +using namespace GameLogic; + + + +AttatchmentMassDriver::AttatchmentMassDriver(void) +{ + this->owner = 0; +} + +AttatchmentMassDriver::AttatchmentMassDriver(Player &owner) +{ + + this->owner = &owner; +} + + +AttatchmentMassDriver::~AttatchmentMassDriver(void) +{ + +} + +/******************************************************** +* Uses the attatchment and will from here switch case the different WEAPON_FIRE's that are to be used +********************************************************/ +void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage, float dt) +{ + //switch case to determin what functionallity to use in the attatchment + switch (usage) + { + case WEAPON_FIRE::WEAPON_USE_PRIMARY_PRESS: + ForcePush(usage,dt); + break; + case WEAPON_FIRE::WEAPON_USE_SECONDARY_PRESS: + ForcePull(usage,dt); + break; + } + +} + +/******************************************************** +* Pushes objects in a cone in front of the weapon when fired +********************************************************/ +void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float dt) +{ + //Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt); + + Oyster::Math::Float3 look = owner->GetLookDir(); + Oyster::Math::Float3 up = -owner->GetRigidBody()->GetGravityNormal(); + Oyster::Math::Float3 pos = owner->GetPosition(); + Oyster::Math::Float4x4 aim = Oyster::Math3D::OrientationMatrix_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)); + int arg = 0; + + Oyster::Physics::API::Instance().ApplyEffect(hitFrustum,&arg,ForcePushAction); +} + +/******************************************************** +* 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) +{ + Oyster::Physics::Struct::CustomBodyState state = this->owner->GetRigidBody()->GetState(); + + //do something with state + state.ApplyLinearImpulse(Oyster::Math::Float3(this->owner->GetLookDir()) * (500 * dt)); + + this->owner->GetRigidBody()->SetState(state); +} + + diff --git a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp index 06f200bf..4a54297f 100644 --- a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp +++ b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp @@ -38,7 +38,7 @@ namespace DanBias public: WindowShell* window; InputClass* inputObj; - Utility::WinTimer* timer; + Utility::WinTimer timer; GameRecieverObject* recieverObj; bool serverOwner; @@ -69,12 +69,11 @@ namespace DanBias m_data->serverOwner = false; // 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)) return DanBiasClientReturn_Error; - m_data->timer = new Utility::WinTimer(); //why dynamic memory? - m_data->timer->reset(); + m_data->timer.reset(); return DanBiasClientReturn_Sucess; } @@ -83,8 +82,8 @@ namespace DanBias // Main message loop while(m_data->window->Frame()) { - float dt = (float)m_data->timer->getElapsedSeconds(); - m_data->timer->reset(); + float dt = (float)m_data->timer.getElapsedSeconds(); + m_data->timer.reset(); capFrame += dt; if(capFrame > 0.03) @@ -131,8 +130,9 @@ namespace DanBias HRESULT DanBiasGame::Update(float deltaTime) { + if(m_data->recieverObj->IsConnected()) + m_data->recieverObj->Update(); - m_data->recieverObj->Update(); m_data->inputObj->Update(); if(m_data->serverOwner) @@ -192,7 +192,6 @@ namespace DanBias delete m_data->recieverObj->gameClientState; m_data->recieverObj->Disconnect(); delete m_data->recieverObj; - delete m_data->timer; delete m_data->inputObj; delete m_data; diff --git a/Code/Game/DanBiasGame/GameClientRecieverFunc.h b/Code/Game/DanBiasGame/GameClientRecieverFunc.h index 36b831a0..de8f63a6 100644 --- a/Code/Game/DanBiasGame/GameClientRecieverFunc.h +++ b/Code/Game/DanBiasGame/GameClientRecieverFunc.h @@ -2,6 +2,8 @@ #define DANBIAS_CLIENTRECIEVEROBJECT_H //WTF!? No headers included??? +#include "../DanBiasGame/Include/DanBiasGame.h" +#include "../GameProtocols/GeneralProtocols.h" namespace DanBias { @@ -128,8 +130,8 @@ namespace DanBias break; case protocol_Lobby_GameData: //this->LobbyGameData (Protocol_LobbyGameData (p), c); { - GameLogic::Protocol_LobbyGameData temp(p); - printf("%s, %i.%i\n", temp.mapName.c_str(), temp.majorVersion, temp.minorVersion); + //GameLogic::Protocol_LobbyGameData temp(p); + //printf("%s, %i.%i\n", temp.mapName.c_str(), temp.majorVersion, temp.minorVersion); } break; case protocol_Lobby_ClientData: //this->LobbyMainData (Protocol_LobbyClientData (p), c); diff --git a/Code/Game/DanBiasGame/GameClientState/GameClientState.h b/Code/Game/DanBiasGame/GameClientState/GameClientState.h index a369233a..378eeefc 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameClientState.h +++ b/Code/Game/DanBiasGame/GameClientState/GameClientState.h @@ -53,6 +53,7 @@ public: { ClientState_Login, ClientState_Lobby, + ClientState_Lan, ClientState_LobbyCreated, ClientState_Game, ClientState_Same, diff --git a/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp b/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp index fdb02fa9..8df39bfa 100644 --- a/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp @@ -5,6 +5,10 @@ #include "C_obj/C_DynamicObj.h" #include "DllInterfaces/GFXAPI.h" +#include "LobbyState.h" +#include "GameState.h" +#include "../GameClientRecieverFunc.h" + #include using namespace DanBias::Client; @@ -16,6 +20,10 @@ struct LanMenuState::myData Oyster::Math3D::Float4x4 proj; C_Object* object[2]; int modelCount; + + GameRecieverObject* recieverObj; + bool serverOwner; + // UI object // game client* }privData; @@ -83,6 +91,49 @@ bool LanMenuState::InitCamera(Oyster::Math::Float3 startPos) } 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)) diff --git a/Code/Game/DanBiasGame/GameClientState/LanMenuState.h b/Code/Game/DanBiasGame/GameClientState/LanMenuState.h index 5182c80c..6b11fd20 100644 --- a/Code/Game/DanBiasGame/GameClientState/LanMenuState.h +++ b/Code/Game/DanBiasGame/GameClientState/LanMenuState.h @@ -17,6 +17,8 @@ namespace DanBias 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); diff --git a/Code/Game/GameLogic/Object.h b/Code/Game/GameLogic/Object.h index 44b0ca48..d3a3690f 100644 --- a/Code/Game/GameLogic/Object.h +++ b/Code/Game/GameLogic/Object.h @@ -42,6 +42,7 @@ namespace GameLogic 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 DefaultCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); private: OBJECT_TYPE type; int objectID; diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 6f164810..5fa3a982 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -26,7 +26,7 @@ namespace ICustomBody::State protoState; proto->GetState( protoState ); ICustomBody::State deuterState; deuter->GetState( deuterState ); - Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact.xyz ), + Float4 protoG = protoState.GetLinearMomentum(worldPointOfContact.xyz ), deuterG = deuterState.GetLinearMomentum( worldPointOfContact.xyz ); // calc from perspective of deuter diff --git a/Code/Misc/EventHandler/EventButton.cpp b/Code/Misc/EventHandler/EventButton.cpp new file mode 100644 index 00000000..e69de29b diff --git a/Code/Misc/EventHandler/EventButton.h b/Code/Misc/EventHandler/EventButton.h new file mode 100644 index 00000000..e69de29b diff --git a/Code/Misc/EventHandler/EventButtonCollection.cpp b/Code/Misc/EventHandler/EventButtonCollection.cpp new file mode 100644 index 00000000..b3d37bfe --- /dev/null +++ b/Code/Misc/EventHandler/EventButtonCollection.cpp @@ -0,0 +1,25 @@ +#include "EventButtonCollection.h" + +using namespace Oyster::Event; + +EventButtonCollection::EventButtonCollection() +{ + +} + +EventButtonCollection::~EventButtonCollection() +{ +} + +void EventButtonCollection::Update(InputClass* inputObject) +{ + for(int i = 0; i < buttons.size(); i++) + { + buttons.at(i)->Update(inputObject); + } +} + +EventButton* EventButtonCollection::AddButton(EventButton* button) +{ + +} \ No newline at end of file diff --git a/Code/Misc/EventHandler/EventButtonCollection.h b/Code/Misc/EventHandler/EventButtonCollection.h new file mode 100644 index 00000000..31201f9c --- /dev/null +++ b/Code/Misc/EventHandler/EventButtonCollection.h @@ -0,0 +1,31 @@ +#ifndef EVENT_BUTTON_COLLECTION_H +#define EVENT_BUTTON_COLLECTION_H + +#include "../../Input/L_inputClass.h" + +#include "EventButton.h" + +#include + +namespace Oyster +{ + namespace Event + { + class EventButtonCollection + { + public: + EventButtonCollection(); + ~EventButtonCollection(); + + void Update(InputClass* inputObject); + + EventButton* AddButton(EventButton* button); + + private: + std::vector buttons; + + }; + } +} + +#endif \ No newline at end of file diff --git a/Code/Misc/EventHandler/EventHandler.cpp b/Code/Misc/EventHandler/EventHandler.cpp new file mode 100644 index 00000000..8f6705df --- /dev/null +++ b/Code/Misc/EventHandler/EventHandler.cpp @@ -0,0 +1,37 @@ +#include "EventHandler.h" + +using namespace Oyster::Event; + +EventHandler EvtHandler; + +EventHandler& EventHandler::Instance() +{ + return EvtHandler; +} + +EventHandler::EventHandler() +{ + +} + +EventHandler::~EventHandler() +{ +} + +void EventHandler::Update(InputClass* inputObject) +{ + for(int i = 0; i < collections.size(); i++) + { + collections.at(i)->Update(inputObject); + } +} + +EventButtonCollection* EventHandler::CreateCollection() +{ + +} + +EventButtonCollection* EventHandler::GetCollection(/*ID*/); +{ + +} \ No newline at end of file diff --git a/Code/Misc/EventHandler/EventHandler.h b/Code/Misc/EventHandler/EventHandler.h new file mode 100644 index 00000000..c3ecc0a2 --- /dev/null +++ b/Code/Misc/EventHandler/EventHandler.h @@ -0,0 +1,35 @@ +#ifndef EVENT_HANDLER_H +#define EVENT_HANDLER_H + +#include "../../Input/L_inputClass.h" + +#include "EventButtonCollection.h" +#include "EventButton.h" + +#include + +namespace Oyster +{ + namespace Event + { + class EventHandler + { + EventHandler(); + ~EventHandler(); + + EventHandler& Instance(); + + void Update(InputClass* inputObject); + + EventButtonCollection* CreateCollection(); + EventButtonCollection* GetCollection(/*ID*/); + + + private: + std::vector collections; + + }; + } +} + +#endif \ No newline at end of file diff --git a/Code/Misc/Misc.vcxproj b/Code/Misc/Misc.vcxproj index 6c3db1ec..52b7c96c 100644 --- a/Code/Misc/Misc.vcxproj +++ b/Code/Misc/Misc.vcxproj @@ -146,6 +146,9 @@ + + + @@ -162,8 +165,11 @@ + + + diff --git a/Code/Misc/Misc.vcxproj.filters b/Code/Misc/Misc.vcxproj.filters index 8413642a..d4874b4c 100644 --- a/Code/Misc/Misc.vcxproj.filters +++ b/Code/Misc/Misc.vcxproj.filters @@ -51,6 +51,15 @@ Source Files + + Source Files + + + Source Files + + + Source Files + @@ -116,5 +125,14 @@ Header Files + + Header Files + + + Header Files + + + Header Files + \ No newline at end of file From 79872a45eeb1a0bc64213f185a84e92e82379578 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Fri, 31 Jan 2014 14:27:33 +0100 Subject: [PATCH 17/74] SnapAngularAxis fix + added overload compilation error fix + Float3 version --- Code/OysterMath/LinearMath.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Code/OysterMath/LinearMath.h b/Code/OysterMath/LinearMath.h index 9ea4bf42..7874cb52 100644 --- a/Code/OysterMath/LinearMath.h +++ b/Code/OysterMath/LinearMath.h @@ -750,12 +750,20 @@ namespace LinearAlgebra3D template ::LinearAlgebra::Vector4 & SnapAngularAxis( ::LinearAlgebra::Vector4 &startAngularAxis, const ::LinearAlgebra::Vector4 &localStartNormal, const ::LinearAlgebra::Vector4 &worldEndNormal, ::LinearAlgebra::Vector4 &targetMem = ::LinearAlgebra::Vector4() ) { - ::LinearAlgebra::Vector4 worldStartNormal( WorldAxisOf(Rotation(startAngularAxis), localStartNormal), (ScalarType)0 ); + ::LinearAlgebra::Vector4 worldStartNormal( WorldAxisOf(Rotation(startAngularAxis.xyz), localStartNormal), (ScalarType)0 ); targetMem = ::LinearAlgebra::Vector4( worldStartNormal.xyz.Cross(worldEndNormal.xyz), (ScalarType)0); targetMem *= (ScalarType)::std::acos( worldStartNormal.Dot(worldEndNormal) ); return targetMem += startAngularAxis; } + template + ::LinearAlgebra::Vector3 & SnapAngularAxis( ::LinearAlgebra::Vector3 &startAngularAxis, const ::LinearAlgebra::Vector3 &localStartNormal, const ::LinearAlgebra::Vector3 &worldEndNormal, ::LinearAlgebra::Vector3 &targetMem = ::LinearAlgebra::Vector3() ) + { + return targetMem = SnapAngularAxis( ::LinearAlgebra::Vector4(startAngularAxis, (ScalarType)0), + ::LinearAlgebra::Vector4(localStartNormal, (ScalarType)0), + ::LinearAlgebra::Vector4(worldEndNormal, (ScalarType)0), ).xyz; + } + template ::LinearAlgebra::Matrix4x4 & SnapAxisYToNormal_UsingNlerp( ::LinearAlgebra::Matrix4x4 &rotation, const ::LinearAlgebra::Vector4 &normalizedAxis ) { From 22d0722dfa718b46c33d090daff9098b31588022 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Fri, 31 Jan 2014 14:29:49 +0100 Subject: [PATCH 18/74] SnapAngularFix compilation fix forgot to remove a copy pasted comma --- Code/OysterMath/LinearMath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/OysterMath/LinearMath.h b/Code/OysterMath/LinearMath.h index 7874cb52..0a4611b1 100644 --- a/Code/OysterMath/LinearMath.h +++ b/Code/OysterMath/LinearMath.h @@ -761,7 +761,7 @@ namespace LinearAlgebra3D { return targetMem = SnapAngularAxis( ::LinearAlgebra::Vector4(startAngularAxis, (ScalarType)0), ::LinearAlgebra::Vector4(localStartNormal, (ScalarType)0), - ::LinearAlgebra::Vector4(worldEndNormal, (ScalarType)0), ).xyz; + ::LinearAlgebra::Vector4(worldEndNormal, (ScalarType)0) ).xyz; } template From 2a816469d564d0d49d0750a690db47004cb43880 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Fri, 31 Jan 2014 14:40:09 +0100 Subject: [PATCH 19/74] SnapAngularAxis fix --- Code/OysterMath/LinearMath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/OysterMath/LinearMath.h b/Code/OysterMath/LinearMath.h index 0a4611b1..dce7a026 100644 --- a/Code/OysterMath/LinearMath.h +++ b/Code/OysterMath/LinearMath.h @@ -750,7 +750,7 @@ namespace LinearAlgebra3D template ::LinearAlgebra::Vector4 & SnapAngularAxis( ::LinearAlgebra::Vector4 &startAngularAxis, const ::LinearAlgebra::Vector4 &localStartNormal, const ::LinearAlgebra::Vector4 &worldEndNormal, ::LinearAlgebra::Vector4 &targetMem = ::LinearAlgebra::Vector4() ) { - ::LinearAlgebra::Vector4 worldStartNormal( WorldAxisOf(Rotation(startAngularAxis.xyz), localStartNormal), (ScalarType)0 ); + ::LinearAlgebra::Vector4 worldStartNormal( WorldAxisOf(Rotation(startAngularAxis.xyz), localStartNormal.xyz), (ScalarType)0 ); targetMem = ::LinearAlgebra::Vector4( worldStartNormal.xyz.Cross(worldEndNormal.xyz), (ScalarType)0); targetMem *= (ScalarType)::std::acos( worldStartNormal.Dot(worldEndNormal) ); return targetMem += startAngularAxis; From b3656a052742f100da432e772b7130e50a6f0fba Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Fri, 31 Jan 2014 15:15:08 +0100 Subject: [PATCH 20/74] Gravity fix --- Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp | 2 +- Code/GamePhysics/Implementation/SphericalRigidBody.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 30ced129..12c46cd5 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -187,7 +187,7 @@ void API_Impl::Update() if( gravityImpulse != Float4::null ) { state.ApplyLinearImpulse( gravityImpulse.xyz ); - (*proto)->SetGravityNormal( gravityImpulse.GetNormalized().xyz ); + state.SetGravityNormal( gravityImpulse.GetNormalized().xyz ); (*proto)->SetState( state ); } diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index 539093db..633997ef 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -105,6 +105,7 @@ void SphericalRigidBody::SetState( const SphericalRigidBody::State &state ) this->rigid.frictionCoeff_Kinetic = state.GetFrictionCoeff_Kinetic(); this->rigid.SetMass_KeepMomentum( state.GetMass() ); this->rigid.SetMomentOfInertia_KeepMomentum( state.GetMomentOfInertia() ); + this->rigid.gravityNormal = state.GetGravityNormal(); if( state.IsForwarded() ) { From 7b503bcb5233a60a339665beecc3142c601c9796 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Fri, 31 Jan 2014 15:17:09 +0100 Subject: [PATCH 21/74] GL - working with snap --- Code/Game/GameLogic/Game_PlayerData.cpp | 2 +- Code/Game/GameLogic/Level.cpp | 2 +- Code/Game/GameLogic/Object.cpp | 16 ++++++++++------ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index 93fcfba6..8f303cea 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -7,7 +7,7 @@ Game::PlayerData::PlayerData() { //set some stats that are appropriate to a player Oyster::Physics::API::SimpleBodyDescription sbDesc; - sbDesc.centerPosition = Oyster::Math::Float3(10,350,0); + sbDesc.centerPosition = Oyster::Math::Float3(0,320,0); sbDesc.size = Oyster::Math::Float3(4,7,4); sbDesc.mass = 70; //create rigid body diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index e95f95c6..cb3abe49 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -41,7 +41,7 @@ void Level::InitiateLevel(float radius) // add box API::SimpleBodyDescription sbDesc_TestBox; - sbDesc_TestBox.centerPosition = Oyster::Math::Float4(0,320,0,0); + sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10,320,0,0); sbDesc_TestBox.ignoreGravity = false; sbDesc_TestBox.mass = 50; sbDesc_TestBox.size = Oyster::Math::Float4(4,4,4,0); diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index 3b8094fb..fc0ac4c4 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -118,18 +118,22 @@ Oyster::Physics::ICustomBody* Object::GetRigidBody() void Object::BeginFrame() { + Oyster::Math::Float4 axis; + if(setState.GetGravityNormal()!= Float3::null) + { + Oyster::Math3D::SnapAngularAxis(Oyster::Math::Float4(setState.GetAngularAxis(), 0), Oyster::Math::Float4::standard_unit_y, -Oyster::Math::Float4(setState.GetGravityNormal()), axis); + setState.SetRotation(axis.xyz); + + Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y); + debug += setState.GetGravityNormal(); + } + this->rigidBody->SetState(this->setState); - } // update physic void Object::EndFrame() { - - 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(); this->setState = this->getState; } From 8f576c9a757d12a708c1e56030fbd2e6672834bd Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Fri, 31 Jan 2014 15:30:23 +0100 Subject: [PATCH 22/74] Removed malign obsolete hack fix --- Code/GamePhysics/PhysicsStructs-Impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/GamePhysics/PhysicsStructs-Impl.h b/Code/GamePhysics/PhysicsStructs-Impl.h index 05cba2da..af2fb91c 100644 --- a/Code/GamePhysics/PhysicsStructs-Impl.h +++ b/Code/GamePhysics/PhysicsStructs-Impl.h @@ -124,7 +124,7 @@ namespace Oyster inline const ::Oyster::Math::Float3 & CustomBodyState::GetAngularAxis() const { - return ::Utility::Value::Radian(this->angularAxis); + return this->angularAxis; } inline ::Oyster::Math::Float4x4 CustomBodyState::GetRotation() const From fabf471e76884b0d6b42d77c925ce2c6b6fcf0a3 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Fri, 31 Jan 2014 15:58:02 +0100 Subject: [PATCH 23/74] Removed malign obsolete hack fix --- Code/GamePhysics/Implementation/SimpleRigidBody.cpp | 2 +- Code/GamePhysics/Implementation/SphericalRigidBody.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index ef3027ee..a2871229 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -128,7 +128,7 @@ SimpleRigidBody::State & SimpleRigidBody::GetState( SimpleRigidBody::State &targ void SimpleRigidBody::SetState( const SimpleRigidBody::State &state ) { 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.momentum_Linear = state.GetLinearMomentum(); this->rigid.momentum_Angular = state.GetAngularMomentum(); diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index 633997ef..f6f89c64 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -94,7 +94,7 @@ SphericalRigidBody::State & SphericalRigidBody::GetState( SphericalRigidBody::St void SphericalRigidBody::SetState( const SphericalRigidBody::State &state ) { 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.momentum_Linear = state.GetLinearMomentum(); this->rigid.momentum_Angular = state.GetAngularMomentum(); From e327f64702158fa44ccecbe22f8950962d7e1108 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Fri, 31 Jan 2014 16:33:16 +0100 Subject: [PATCH 24/74] GL - can play with two characters --- Code/Game/DanBiasGame/DanBiasGame_Impl.cpp | 6 ++++++ .../DanBiasGame/GameClientState/GameState.cpp | 19 +++++++++++++++++-- .../DanBiasGame/GameClientState/GameState.h | 3 ++- .../GameClientState/LobbyState.cpp | 3 --- .../GameClientState/LoginState.cpp | 2 +- Code/Game/GameLogic/Game_PlayerData.cpp | 3 ++- Code/Game/GameLogic/Level.cpp | 2 +- Code/Game/GameLogic/Object.cpp | 2 +- .../Implementation/GameSession_Gameplay.cpp | 14 ++++++++------ 9 files changed, 38 insertions(+), 16 deletions(-) diff --git a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp index 06f200bf..205f826f 100644 --- a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp +++ b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp @@ -157,7 +157,13 @@ namespace DanBias m_data->recieverObj->gameClientState = new Client::LobbyState(); break; case Client::GameClientState::ClientState_Game: + if(m_data->serverOwner) + DanBias::GameServerAPI::GameStart(); m_data->recieverObj->gameClientState = new Client::GameState(); + if(m_data->serverOwner) + ((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(2); + else + ((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(3); break; default: return E_FAIL; diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index 43b25ba7..cd281717 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -114,6 +114,18 @@ bool GameState::LoadModels(std::wstring mapFile) 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(10, 320, 0)); + + modelData.world = modelData.world * translate; + modelData.visible = true; + modelData.modelPath = L"..\\Content\\Models\\char_white.dan"; + modelData.id = 3; + // load models + obj = new C_Player(); + privData->object.push_back(obj); + privData->object[privData->object.size() -1 ]->Init(modelData); return true; @@ -137,7 +149,10 @@ bool GameState::InitCamera(Oyster::Math::Float3 startPos) privData->view = Oyster::Math3D::InverseOrientationMatrix(privData->view); return true; } - +void GameState::setClientId(int id) +{ + myId = id; +} GameClientState::ClientState GameState::Update(float deltaTime, InputClass* KeyInput) { switch (privData->state) @@ -344,7 +359,7 @@ void GameState::Protocol( ObjPos* pos ) //camera->setRight((Oyster::Math::Float3(world[0], world[1], world[2]))); //camera->setUp((Oyster::Math::Float3(world[4], world[5], world[6]))); //camera->setLook((Oyster::Math::Float3(world[8], world[9], world[10]))); - if(i == 2) // playerobj + if(i == myId) // playerobj { camera->SetPosition(Oyster::Math::Float3(world[12], world[13]+2.2f, world[14]-1)); camera->UpdateViewMatrix(); diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.h b/Code/Game/DanBiasGame/GameClientState/GameState.h index f8f1b67b..04d5b791 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.h +++ b/Code/Game/DanBiasGame/GameClientState/GameState.h @@ -26,6 +26,7 @@ private: bool key_Jump; Camera* camera; + int myId; struct myData; myData* privData; public: @@ -36,7 +37,7 @@ public: bool LoadModels(std::wstring mapFile) ; bool InitCamera(Oyster::Math::Float3 startPos) ; gameStateState LoadGame(); - + void setClientId(int id); void readKeyInput(InputClass* KeyInput); bool Render()override; bool Release()override; diff --git a/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp b/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp index 35a5f295..538408c5 100644 --- a/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp @@ -87,12 +87,9 @@ GameClientState::ClientState LobbyState::Update(float deltaTime, InputClass* Key // update animation // send data to server // check data from server - if( KeyInput->IsKeyPressed(DIK_G)) { - if(!DanBias::GameServerAPI::GameStart()) - return GameClientState::ClientState_Same; return ClientState_Game; } diff --git a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp index 4d1079bc..9beb6657 100644 --- a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp @@ -109,7 +109,7 @@ GameClientState::ClientState LoginState::Update(float deltaTime, InputClass* Key if( KeyInput->IsKeyPressed(DIK_J)) { // game ip - nwClient->Connect(15151, "193.11.184.109"); + nwClient->Connect(15151, "127.0.0.1"); if (!nwClient->IsConnected()) { diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index 8f303cea..e19af2f3 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -7,9 +7,10 @@ Game::PlayerData::PlayerData() { //set some stats that are appropriate to a player Oyster::Physics::API::SimpleBodyDescription sbDesc; - sbDesc.centerPosition = Oyster::Math::Float3(0,320,0); + sbDesc.centerPosition = Oyster::Math::Float3(0,308,0); sbDesc.size = Oyster::Math::Float3(4,7,4); sbDesc.mass = 70; + sbDesc.restitutionCoeff = 0.5; //create rigid body Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index cb3abe49..50737eb9 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -32,7 +32,7 @@ void Level::InitiateLevel(float radius) ICustomBody::State state; rigidBody->GetState(state); - state.SetRestitutionCoeff(0.01); + state.SetRestitutionCoeff(0.2); rigidBody->SetState(state); levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD); diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index fc0ac4c4..a0823247 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -123,7 +123,7 @@ void Object::BeginFrame() { Oyster::Math3D::SnapAngularAxis(Oyster::Math::Float4(setState.GetAngularAxis(), 0), Oyster::Math::Float4::standard_unit_y, -Oyster::Math::Float4(setState.GetGravityNormal()), axis); setState.SetRotation(axis.xyz); - + setState.SetAngularMomentum(Float3::null); Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y); debug += setState.GetGravityNormal(); } diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index c0041301..8235c903 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -86,12 +86,14 @@ namespace DanBias if(dynamic_cast (movedObject)) { IPlayerData* temp = (IPlayerData*)movedObject; - temp->GetID(); + + int id = temp->GetID(); Oyster::Math::Float4x4 world = temp->GetOrientation(); - Protocol_ObjectPosition p(world, 2); + Protocol_ObjectPosition p(world, id); GameSession::gameSession->Send(*p.GetProtocol()); } + GameLogic::IObjectData* obj = NULL; if(dynamic_cast(movedObject)) { @@ -100,10 +102,10 @@ namespace DanBias { if(obj->GetObjectType() == OBJECT_TYPE_WORLD) { - obj->GetID(); + int id = obj->GetID(); Oyster::Math::Float4x4 world =obj->GetOrientation(); - Protocol_ObjectPosition p(world, 0); + Protocol_ObjectPosition p(world, id); GameSession::gameSession->Send(*p.GetProtocol()); } } @@ -114,9 +116,9 @@ namespace DanBias { if(obj->GetObjectType() == OBJECT_TYPE_BOX) { - obj->GetID(); + int id = obj->GetID(); Oyster::Math::Float4x4 world = obj->GetOrientation(); - Protocol_ObjectPosition p(world, 1); + Protocol_ObjectPosition p(world, id); GameSession::gameSession->Send(*p.GetProtocol()); } } From 83ca3c2ff23525ca29fbd4c365ae4242c2962600 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Fri, 31 Jan 2014 16:43:18 +0100 Subject: [PATCH 25/74] GL - remove buttons from GL branch --- Code/Misc/EventHandler/EventButton.cpp | 0 Code/Misc/EventHandler/EventButton.h | 0 .../EventHandler/EventButtonCollection.cpp | 25 ------------- .../Misc/EventHandler/EventButtonCollection.h | 31 ---------------- Code/Misc/EventHandler/EventHandler.cpp | 37 ------------------- Code/Misc/EventHandler/EventHandler.h | 35 ------------------ 6 files changed, 128 deletions(-) delete mode 100644 Code/Misc/EventHandler/EventButton.cpp delete mode 100644 Code/Misc/EventHandler/EventButton.h delete mode 100644 Code/Misc/EventHandler/EventButtonCollection.cpp delete mode 100644 Code/Misc/EventHandler/EventButtonCollection.h delete mode 100644 Code/Misc/EventHandler/EventHandler.cpp delete mode 100644 Code/Misc/EventHandler/EventHandler.h diff --git a/Code/Misc/EventHandler/EventButton.cpp b/Code/Misc/EventHandler/EventButton.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/Code/Misc/EventHandler/EventButton.h b/Code/Misc/EventHandler/EventButton.h deleted file mode 100644 index e69de29b..00000000 diff --git a/Code/Misc/EventHandler/EventButtonCollection.cpp b/Code/Misc/EventHandler/EventButtonCollection.cpp deleted file mode 100644 index b3d37bfe..00000000 --- a/Code/Misc/EventHandler/EventButtonCollection.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "EventButtonCollection.h" - -using namespace Oyster::Event; - -EventButtonCollection::EventButtonCollection() -{ - -} - -EventButtonCollection::~EventButtonCollection() -{ -} - -void EventButtonCollection::Update(InputClass* inputObject) -{ - for(int i = 0; i < buttons.size(); i++) - { - buttons.at(i)->Update(inputObject); - } -} - -EventButton* EventButtonCollection::AddButton(EventButton* button) -{ - -} \ No newline at end of file diff --git a/Code/Misc/EventHandler/EventButtonCollection.h b/Code/Misc/EventHandler/EventButtonCollection.h deleted file mode 100644 index 31201f9c..00000000 --- a/Code/Misc/EventHandler/EventButtonCollection.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef EVENT_BUTTON_COLLECTION_H -#define EVENT_BUTTON_COLLECTION_H - -#include "../../Input/L_inputClass.h" - -#include "EventButton.h" - -#include - -namespace Oyster -{ - namespace Event - { - class EventButtonCollection - { - public: - EventButtonCollection(); - ~EventButtonCollection(); - - void Update(InputClass* inputObject); - - EventButton* AddButton(EventButton* button); - - private: - std::vector buttons; - - }; - } -} - -#endif \ No newline at end of file diff --git a/Code/Misc/EventHandler/EventHandler.cpp b/Code/Misc/EventHandler/EventHandler.cpp deleted file mode 100644 index 8f6705df..00000000 --- a/Code/Misc/EventHandler/EventHandler.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "EventHandler.h" - -using namespace Oyster::Event; - -EventHandler EvtHandler; - -EventHandler& EventHandler::Instance() -{ - return EvtHandler; -} - -EventHandler::EventHandler() -{ - -} - -EventHandler::~EventHandler() -{ -} - -void EventHandler::Update(InputClass* inputObject) -{ - for(int i = 0; i < collections.size(); i++) - { - collections.at(i)->Update(inputObject); - } -} - -EventButtonCollection* EventHandler::CreateCollection() -{ - -} - -EventButtonCollection* EventHandler::GetCollection(/*ID*/); -{ - -} \ No newline at end of file diff --git a/Code/Misc/EventHandler/EventHandler.h b/Code/Misc/EventHandler/EventHandler.h deleted file mode 100644 index c3ecc0a2..00000000 --- a/Code/Misc/EventHandler/EventHandler.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef EVENT_HANDLER_H -#define EVENT_HANDLER_H - -#include "../../Input/L_inputClass.h" - -#include "EventButtonCollection.h" -#include "EventButton.h" - -#include - -namespace Oyster -{ - namespace Event - { - class EventHandler - { - EventHandler(); - ~EventHandler(); - - EventHandler& Instance(); - - void Update(InputClass* inputObject); - - EventButtonCollection* CreateCollection(); - EventButtonCollection* GetCollection(/*ID*/); - - - private: - std::vector collections; - - }; - } -} - -#endif \ No newline at end of file From ef71b365ab10abe6260a6197a1ce93add3839de3 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Mon, 3 Feb 2014 10:42:40 +0100 Subject: [PATCH 26/74] asd --- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 3 +++ Code/Game/GameLogic/GameLogic.vcxproj.user | 2 +- Code/Game/GameLogic/Game_PlayerData.cpp | 6 ++++++ Code/Game/GameLogic/Level.cpp | 7 +++++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index a63b6e1d..bca972fd 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -46,7 +46,10 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage, ********************************************************/ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float dt) { +<<<<<<< HEAD +======= +>>>>>>> GL - mergeissues Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt); Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); diff --git a/Code/Game/GameLogic/GameLogic.vcxproj.user b/Code/Game/GameLogic/GameLogic.vcxproj.user index 2e28d6f7..4b847ee6 100644 --- a/Code/Game/GameLogic/GameLogic.vcxproj.user +++ b/Code/Game/GameLogic/GameLogic.vcxproj.user @@ -1,7 +1,7 @@  - true + false $(OutDir) diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index e19af2f3..1626f5b3 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -9,8 +9,14 @@ Game::PlayerData::PlayerData() Oyster::Physics::API::SimpleBodyDescription sbDesc; sbDesc.centerPosition = Oyster::Math::Float3(0,308,0); sbDesc.size = Oyster::Math::Float3(4,7,4); +<<<<<<< HEAD sbDesc.mass = 70; sbDesc.restitutionCoeff = 0.5; +======= + + sbDesc.mass = 90; + +>>>>>>> GL - mergeissues //create rigid body Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index 50737eb9..0a1a37e6 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -43,8 +43,15 @@ void Level::InitiateLevel(float radius) API::SimpleBodyDescription sbDesc_TestBox; sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10,320,0,0); sbDesc_TestBox.ignoreGravity = false; +<<<<<<< HEAD sbDesc_TestBox.mass = 50; sbDesc_TestBox.size = Oyster::Math::Float4(4,4,4,0); +======= + + sbDesc_TestBox.mass = 10; + sbDesc_TestBox.size = Oyster::Math::Float4(4,4,4,0); + +>>>>>>> GL - mergeissues ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); From 50d895d37c5d305f7de05df9dc5a75040bc13286 Mon Sep 17 00:00:00 2001 From: Robin Engman Date: Mon, 3 Feb 2014 10:45:25 +0100 Subject: [PATCH 27/74] Applied friction Needs to be tested. --- Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 12c46cd5..ee47eeba 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -78,10 +78,14 @@ namespace deuterState.GetMass(), deuterG_Magnitude ); Float4 bounce = Average( bounceD, bounceP ); + + Float4 friction = Formula::CollisionResponse::Friction( protoG_Magnitude, normal, + Float4(protoState.GetLinearMomentum(), 0), protoState.GetFrictionCoeff_Static(), protoState.GetFrictionCoeff_Kinetic(), protoState.GetMass(), + Float4(deuterState.GetLinearMomentum(), 0), deuterState.GetFrictionCoeff_Static(), deuterState.GetFrictionCoeff_Kinetic(), deuterState.GetMass()); Float kineticEnergyPBefore = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), protoState.GetLinearMomentum()/protoState.GetMass() ); - protoState.ApplyImpulse( bounce.xyz, worldPointOfContact.xyz, normal.xyz ); + protoState.ApplyImpulse( bounce.xyz - friction.xyz, worldPointOfContact.xyz, normal.xyz ); proto->SetState( protoState ); Float kineticEnergyPAFter = Oyster::Physics3D::Formula::LinearKineticEnergy( protoState.GetMass(), (protoState.GetLinearMomentum() + protoState.GetLinearImpulse())/protoState.GetMass() ); From 8f234611d2c9691506876132ba1f6119937d4d20 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Mon, 3 Feb 2014 10:48:12 +0100 Subject: [PATCH 28/74] GL - mergeissues fixed --- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 4 ---- Code/Game/GameLogic/Game_PlayerData.cpp | 5 ----- Code/Game/GameLogic/Level.cpp | 7 +------ 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index bca972fd..5f5834bb 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -46,10 +46,6 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage, ********************************************************/ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float dt) { -<<<<<<< HEAD - -======= ->>>>>>> GL - mergeissues Oyster::Math::Float4 pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * dt); Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index 1626f5b3..18bb10a7 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -9,14 +9,9 @@ Game::PlayerData::PlayerData() Oyster::Physics::API::SimpleBodyDescription sbDesc; sbDesc.centerPosition = Oyster::Math::Float3(0,308,0); sbDesc.size = Oyster::Math::Float3(4,7,4); -<<<<<<< HEAD sbDesc.mass = 70; sbDesc.restitutionCoeff = 0.5; -======= - sbDesc.mass = 90; - ->>>>>>> GL - mergeissues //create rigid body Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index 0a1a37e6..b070eb56 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -43,15 +43,10 @@ void Level::InitiateLevel(float radius) API::SimpleBodyDescription sbDesc_TestBox; sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10,320,0,0); sbDesc_TestBox.ignoreGravity = false; -<<<<<<< HEAD + sbDesc_TestBox.mass = 50; sbDesc_TestBox.size = Oyster::Math::Float4(4,4,4,0); -======= - sbDesc_TestBox.mass = 10; - sbDesc_TestBox.size = Oyster::Math::Float4(4,4,4,0); - ->>>>>>> GL - mergeissues ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); From b8e6b83148014baa487bb47b44ddd9964255a678 Mon Sep 17 00:00:00 2001 From: Robin Engman Date: Mon, 3 Feb 2014 11:10:04 +0100 Subject: [PATCH 29/74] Momentum "fall-off" added Temporary till real fluid drag is implemented. --- Code/OysterPhysics3D/RigidBody.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Code/OysterPhysics3D/RigidBody.cpp b/Code/OysterPhysics3D/RigidBody.cpp index f053e8dd..70ded863 100644 --- a/Code/OysterPhysics3D/RigidBody.cpp +++ b/Code/OysterPhysics3D/RigidBody.cpp @@ -49,6 +49,10 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength ) { // by Dan Andersson: Euler leap frog update when Runga Kutta is not needed // updating the linear + //Decrease momentum with 1% as "fall-off" + //! HACK: @todo Add real solution with fluid drag + this->momentum_Linear = this->momentum_Linear*0.99f; + this->momentum_Angular = this->momentum_Angular*0.99f; // ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G Float3 deltaPos = ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear ); if( deltaPos.GetLength() < 0.001f ) From e7fee8b2e7161d2768e914d398a424da151edb6a Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Mon, 3 Feb 2014 14:50:15 +0100 Subject: [PATCH 30/74] GL - Updated LevelLoader. Added lights. Added lights. Changed the return type to vector> Hid the LevelParser from the outside. --- Bin/Level.txt | Bin 156 -> 0 bytes Bin/map | Bin 156 -> 0 bytes Bin/map.txt | Bin 60 -> 0 bytes .../GameLogic/LevelLoader/LevelLoader.cpp | 22 ++++- Code/Game/GameLogic/LevelLoader/LevelLoader.h | 44 +++++----- .../GameLogic/LevelLoader/LevelParser.cpp | 81 +++++++++++++----- Code/Game/GameLogic/LevelLoader/LevelParser.h | 3 +- .../GameLogic/LevelLoader/ObjectDefines.h | 47 +++++++++- .../GameLogic/LevelLoader/ParseFunctions.h | 10 ++- 9 files changed, 156 insertions(+), 51 deletions(-) delete mode 100644 Bin/Level.txt delete mode 100644 Bin/map delete mode 100644 Bin/map.txt diff --git a/Bin/Level.txt b/Bin/Level.txt deleted file mode 100644 index d86dd3db4f89e0c84adfa01d7b0ec5a42dd61adb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmZQzU|?VYV!y=PR7M~T0wBIiYH>0$&A`y$pam3X0x19jkXjHMgqeXjYRNaJ8F^XG hjYrow<6?ux*}DpzTmbMiDYF0o diff --git a/Bin/map b/Bin/map deleted file mode 100644 index a578cc3216cf4c730d47a3cae791ddccf2b29610..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmZQ#U|?VZVrC$YTJp_lMqZY47AJ$m6N^*QIDs?+LxY1BkYob085kIWGyuTm1-1YH diff --git a/Code/Game/GameLogic/LevelLoader/LevelLoader.cpp b/Code/Game/GameLogic/LevelLoader/LevelLoader.cpp index d60aac66..5bb916ab 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelLoader.cpp +++ b/Code/Game/GameLogic/LevelLoader/LevelLoader.cpp @@ -3,16 +3,30 @@ ////////////////////////////////// #include "LevelLoader.h" +#include "LevelParser.h" using namespace GameLogic; using namespace GameLogic::LevelFileLoader; - -std::vector LevelLoader::LoadLevel(std::string fileName) +struct LevelLoader::PrivData { - return parser.Parse(fileName); + LevelParser parser; +}; + +LevelLoader::LevelLoader() + : pData(new PrivData) +{ +} + +LevelLoader::~LevelLoader() +{ +} + +std::vector> LevelLoader::LoadLevel(std::string fileName) +{ + return pData->parser.Parse(fileName); } LevelMetaData LevelLoader::LoadLevelHeader(std::string fileName) { - return parser.ParseHeader(fileName); + return pData->parser.ParseHeader(fileName); } \ No newline at end of file diff --git a/Code/Game/GameLogic/LevelLoader/LevelLoader.h b/Code/Game/GameLogic/LevelLoader/LevelLoader.h index 4ac7a950..bcd6e587 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelLoader.h +++ b/Code/Game/GameLogic/LevelLoader/LevelLoader.h @@ -7,36 +7,36 @@ #include #include -#include +#include "../Misc/Utilities.h" #include "ObjectDefines.h" -#include "LevelParser.h" namespace GameLogic { - class LevelLoader - { + class LevelLoader + { - public: - LevelLoader(){this->parser = GameLogic::LevelFileLoader::LevelParser(); } - ~LevelLoader(){} + public: + LevelLoader(); + ~LevelLoader(); - /******************************************************** - * Loads the level and objects from file. - * @param fileName: Path to the level-file that you want to load. - * @return: Returns all structs with objects and information about the level. - ********************************************************/ - std::vector LoadLevel(std::string fileName); + /******************************************************** + * Loads the level and objects from file. + * @param fileName: Path to the level-file that you want to load. + * @return: Returns all structs with objects and information about the level. + ********************************************************/ + std::vector> LoadLevel(std::string fileName); - /******************************************************** - * Just for fast access for the meta information about the level. - * @param fileName: Path to the level-file that you want to load. - * @return: Returns the meta information about the level. - ********************************************************/ - LevelMetaData LoadLevelHeader(std::string fileName); //. + /******************************************************** + * Just for fast access for the meta information about the level. + * @param fileName: Path to the level-file that you want to load. + * @return: Returns the meta information about the level. + ********************************************************/ + LevelMetaData LoadLevelHeader(std::string fileName); //. - private: - GameLogic::LevelFileLoader::LevelParser parser; - }; + private: + struct PrivData; + Utility::DynamicMemory::SmartPointer pData; + }; } #endif \ No newline at end of file diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp index 3ab3c203..3a20f192 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp @@ -5,6 +5,7 @@ using namespace GameLogic; using namespace ::LevelFileLoader; +using namespace Utility::DynamicMemory; LevelParser::LevelParser() { @@ -16,12 +17,12 @@ LevelParser::~LevelParser() { } -std::vector LevelParser::Parse(std::string filename) +std::vector> LevelParser::Parse(std::string filename) { int bufferSize = 0; int counter = 0; - std::vector objects; + std::vector> objects; //Read entire level file. Loader loader; @@ -42,26 +43,66 @@ std::vector LevelParser::Parse(std::string filename) ParseObject(&buffer[counter], &typeID, sizeof(typeID)); switch((int)typeID.typeID) { - case ObjectType_LevelMetaData: - { - LevelMetaData header; - ParseLevelMetaData(&buffer[counter], header, counter); - objects.push_back(header); - break; - } + case ObjectType_LevelMetaData: + { + LevelMetaData* header = new LevelMetaData; + ParseLevelMetaData(&buffer[counter], *header, counter); + objects.push_back(header); + break; + } - case ObjectType_Dynamic: - { - ObjectHeader header; - ParseObject(&buffer[counter], &header, sizeof(header)); - objects.push_back(header); - counter += sizeof(header); - break; - } + //This is by design, static and dynamic is using the same converter. Do not add anything inbetween them. + case ObjectType_Static: case ObjectType_Dynamic: + { + ObjectHeader* header = new ObjectHeader; + ParseObject(&buffer[counter], header, sizeof(*header)); + objects.push_back(header); + counter += sizeof(*header); + break; + } - default: - //Couldn't find typeID. FAIL!!!!!! - break; + case ObjectType_Light: + { + LightType lightType; + + //Get Light type + ParseObject(&buffer[counter+4], &lightType, sizeof(lightType)); + + switch(lightType) + { + case LightType_PointLight: + { + PointLight* header = new PointLight; + ParseObject(&buffer[counter], header, sizeof(*header)); + counter += sizeof(*header); + objects.push_back(header); + break; + } + case LightType_DirectionalLight: + { + DirectionalLight* header = new DirectionalLight; + ParseObject(&buffer[counter], header, sizeof(*header)); + counter += sizeof(*header); + objects.push_back(header); + break; + } + case LightType_SpotLight: + { + SpotLight* header = new SpotLight; + ParseObject(&buffer[counter], header, sizeof(*header)); + counter += sizeof(*header); + objects.push_back(header); + break; + } + default: + //Undefined LightType. + break; + } + break; + } + default: + //Couldn't find typeID. FAIL!!!!!! + break; } } diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.h b/Code/Game/GameLogic/LevelLoader/LevelParser.h index 6dce25f8..9ad30642 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.h +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.h @@ -4,6 +4,7 @@ #include #include #include "ObjectDefines.h" +#include "../Misc/Utilities.h" namespace GameLogic { @@ -16,7 +17,7 @@ namespace GameLogic ~LevelParser(); // - std::vector Parse(std::string filename); + std::vector> Parse(std::string filename); // LevelMetaData ParseHeader(std::string filename); diff --git a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h index dcf960a5..21e3a7e3 100644 --- a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h +++ b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h @@ -15,11 +15,12 @@ namespace GameLogic ObjectType_LevelMetaData, ObjectType_Static, ObjectType_Dynamic, + ObjectType_Light, //Etc ObjectType_NUM_OF_TYPES, - ObjectType_Unknown = -1, + ObjectType_Unknown = -1 }; enum UsePhysics @@ -29,7 +30,17 @@ namespace GameLogic UsePhysics_IgnorePhysics, UsePhysics_Count, - UsePhysics_Unknown = -1, + UsePhysics_Unknown = -1 + }; + + enum LightType + { + LightType_PointLight, + LightType_DirectionalLight, + LightType_SpotLight, + + LightType_Count, + LightType_Unknown = -1 }; //Should this be moved somewhere else? @@ -40,7 +51,7 @@ namespace GameLogic //Etc GameMode_Count, - GameMode_Unknown = -1, + GameMode_Unknown = -1 }; @@ -104,6 +115,36 @@ namespace GameLogic //Scale float scale[3]; }; + + + /************************************ + Lights + *************************************/ + + struct BasicLight : public ObjectTypeHeader + { + LightType lightType; + float ambientColor[3]; + float diffuseColor[3]; + float specularColor[3]; + }; + + struct PointLight : public BasicLight + { + float position[3]; + }; + + struct DirectionalLight : public BasicLight + { + float direction[3]; + }; + + struct SpotLight : public BasicLight + { + float direction[3]; + float range; + float attenuation[3]; + }; } #endif \ No newline at end of file diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.h b/Code/Game/GameLogic/LevelLoader/ParseFunctions.h index 08962b4a..554b95db 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.h +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.h @@ -10,8 +10,16 @@ namespace GameLogic { namespace LevelFileLoader { + /* + These functions will copy data from where the buffer pointer points. + header is the destination where the data will be copied. + size is either the size of the data to be copied (if it is NOT sent by reference). + Or the current index that is being used to parse the entire file (if it is sent by reference) this means you have to increase size with the appropiate size after you have copied. + + */ + void ParseObject(char* buffer, void *header, int size); - void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size); + void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size); } } From f527d329a270b78e4a0a86783d4d4c0363afcb0f Mon Sep 17 00:00:00 2001 From: Robin Engman Date: Mon, 3 Feb 2014 15:15:47 +0100 Subject: [PATCH 31/74] Added limbo functionality --- Code/GamePhysics/Implementation/Octree.cpp | 36 ++++++++++++++++--- Code/GamePhysics/Implementation/Octree.h | 7 ++++ .../Implementation/PhysicsAPI_Impl.cpp | 7 ++-- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/Code/GamePhysics/Implementation/Octree.cpp b/Code/GamePhysics/Implementation/Octree.cpp index b4395516..47bf3e39 100644 --- a/Code/GamePhysics/Implementation/Octree.cpp +++ b/Code/GamePhysics/Implementation/Octree.cpp @@ -40,6 +40,7 @@ void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef) data.next = NULL; data.prev = NULL; data.customBodyRef = customBodyRef; + data.limbo = false; this->mapReferences.insert(std::pair (data.customBodyRef, this->leafData.size())); this->leafData.push_back(data); @@ -64,6 +65,33 @@ void Octree::MoveToUpdateQueue(UniquePointer< ICustomBody > customBodyRef) this->updateQueue.push_back(&this->leafData[this->mapReferences[customBodyRef]]);*/ } +void Octree::MoveToLimbo(const ICustomBody* customBodyRef) +{ + auto object = this->mapReferences.find(customBodyRef); + + unsigned int tempRef = object->second; + + this->leafData[tempRef].limbo = true; +} + +bool Octree::IsInLimbo(const ICustomBody* customBodyRef) +{ + auto object = this->mapReferences.find(customBodyRef); + + unsigned int tempRef = object->second; + + return this->leafData[tempRef].limbo; +} + +void Octree::ReleaseFromLimbo(const ICustomBody* customBodyRef) +{ + auto object = this->mapReferences.find(customBodyRef); + + unsigned int tempRef = object->second; + + this->leafData[tempRef].limbo = false; +} + void Octree::DestroyObject(UniquePointer< ICustomBody > customBodyRef) { std::map::iterator it = this->mapReferences.find(customBodyRef); @@ -86,7 +114,7 @@ std::vector& Octree::Sample(ICustomBody* customBodyRef, std::vecto for(unsigned int i = 0; ileafData.size(); i++) { - if(tempRef != i) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container)) + if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container)) { updateList.push_back(this->leafData[i].customBodyRef); } @@ -99,7 +127,7 @@ std::vector& Octree::Sample(const Oyster::Collision3D::ICollideabl { for(unsigned int i = 0; ileafData.size(); i++) { - if(this->leafData[i].container.Intersects(collideable)) + if(!this->leafData[i].limbo && this->leafData[i].container.Intersects(collideable)) { updateList.push_back(this->leafData[i].customBodyRef); } @@ -121,7 +149,7 @@ void Octree::Visit(ICustomBody* customBodyRef, VisitorAction hitAction ) for(unsigned int i = 0; ileafData.size(); i++) { - if(tempRef != i) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container)) + if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container)) { hitAction(*this, tempRef, i); } @@ -132,7 +160,7 @@ void Octree::Visit(const Oyster::Collision3D::ICollideable& collideable, void* a { for(unsigned int i = 0; ileafData.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 ); } diff --git a/Code/GamePhysics/Implementation/Octree.h b/Code/GamePhysics/Implementation/Octree.h index 50b9569a..573738f2 100644 --- a/Code/GamePhysics/Implementation/Octree.h +++ b/Code/GamePhysics/Implementation/Octree.h @@ -29,6 +29,8 @@ namespace Oyster ::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef; + bool limbo; + unsigned int queueRef; }; @@ -48,6 +50,10 @@ namespace Oyster void MoveToUpdateQueue(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef); + void MoveToLimbo(const ICustomBody* customBodyRef); + bool IsInLimbo(const ICustomBody* customBodyRef); + void ReleaseFromLimbo(const ICustomBody* customBodyRef); + void DestroyObject(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef); std::vector& Sample(ICustomBody* customBodyRef, std::vector& updateList); @@ -66,6 +72,7 @@ namespace Oyster private: std::vector < Data > leafData; std::vector < Data* > updateQueue; + std::vector < Data* > limbo; std::map< const ICustomBody*, unsigned int > mapReferences; diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index ee47eeba..9880526d 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -237,17 +237,16 @@ void API_Impl::Update() bool API_Impl::IsInLimbo( const ICustomBody* objRef ) { - //! @todo TODO: implement stub - return true; + return this->worldScene.IsInLimbo( objRef ); } void API_Impl::MoveToLimbo( const ICustomBody* objRef ) { - /** @todo TODO: Fix this function.*/ + this->worldScene.MoveToLimbo( objRef ); } void API_Impl::ReleaseFromLimbo( const ICustomBody* objRef ) { - /** @todo TODO: Fix this function.*/ + this->worldScene.ReleaseFromLimbo( objRef ); } void API_Impl::AddObject( ::Utility::DynamicMemory::UniquePointer handle ) From dc5b4081962654e9f1d473eb62761f795258d309 Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Mon, 3 Feb 2014 15:32:20 +0100 Subject: [PATCH 32/74] Network - Updated network api with comment. --- Code/Network/NetworkAPI/NetworkServer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Network/NetworkAPI/NetworkServer.h b/Code/Network/NetworkAPI/NetworkServer.h index 97a3e024..1a6af478 100644 --- a/Code/Network/NetworkAPI/NetworkServer.h +++ b/Code/Network/NetworkAPI/NetworkServer.h @@ -84,8 +84,8 @@ namespace Oyster */ std::string GetLanAddress(); - /** - * + /** Returns the port the server is listening on. + * @return Returns the port the server has been initiated with. */ int NetworkServer::GetPort(); From 99b041f1650009ebe1fed77706313db717a9c6b3 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Mon, 3 Feb 2014 15:32:46 +0100 Subject: [PATCH 33/74] GL - first implementation of weapons forcepull with pickup functionallity --- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 72 ++++++++++++++++++- Code/Game/GameLogic/AttatchmentMassDriver.h | 21 ++++-- Code/Game/GameLogic/CollisionManager.cpp | 37 ++++++++++ Code/Game/GameLogic/CollisionManager.h | 1 + Code/Game/GameLogic/IAttatchment.h | 1 + Code/Game/GameLogic/Object.h | 4 +- Code/Game/GameLogic/Player.cpp | 12 ++++ Code/Game/GameLogic/Player.h | 3 + Code/Game/GameLogic/StaticObject.cpp | 4 +- Code/Game/GameLogic/Weapon.cpp | 5 ++ Code/Game/GameLogic/Weapon.h | 1 + 11 files changed, 152 insertions(+), 9 deletions(-) diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index 5f5834bb..837393db 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -9,12 +9,16 @@ using namespace GameLogic; AttatchmentMassDriver::AttatchmentMassDriver(void) { this->owner = 0; + this->heldObject = NULL; + this->hasObject = false; } AttatchmentMassDriver::AttatchmentMassDriver(Player &owner) { this->owner = &owner; + this->heldObject = NULL; + this->hasObject = false; } @@ -37,16 +41,51 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage, case WEAPON_FIRE::WEAPON_USE_SECONDARY_PRESS: ForcePull(usage,dt); break; + case WEAPON_FIRE::WEAPON_USE_UTILLITY_PRESS: + ForceZip(usage,dt); + break; } } +void AttatchmentMassDriver::Update(float dt) +{ + + //update position of heldObject if there is an object being held + if(hasObject) + { + Oyster::Physics::ICustomBody::State state; + state = heldObject->GetState(); + + Oyster::Math::Float3 pos = owner->GetPosition() + owner->GetLookDir().GetNormalized(); + + state.SetCenterPosition(pos); + + heldObject->SetState(state); + } +} + /******************************************************** * Pushes objects in a cone in front of the weapon when fired +*alternativly it puts a large force on the currently held object ********************************************************/ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float dt) { - 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::Float4 pushForce; + + if(hasObject) + { + pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (800 * dt); + Oyster::Physics::ICustomBody::State state = heldObject->GetState(); + state.ApplyLinearImpulse((Oyster::Math::Float3)pushForce); + heldObject->SetState(state); + hasObject = false; + heldObject = NULL; + return; + } + + pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (500 * 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); @@ -60,7 +99,7 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float /******************************************************** * Pulls the player in the direction he is looking, used for fast movement(kinda like a jetpack) ********************************************************/ -void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt) +void AttatchmentMassDriver::ForceZip(const WEAPON_FIRE &usage, float dt) { Oyster::Physics::Struct::CustomBodyState state = this->owner->GetRigidBody()->GetState(); @@ -71,3 +110,32 @@ 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::Float4 pos = owner->GetPosition() + owner->GetLookDir().GetNormalized(); + Oyster::Collision3D::Sphere hitSphere = Oyster::Collision3D::Sphere(pos,1); + + Oyster::Physics::API::Instance().ApplyEffect(hitSphere,this,AttemptPickUp); + +} diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.h b/Code/Game/GameLogic/AttatchmentMassDriver.h index 594ea4fd..51368e91 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.h +++ b/Code/Game/GameLogic/AttatchmentMassDriver.h @@ -16,29 +16,42 @@ namespace GameLogic void UseAttatchment(const WEAPON_FIRE &usage, float dt); + void Update(float dt); private: /******************************************************** * Pushes objects and players in a cone in front of the player - * @param fireInput: allows switching on different functionality in this specific function + * @param usage: allows switching on different functionality in this specific function ********************************************************/ void ForcePush(const WEAPON_FIRE &usage, float dt); /******************************************************** * Pulls the player forward, this is a movement tool - * @param fireInput: allows switching on different functionality in this specific function + * @param usage: allows switching on different functionality in this specific function + ********************************************************/ + void ForceZip(const WEAPON_FIRE &usage, float dt); + + /******************************************************** + * Sucks objects towards the player, the player can then pick up an object and throw it as a projectile + * @param usage: allows switching on different functionality in this specific function ********************************************************/ void ForcePull(const WEAPON_FIRE &usage, float dt); /******************************************************** * Sucks objects towards the player, the player can then pick up an object and throw it as a projectile - * @param fireInput: allows switching on different functionality in this specific function + * @param usage: allows switching on different functionality in this specific function ********************************************************/ - void ForceSuck(const WEAPON_FIRE &usage, float dt); + void PickUpObject(const WEAPON_FIRE &usage, float dt); + static void ForcePushAction(Oyster::Physics::ICustomBody *obj, void* args); + static void AttemptPickUp(Oyster::Physics::ICustomBody *obj, void* args); + + private: + Oyster::Physics::ICustomBody *heldObject; + bool hasObject; }; } diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 019df6f4..afb94035 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -5,6 +5,7 @@ #include "Level.h" #include "AttatchmentMassDriver.h" #include "Game.h" +#include "CollisionManager.h" using namespace Oyster; @@ -77,6 +78,13 @@ using namespace GameLogic; { return Physics::ICustomBody::SubscriptMessage_ignore_collision_response; } + + Oyster::Physics::ICustomBody::SubscriptMessage CollisionManager::IgnoreCollision(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustomBody *obj) + { + return Physics::ICustomBody::SubscriptMessage_ignore_collision_response; + } + + Oyster::Physics::ICustomBody::SubscriptMessage Level::LevelCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) { return Physics::ICustomBody::SubscriptMessage_ignore_collision_response; @@ -93,4 +101,33 @@ using namespace GameLogic; state = obj->GetState(); state.ApplyLinearImpulse(((forcePushData*)(args))->pushForce); obj->SetState(state); + } + + void AttatchmentMassDriver::AttemptPickUp(Oyster::Physics::ICustomBody *obj, void* args) + { + AttatchmentMassDriver *weapon = ((AttatchmentMassDriver*)args); + + if(weapon->hasObject) + { + //do nothing + } + else + { + Object* realObj = (Object*)(obj->GetCustomTag()); + //check so that it is an object that you can pickup + + switch(realObj->GetObjectType()) + { + case OBJECT_TYPE::OBJECT_TYPE_BOX: + obj->SetGravity(true); //will now ignore gravity, dont mind the naming + //move obj to limbo in physics to make sure it wont collide with anything + weapon->heldObject = obj; //weapon now holds the object + weapon->hasObject = true; + + break; + } + + } + + } \ No newline at end of file diff --git a/Code/Game/GameLogic/CollisionManager.h b/Code/Game/GameLogic/CollisionManager.h index 6179333f..d3be9809 100644 --- a/Code/Game/GameLogic/CollisionManager.h +++ b/Code/Game/GameLogic/CollisionManager.h @@ -11,6 +11,7 @@ namespace GameLogic { public: //put general collision functions here that are not part of a specific object + static Oyster::Physics::ICustomBody::SubscriptMessage IgnoreCollision(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustomBody *obj); }; diff --git a/Code/Game/GameLogic/IAttatchment.h b/Code/Game/GameLogic/IAttatchment.h index e458fdbf..9984303a 100644 --- a/Code/Game/GameLogic/IAttatchment.h +++ b/Code/Game/GameLogic/IAttatchment.h @@ -20,6 +20,7 @@ namespace GameLogic ~IAttatchment(void); virtual void UseAttatchment(const WEAPON_FIRE &usage, float dt) = 0; + virtual void Update(float dt) = 0; private: diff --git a/Code/Game/GameLogic/Object.h b/Code/Game/GameLogic/Object.h index d3a3690f..96d97591 100644 --- a/Code/Game/GameLogic/Object.h +++ b/Code/Game/GameLogic/Object.h @@ -35,8 +35,8 @@ namespace GameLogic Oyster::Physics::ICustomBody* GetRigidBody(); void ApplyLinearImpulse(Oyster::Math::Float3 force); - void BeginFrame(); - void EndFrame(); + virtual void BeginFrame(); + virtual void EndFrame(); void setBeforeCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter)); void setAfterCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss)); diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index ea36b284..73ddb9fc 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -58,6 +58,18 @@ Player::~Player(void) } } +void Player::BeginFrame() +{ + weapon->Update(0.002f); + Object::BeginFrame(); +} + +void Player::EndFrame() +{ + + Object::EndFrame(); +} + void Player::Move(const PLAYER_MOVEMENT &movement) { switch(movement) diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index 0df0d040..f44f98d1 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -71,6 +71,9 @@ namespace GameLogic void DamageLife(int damage); + void BeginFrame(); + void EndFrame(); + private: void Jump(); diff --git a/Code/Game/GameLogic/StaticObject.cpp b/Code/Game/GameLogic/StaticObject.cpp index 21b339be..c007b919 100644 --- a/Code/Game/GameLogic/StaticObject.cpp +++ b/Code/Game/GameLogic/StaticObject.cpp @@ -1,4 +1,5 @@ #include "StaticObject.h" +#include "CollisionManager.h" using namespace GameLogic; @@ -17,7 +18,8 @@ StaticObject::StaticObject(OBJECT_TYPE type) StaticObject::StaticObject(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type) :Object(rigidBody,type) { - + this->rigidBody->SetGravity(true); + this->rigidBody->SetSubscription((Oyster::Physics::ICustomBody::EventAction_BeforeCollisionResponse)(CollisionManager::IgnoreCollision)); } StaticObject::StaticObject(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type) diff --git a/Code/Game/GameLogic/Weapon.cpp b/Code/Game/GameLogic/Weapon.cpp index a4c87e9e..19b53a31 100644 --- a/Code/Game/GameLogic/Weapon.cpp +++ b/Code/Game/GameLogic/Weapon.cpp @@ -125,4 +125,9 @@ void Weapon::SelectAttatchment(int socketID) selectedSocketID = socketID; } +} + +void Weapon::Update(float dt) +{ + selectedAttatchment->Update(dt); } \ No newline at end of file diff --git a/Code/Game/GameLogic/Weapon.h b/Code/Game/GameLogic/Weapon.h index 5138b2ac..8f226f12 100644 --- a/Code/Game/GameLogic/Weapon.h +++ b/Code/Game/GameLogic/Weapon.h @@ -20,6 +20,7 @@ namespace GameLogic ~Weapon(void); void Use(const WEAPON_FIRE &usage, float dt); + void Update(float dt); void AddNewAttatchment(IAttatchment *attatchment, Player *owner); void SwitchAttatchment(IAttatchment *attatchment, int socketID, Player *owner); From d77b3d92d8195447737ecad503554b3a5a5802aa Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Mon, 3 Feb 2014 15:45:48 +0100 Subject: [PATCH 34/74] GL - using movetolimbo in massdriver pickup functionallity --- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 1 + Code/Game/GameLogic/CollisionManager.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index 837393db..d5de9baa 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -80,6 +80,7 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float Oyster::Physics::ICustomBody::State state = heldObject->GetState(); state.ApplyLinearImpulse((Oyster::Math::Float3)pushForce); heldObject->SetState(state); + Oyster::Physics::API::Instance().ReleaseFromLimbo(heldObject); hasObject = false; heldObject = NULL; return; diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index afb94035..d1e9a324 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -119,8 +119,8 @@ using namespace GameLogic; switch(realObj->GetObjectType()) { case OBJECT_TYPE::OBJECT_TYPE_BOX: - obj->SetGravity(true); //will now ignore gravity, dont mind the naming //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; From 8b0e1b242630de3e4ff27a679a1125ff928b3d6a Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Mon, 3 Feb 2014 15:48:42 +0100 Subject: [PATCH 35/74] Big patch! New feature :) Objects will now rebound back when colliding. --- .../Implementation/PhysicsAPI_Impl.cpp | 2 + .../Implementation/SimpleRigidBody.cpp | 88 +++++++++++-- .../Implementation/SimpleRigidBody.h | 10 ++ .../Implementation/SphericalRigidBody.cpp | 83 +++++++++++-- .../Implementation/SphericalRigidBody.h | 9 ++ Code/GamePhysics/PhysicsAPI.h | 5 + Code/GamePhysics/PhysicsStructs-Impl.h | 4 +- Code/GamePhysics/PhysicsStructs.h | 4 +- Code/Misc/Utilities.h | 8 ++ Code/OysterMath/LinearMath.h | 117 ++++++++++++++---- Code/OysterMath/OysterMath.h | 3 + Code/OysterPhysics3D/Box.cpp | 25 +++- Code/OysterPhysics3D/Box.h | 59 +++++---- Code/OysterPhysics3D/BoxAxisAligned.cpp | 12 ++ Code/OysterPhysics3D/BoxAxisAligned.h | 2 + Code/OysterPhysics3D/Frustrum.cpp | 12 ++ Code/OysterPhysics3D/Frustrum.h | 2 + Code/OysterPhysics3D/ICollideable.h | 2 + Code/OysterPhysics3D/Line.cpp | 12 ++ Code/OysterPhysics3D/Line.h | 2 + Code/OysterPhysics3D/OysterCollision3D.cpp | 39 ++++++ Code/OysterPhysics3D/OysterCollision3D.h | 3 + .../OysterPhysics3D.vcxproj.filters | 6 +- Code/OysterPhysics3D/Plane.cpp | 12 ++ Code/OysterPhysics3D/Plane.h | 2 + Code/OysterPhysics3D/Point.cpp | 14 +++ Code/OysterPhysics3D/Point.h | 2 + Code/OysterPhysics3D/Ray.cpp | 12 ++ Code/OysterPhysics3D/Ray.h | 2 + Code/OysterPhysics3D/RigidBody.cpp | 14 ++- Code/OysterPhysics3D/RigidBody.h | 2 +- Code/OysterPhysics3D/Sphere.cpp | 28 ++++- Code/OysterPhysics3D/Sphere.h | 51 +++++--- Code/OysterPhysics3D/Universe.cpp | 5 + Code/OysterPhysics3D/Universe.h | 2 + 35 files changed, 553 insertions(+), 102 deletions(-) diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 9880526d..614014e2 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -60,6 +60,8 @@ namespace return; } + // calculate and store time interpolation value, for later rebound. + proto->SetTimeOfContact( worldPointOfContact ); // bounce Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(), diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index a2871229..d1be7d61 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -49,14 +49,21 @@ SimpleRigidBody::SimpleRigidBody() this->onCollision = Default::EventAction_BeforeCollisionResponse; this->onCollisionResponse = Default::EventAction_AfterCollisionResponse; this->onMovement = Default::EventAction_Move; + + this->collisionRebound.previousSpatial.center = this->rigid.centerPos; + this->collisionRebound.previousSpatial.axis = this->rigid.axis; + this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach; + this->collisionRebound.timeOfContact = 1.0f; + this->scene = nullptr; this->customTag = nullptr; this->ignoreGravity = this->isForwarded = false; } SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc ) -{ - //this->rigid.SetRotation( desc.rotation ); +{ + this->rigid = RigidBody(); + this->rigid.SetRotation( desc.rotation ); this->rigid.centerPos = desc.centerPosition; this->rigid.SetSize( desc.size ); this->rigid.SetMass_KeepMomentum( desc.mass ); @@ -66,6 +73,11 @@ SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc ) this->gravityNormal = Float3::null; + this->collisionRebound.previousSpatial.center = this->rigid.centerPos; + this->collisionRebound.previousSpatial.axis = this->rigid.axis; + this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach; + this->collisionRebound.timeOfContact = 1.0f; + if( desc.subscription_onCollision ) { this->onCollision = desc.subscription_onCollision; @@ -198,6 +210,26 @@ bool SimpleRigidBody::Intersects( const ICustomBody &object, Float4 &worldPointO return object.Intersects( Box(this->rigid.GetRotationMatrix(), this->rigid.centerPos, this->rigid.GetSize()), worldPointOfContact ); } +void SimpleRigidBody::SetTimeOfContact( Float4 &worldPointOfContact ) +{ + Point pointOfContact = Point( worldPointOfContact ); + Box start = Box(); + { + start.rotation = RotationMatrix( this->collisionRebound.previousSpatial.axis ); + start.center = this->collisionRebound.previousSpatial.center; + start.boundingOffset = this->collisionRebound.previousSpatial.reach; + } + Box end = Box(); + { + end.rotation = RotationMatrix( this->rigid.axis ); + end.center = this->rigid.centerPos; + end.boundingOffset = this->rigid.boundingReach; + } + Float timeOfContact = ::Oyster::Collision3D::Utility::TimeOfContact( start, end, pointOfContact ); + + this->collisionRebound.timeOfContact = Min( this->collisionRebound.timeOfContact, timeOfContact ); +} + Sphere & SimpleRigidBody::GetBoundingSphere( Sphere &targetMem ) const { return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.GetMagnitude() ); @@ -293,18 +325,52 @@ void * SimpleRigidBody::GetCustomTag() const UpdateState SimpleRigidBody::Update( Float timeStepLength ) { - if( this->isForwarded ) - { - this->rigid.Move( this->deltaPos.xyz, this->deltaAxis.xyz ); - this->deltaPos = Float4::null; - this->deltaAxis = Float4::null; - this->isForwarded = false; - } + //if( this->isForwarded ) + //{ + // this->rigid.Move( this->deltaPos.xyz, this->deltaAxis.xyz ); + // this->deltaPos = Float4::null; + // this->deltaAxis = Float4::null; + // this->isForwarded = false; + //} this->rigid.Update_LeapFrog( timeStepLength ); - //! @todo TODO: compare previous and new state and return result - //return this->current == this->previous ? UpdateState_resting : UpdateState_altered; + { // Rebound if needed + if( this->collisionRebound.timeOfContact < 1.0f ) + { + 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 ); + } + + // Update rebound data + 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; + } + + { // Maintain rotation resolution by keeping axis within [0, 2pi] (trigonometric methods gets faster too) + Float3 n; + ::std::modf( this->rigid.axis * (0.5f / pi), n ); + this->rigid.axis -= (2.0f * pi) * n; + } + + { // Check if this is close enough to be set resting + unsigned char resting = 0; + if( this->rigid.momentum_Linear.Dot(this->rigid.momentum_Linear) <= (Constant::epsilon * Constant::epsilon) ) + { + this->rigid.momentum_Linear = Float3::null; + resting = 1; + } + if( this->rigid.momentum_Angular.Dot(this->rigid.momentum_Angular) <= (Constant::epsilon * Constant::epsilon) ) + { + this->rigid.momentum_Angular = Float3::null; + ++resting; + } + if( resting == 2 ) return UpdateState_resting; + } + return UpdateState_altered; } diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.h b/Code/GamePhysics/Implementation/SimpleRigidBody.h index 9e61cee3..1811c911 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.h @@ -30,6 +30,8 @@ namespace Oyster { namespace Physics bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const; bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const; + void SetTimeOfContact( ::Oyster::Math::Float4 &worldPointOfContact ); + ::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const; ::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const; ::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; @@ -65,9 +67,17 @@ namespace Oyster { namespace Physics ::Oyster::Physics3D::RigidBody rigid; ::Oyster::Math::Float4 deltaPos, deltaAxis; ::Oyster::Math::Float3 gravityNormal; + + struct + { + struct { ::Oyster::Math::Float3 center, axis, reach; } previousSpatial; + ::Oyster::Math::Float timeOfContact; + } collisionRebound; + EventAction_BeforeCollisionResponse onCollision; EventAction_AfterCollisionResponse onCollisionResponse; EventAction_Move onMovement; + Octree *scene; void *customTag; bool ignoreGravity, isForwarded; diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index f6f89c64..49aed408 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -11,11 +11,17 @@ using namespace ::Utility::Value; SphericalRigidBody::SphericalRigidBody() { this->rigid = RigidBody(); - this->rigid.SetMass_KeepMomentum( 10.0f ); + this->rigid.SetMass_KeepMomentum( 16.0f ); this->gravityNormal = Float3::null; this->onCollision = Default::EventAction_BeforeCollisionResponse; this->onCollisionResponse = Default::EventAction_AfterCollisionResponse; this->onMovement = Default::EventAction_Move; + + this->collisionRebound.previousSpatial.center = this->rigid.centerPos; + this->collisionRebound.previousSpatial.axis = this->rigid.axis; + this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach; + this->collisionRebound.timeOfContact = 1.0f; + this->scene = nullptr; this->customTag = nullptr; this->ignoreGravity = this->isForwarded = false; @@ -24,7 +30,7 @@ SphericalRigidBody::SphericalRigidBody() SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc ) { this->rigid = RigidBody(); - //this->rigid.SetRotation( desc.rotation ); + this->rigid.SetRotation( desc.rotation ); this->rigid.centerPos = desc.centerPosition; this->rigid.boundingReach = Float4( desc.radius, desc.radius, desc.radius, 0.0f ); this->rigid.SetMass_KeepMomentum( desc.mass ); @@ -34,6 +40,11 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des this->gravityNormal = Float3::null; + this->collisionRebound.previousSpatial.center = this->rigid.centerPos; + this->collisionRebound.previousSpatial.axis = this->rigid.axis; + this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach; + this->collisionRebound.timeOfContact = 1.0f; + if( desc.subscription_onCollision ) { this->onCollision = desc.subscription_onCollision; @@ -64,6 +75,11 @@ SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &des this->scene = nullptr; this->customTag = nullptr; this->ignoreGravity = desc.ignoreGravity; + + this->collisionRebound.previousSpatial.center = this->rigid.centerPos; + this->collisionRebound.previousSpatial.axis = this->rigid.axis; + this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach; + this->collisionRebound.timeOfContact = 1.0f; } SphericalRigidBody::~SphericalRigidBody() {} @@ -165,6 +181,17 @@ bool SphericalRigidBody::Intersects( const ICustomBody &object, Float4 &worldPoi return object.Intersects( Sphere(this->rigid.centerPos, this->rigid.boundingReach.x), worldPointOfContact ); } +void SphericalRigidBody::SetTimeOfContact( Float4 &worldPointOfContact ) +{ + Point pointOfContact = Point( worldPointOfContact ); + Sphere start = Sphere( this->collisionRebound.previousSpatial.center, this->collisionRebound.previousSpatial.reach.x ); + Sphere end = Sphere( this->rigid.centerPos, this->rigid.boundingReach.x ); + + Float timeOfContact = ::Oyster::Collision3D::Utility::TimeOfContact( start, end, pointOfContact ); + + this->collisionRebound.timeOfContact = Min( this->collisionRebound.timeOfContact, timeOfContact ); +} + Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const { return targetMem = Sphere( this->rigid.centerPos, this->rigid.boundingReach.x ); @@ -219,18 +246,52 @@ void * SphericalRigidBody::GetCustomTag() const UpdateState SphericalRigidBody::Update( Float timeStepLength ) { - if( this->isForwarded ) - { - this->rigid.Move( this->deltaPos.xyz, this->deltaAxis.xyz ); - this->deltaPos = Float4::null; - this->deltaAxis = Float4::null; - this->isForwarded = false; - } + //if( this->isForwarded ) + //{ + // this->rigid.Move( this->deltaPos.xyz, this->deltaAxis.xyz ); + // this->deltaPos = Float4::null; + // this->deltaAxis = Float4::null; + // this->isForwarded = false; + //} this->rigid.Update_LeapFrog( timeStepLength ); - // compare previous and new state and return result - //return this->current == this->previous ? UpdateState_resting : UpdateState_altered; + { // Rebound if needed + if( this->collisionRebound.timeOfContact < 1.0f ) + { + 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 ); + } + + // Update rebound data + 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; + } + + { // Maintain rotation resolution by keeping axis within [0, 2pi] (trigonometric methods gets faster too) + Float3 n; + ::std::modf( this->rigid.axis * (0.5f / pi), n ); + this->rigid.axis -= (2.0f * pi) * n; + } + + { // Check if this is close enough to be set resting + unsigned char resting = 0; + if( this->rigid.momentum_Linear.Dot(this->rigid.momentum_Linear) <= (Constant::epsilon * Constant::epsilon) ) + { + this->rigid.momentum_Linear = Float3::null; + resting = 1; + } + if( this->rigid.momentum_Angular.Dot(this->rigid.momentum_Angular) <= (Constant::epsilon * Constant::epsilon) ) + { + this->rigid.momentum_Angular = Float3::null; + ++resting; + } + if( resting == 2 ) return UpdateState_resting; + } + return UpdateState_altered; } diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.h b/Code/GamePhysics/Implementation/SphericalRigidBody.h index 390b7171..c2dc8131 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.h +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.h @@ -31,6 +31,8 @@ namespace Oyster { namespace Physics bool Intersects( const ::Oyster::Collision3D::ICollideable &shape, ::Oyster::Math::Float4 &worldPointOfContact ) const; bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const; + void SetTimeOfContact( ::Oyster::Math::Float4 &worldPointOfContact ); + ::Oyster::Collision3D::Sphere & GetBoundingSphere( ::Oyster::Collision3D::Sphere &targetMem = ::Oyster::Collision3D::Sphere() ) const; ::Oyster::Math::Float4 & GetNormalAt( const ::Oyster::Math::Float4 &worldPos, ::Oyster::Math::Float4 &targetMem = ::Oyster::Math::Float4() ) const; ::Oyster::Math::Float3 & GetGravityNormal( ::Oyster::Math::Float3 &targetMem = ::Oyster::Math::Float3() ) const; @@ -66,6 +68,13 @@ namespace Oyster { namespace Physics ::Oyster::Physics3D::RigidBody rigid; ::Oyster::Math::Float4 deltaPos, deltaAxis; ::Oyster::Math::Float3 gravityNormal; + + struct + { + struct { ::Oyster::Math::Float3 center, axis, reach; } previousSpatial; + ::Oyster::Math::Float timeOfContact; + } collisionRebound; + EventAction_BeforeCollisionResponse onCollision; EventAction_AfterCollisionResponse onCollisionResponse; EventAction_Move onMovement; diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h index 080b8d30..f636bb73 100644 --- a/Code/GamePhysics/PhysicsAPI.h +++ b/Code/GamePhysics/PhysicsAPI.h @@ -322,6 +322,11 @@ namespace Oyster ********************************************************/ virtual bool Intersects( const ICustomBody &object, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0; + /******************************************************** + * Sets how far back it needs to be interpolated to not be overlapping worldPointOfContact. + ********************************************************/ + virtual void SetTimeOfContact( ::Oyster::Math::Float4 &worldPointOfContact ) = 0; + /******************************************************** * Required by Engine's Collision Search. * @param targetMem: Provided memory that written into and then returned. diff --git a/Code/GamePhysics/PhysicsStructs-Impl.h b/Code/GamePhysics/PhysicsStructs-Impl.h index af2fb91c..311b81f8 100644 --- a/Code/GamePhysics/PhysicsStructs-Impl.h +++ b/Code/GamePhysics/PhysicsStructs-Impl.h @@ -12,7 +12,7 @@ namespace Oyster { inline SimpleBodyDescription::SimpleBodyDescription() { - this->rotation = ::Oyster::Math::Float4x4::identity; + this->rotation = ::Oyster::Math::Float3::null; this->centerPosition = ::Oyster::Math::Float3::null; this->size = ::Oyster::Math::Float3( 1.0f ); this->mass = 6.0f; @@ -28,7 +28,7 @@ namespace Oyster inline SphericalBodyDescription::SphericalBodyDescription() { - this->rotation = ::Oyster::Math::Float4x4::identity; + this->rotation = ::Oyster::Math::Float3::null; this->centerPosition = ::Oyster::Math::Float3::null; this->radius = 0.5f; this->mass = 10.0f; diff --git a/Code/GamePhysics/PhysicsStructs.h b/Code/GamePhysics/PhysicsStructs.h index aef157a8..61a0569f 100644 --- a/Code/GamePhysics/PhysicsStructs.h +++ b/Code/GamePhysics/PhysicsStructs.h @@ -11,7 +11,7 @@ namespace Oyster { namespace Physics { struct SimpleBodyDescription { - ::Oyster::Math::Float4x4 rotation; + ::Oyster::Math::Float3 rotation; ::Oyster::Math::Float3 centerPosition; ::Oyster::Math::Float3 size; ::Oyster::Math::Float mass; @@ -29,7 +29,7 @@ namespace Oyster { namespace Physics struct SphericalBodyDescription { - ::Oyster::Math::Float4x4 rotation; + ::Oyster::Math::Float3 rotation; ::Oyster::Math::Float3 centerPosition; ::Oyster::Math::Float radius; ::Oyster::Math::Float mass; diff --git a/Code/Misc/Utilities.h b/Code/Misc/Utilities.h index 9c71a515..9b3abac0 100644 --- a/Code/Misc/Utilities.h +++ b/Code/Misc/Utilities.h @@ -315,6 +315,14 @@ namespace Utility { using ::std::numeric_limits; + template + 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 inline ValueType Abs( const ValueType &value ) { return value < 0 ? value * -1 : value; } diff --git a/Code/OysterMath/LinearMath.h b/Code/OysterMath/LinearMath.h index dce7a026..ebb1e375 100644 --- a/Code/OysterMath/LinearMath.h +++ b/Code/OysterMath/LinearMath.h @@ -11,27 +11,6 @@ #include "Quaternion.h" #include -namespace std -{ - template - inline ::LinearAlgebra::Vector2 asin( const ::LinearAlgebra::Vector2 &vec ) - { - return ::LinearAlgebra::Vector2( asin(vec.x), asin(vec.y) ); - } - - template - inline ::LinearAlgebra::Vector3 asin( const ::LinearAlgebra::Vector3 &vec ) - { - return ::LinearAlgebra::Vector3( asin(vec.x), asin(vec.y), asin(vec.z) ); - } - - template - inline ::LinearAlgebra::Vector4 asin( const ::LinearAlgebra::Vector4 &vec ) - { - return ::LinearAlgebra::Vector4( asin(vec.x), asin(vec.y), asin(vec.z), asin(vec.w) ); - } -} - // x2 template @@ -112,6 +91,69 @@ inline ::LinearAlgebra::Vector4 operator * ( const ::LinearAlgebra:: (vector.x * matrix.m14) + (vector.y * matrix.m24) + (vector.z * matrix.m34) + (vector.w * matrix.m44) ); } +namespace std +{ + template + inline ::LinearAlgebra::Vector2 asin( const ::LinearAlgebra::Vector2 &vec ) + { + return ::LinearAlgebra::Vector2( asin(vec.x), asin(vec.y) ); + } + + template + inline ::LinearAlgebra::Vector3 asin( const ::LinearAlgebra::Vector3 &vec ) + { + return ::LinearAlgebra::Vector3( asin(vec.x), asin(vec.y), asin(vec.z) ); + } + + template + inline ::LinearAlgebra::Vector4 asin( const ::LinearAlgebra::Vector4 &vec ) + { + return ::LinearAlgebra::Vector4( 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 + inline ::LinearAlgebra::Vector2 modf( const ::LinearAlgebra::Vector2 &vec, ::LinearAlgebra::Vector2 &numerator ) + { + ::LinearAlgebra::Vector2 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 + inline ::LinearAlgebra::Vector3 modf( const ::LinearAlgebra::Vector3 &vec, ::LinearAlgebra::Vector3 &numerator ) + { + ::LinearAlgebra::Vector3 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 + inline ::LinearAlgebra::Vector4 modf( const ::LinearAlgebra::Vector4 &vec, ::LinearAlgebra::Vector4 &numerator ) + { + ::LinearAlgebra::Vector4 denominator; + denominator.x = (ScalarType)modf( vec.x, &numerator.x ); + denominator.y = (ScalarType)modf( vec.y, &numerator.y ); + denominator.z = (ScalarType)modf( vec.z, &numerator.z ); + denominator.w = (ScalarType)modf( vec.w, &numerator.w ); + return denominator; + } +} + namespace LinearAlgebra { // Creates a solution matrix for 'out´= 'targetMem' * 'in'. @@ -795,11 +837,42 @@ namespace LinearAlgebra3D } template - ::LinearAlgebra::Matrix4x4 & InterpolateOrientation_UsingNonRigidNlerp( const ::LinearAlgebra::Matrix4x4 &start, const ::LinearAlgebra::Matrix4x4 &end, ScalarType t, ::LinearAlgebra::Matrix4x4 &targetMem ) + inline ::LinearAlgebra::Matrix4x4 & InterpolateRotation_UsingNonRigidNlerp( const ::LinearAlgebra::Matrix4x4 &start, const ::LinearAlgebra::Matrix4x4 &end, ScalarType t, ::LinearAlgebra::Matrix4x4 &targetMem ) { targetMem.v[0] = ::LinearAlgebra::Nlerp( start.v[0], end.v[0], t ); targetMem.v[1] = ::LinearAlgebra::Nlerp( start.v[1], end.v[1], t ); targetMem.v[2] = ::LinearAlgebra::Nlerp( start.v[2], end.v[2], t ); + return targetMem; + } + + template + inline ::LinearAlgebra::Matrix4x4 & InterpolateOrientation_UsingNonRigidNlerp( const ::LinearAlgebra::Matrix4x4 &start, const ::LinearAlgebra::Matrix4x4 &end, ScalarType t, ::LinearAlgebra::Matrix4x4 &targetMem ) + { + InterpolateRotation_UsingNonRigidNlerp( start, end, t, targetMem ); + targetMem.v[3] = ::LinearAlgebra::Lerp( start.v[3], end.v[3], t ); + return targetMem; + } + + template + ::LinearAlgebra::Matrix4x4 & InterpolateRotation_UsingRigidNlerp( const ::LinearAlgebra::Matrix4x4 &start, const ::LinearAlgebra::Matrix4x4 &end, ScalarType t, ::LinearAlgebra::Matrix4x4 &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 + inline ::LinearAlgebra::Matrix4x4 & InterpolateOrientation_UsingRigidNlerp( const ::LinearAlgebra::Matrix4x4 &start, const ::LinearAlgebra::Matrix4x4 &end, ScalarType t, ::LinearAlgebra::Matrix4x4 &targetMem ) + { + InterpolateRotation_UsingRigidNlerp( start, end, t, targetMem ); targetMem.v[3] = ::LinearAlgebra::Lerp( start.v[3], end.v[3], t ); return targetMem; } diff --git a/Code/OysterMath/OysterMath.h b/Code/OysterMath/OysterMath.h index 7e123183..23ee06db 100644 --- a/Code/OysterMath/OysterMath.h +++ b/Code/OysterMath/OysterMath.h @@ -322,7 +322,10 @@ namespace Oyster { namespace Math3D //! Oyster's native math library specialized using ::LinearAlgebra3D::SnapAxisYToNormal_UsingNlerp; using ::LinearAlgebra3D::InterpolateAxisYToNormal_UsingNlerp; + using ::LinearAlgebra3D::InterpolateRotation_UsingNonRigidNlerp; + using ::LinearAlgebra3D::InterpolateRotation_UsingRigidNlerp; using ::LinearAlgebra3D::InterpolateOrientation_UsingNonRigidNlerp; + using ::LinearAlgebra3D::InterpolateOrientation_UsingRigidNlerp; using ::LinearAlgebra3D::InterpolateOrientation_UsingSlerp; using ::LinearAlgebra3D::SnapAngularAxis; } } diff --git a/Code/OysterPhysics3D/Box.cpp b/Code/OysterPhysics3D/Box.cpp index f55415b7..56950e24 100644 --- a/Code/OysterPhysics3D/Box.cpp +++ b/Code/OysterPhysics3D/Box.cpp @@ -92,4 +92,27 @@ bool Box::Contains( const ICollideable &target ) const //case Type_frustrum: return false; // TODO: default: return false; } -} \ No newline at end of file +} + +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; + } +} } \ No newline at end of file diff --git a/Code/OysterPhysics3D/Box.h b/Code/OysterPhysics3D/Box.h index f98ae362..553037be 100644 --- a/Code/OysterPhysics3D/Box.h +++ b/Code/OysterPhysics3D/Box.h @@ -9,35 +9,48 @@ #include "OysterMath.h" #include "ICollideable.h" -namespace Oyster { namespace Collision3D +namespace Oyster { - class Box : public ICollideable + namespace Collision3D { - public: - union + class Box : public ICollideable { - struct{ ::Oyster::Math::Float4x4 rotation; ::Oyster::Math::Float4 center, boundingOffset; }; - struct + public: + union { - ::Oyster::Math::Float4 xAxis; - ::Oyster::Math::Float4 yAxis; - ::Oyster::Math::Float4 zAxis; + struct{ ::Oyster::Math::Float4x4 rotation; ::Oyster::Math::Float4 center, boundingOffset; }; + struct + { + ::Oyster::Math::Float4 xAxis; + ::Oyster::Math::Float4 yAxis; + ::Oyster::Math::Float4 zAxis; + }; + char byte[sizeof(::Oyster::Math::Float4x4) + 2*sizeof(::Oyster::Math::Float4)]; }; - char byte[sizeof(::Oyster::Math::Float4x4) + 2*sizeof(::Oyster::Math::Float4)]; + + Box( ); + Box( const ::Oyster::Math::Float4x4 &rotation, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &size ); + Box( const ::Oyster::Math::Float4x4 &rotation, const ::Oyster::Math::Float4 &worldPos, const ::Oyster::Math::Float4 &size ); + virtual ~Box( ); + + Box & operator = ( const Box &box ); + + virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; + bool Intersects( const ICollideable &target ) const; + bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const; + bool Contains( const ICollideable &target ) const; + + ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const; }; + } - Box( ); - Box( const ::Oyster::Math::Float4x4 &rotation, const ::Oyster::Math::Float3 &worldPos, const ::Oyster::Math::Float3 &size ); - Box( const ::Oyster::Math::Float4x4 &rotation, const ::Oyster::Math::Float4 &worldPos, const ::Oyster::Math::Float4 &size ); - virtual ~Box( ); - - Box & operator = ( const Box &box ); - - virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable &target ) const; - bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const; - bool Contains( const ICollideable &target ) 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 \ No newline at end of file diff --git a/Code/OysterPhysics3D/BoxAxisAligned.cpp b/Code/OysterPhysics3D/BoxAxisAligned.cpp index bd10016f..8c934617 100644 --- a/Code/OysterPhysics3D/BoxAxisAligned.cpp +++ b/Code/OysterPhysics3D/BoxAxisAligned.cpp @@ -76,4 +76,16 @@ bool BoxAxisAligned::Contains( const ICollideable &target ) const //default: 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; + } } \ No newline at end of file diff --git a/Code/OysterPhysics3D/BoxAxisAligned.h b/Code/OysterPhysics3D/BoxAxisAligned.h index 2ff39463..9ad55165 100644 --- a/Code/OysterPhysics3D/BoxAxisAligned.h +++ b/Code/OysterPhysics3D/BoxAxisAligned.h @@ -31,6 +31,8 @@ namespace Oyster { namespace Collision3D bool Intersects( const ICollideable &target ) const; bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const; bool Contains( const ICollideable &target ) const; + + ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const; }; } } diff --git a/Code/OysterPhysics3D/Frustrum.cpp b/Code/OysterPhysics3D/Frustrum.cpp index ce2c5256..32e6357b 100644 --- a/Code/OysterPhysics3D/Frustrum.cpp +++ b/Code/OysterPhysics3D/Frustrum.cpp @@ -243,6 +243,18 @@ bool Frustrum::Contains( const ICollideable &target ) const } } +Float Frustrum::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const +{ + if( deuterStart.type != deuterEnd.type ) + return -1.0f; + + switch( deuterStart.type ) + { // TODO: more to implement + case Type_universe: return 0.0f; + default: return 1.0f; + } +} + ::Oyster::Math::Float3 Frustrum::ExtractForwad() { return this->bottomPlane.normal.xyz; diff --git a/Code/OysterPhysics3D/Frustrum.h b/Code/OysterPhysics3D/Frustrum.h index ae0f086c..0c4cc04f 100644 --- a/Code/OysterPhysics3D/Frustrum.h +++ b/Code/OysterPhysics3D/Frustrum.h @@ -42,6 +42,8 @@ namespace Oyster { namespace Collision3D bool Intersects( const ICollideable &target, Oyster::Math::Float4 &worldPointOfContact ) const; bool Contains( const ICollideable &target ) const; + ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const; + ::Oyster::Math::Float3 ExtractForwad(); }; diff --git a/Code/OysterPhysics3D/ICollideable.h b/Code/OysterPhysics3D/ICollideable.h index b3f61671..3e63200e 100644 --- a/Code/OysterPhysics3D/ICollideable.h +++ b/Code/OysterPhysics3D/ICollideable.h @@ -38,6 +38,8 @@ namespace Oyster { namespace Collision3D //! Contains a collection of 3D shapes virtual bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const = 0; virtual bool Intersects( const ICollideable &target ) const = 0; virtual bool Contains( const ICollideable &target ) const = 0; + + virtual ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const = 0; }; } } #endif \ No newline at end of file diff --git a/Code/OysterPhysics3D/Line.cpp b/Code/OysterPhysics3D/Line.cpp index cebceaff..fc81791d 100644 --- a/Code/OysterPhysics3D/Line.cpp +++ b/Code/OysterPhysics3D/Line.cpp @@ -76,3 +76,15 @@ bool Line::Intersects( const ICollideable &target, Float4 &worldPointOfContact ) bool Line::Contains( const ICollideable &target ) const { /* TODO: : */ return false; } + +Float Line::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const +{ + if( deuterStart.type != deuterEnd.type ) + return -1.0f; + + switch( deuterStart.type ) + { // TODO: more to implement + case Type_universe: return 0.0f; + default: return 1.0f; + } +} \ No newline at end of file diff --git a/Code/OysterPhysics3D/Line.h b/Code/OysterPhysics3D/Line.h index 2e6d2d55..a305622f 100644 --- a/Code/OysterPhysics3D/Line.h +++ b/Code/OysterPhysics3D/Line.h @@ -32,6 +32,8 @@ namespace Oyster { namespace Collision3D bool Intersects( const ICollideable &target ) const; bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const; bool Contains( const ICollideable &target ) const; + + ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const; }; } } diff --git a/Code/OysterPhysics3D/OysterCollision3D.cpp b/Code/OysterPhysics3D/OysterCollision3D.cpp index 89b3af8a..cc68d536 100644 --- a/Code/OysterPhysics3D/OysterCollision3D.cpp +++ b/Code/OysterPhysics3D/OysterCollision3D.cpp @@ -1061,4 +1061,43 @@ namespace Oyster { namespace Collision3D { namespace Utility return container.normal == -plane.normal; return false; } + + Float TimeOfContact( const Sphere &protoStart, const Sphere &protoEnd, const Point &deuter ) + { // Bisection with 5 levels of detail + Float t = 0.5f; + Sphere s; + for( int i = 0; i < 5; ++i ) + { + Nlerp( protoStart, protoEnd, t, s ); + if( Intersect(s, deuter) ) + { + t *= 0.5f; + } + else + { + t *= 1.5f; + } + } + return t; + } + + Float TimeOfContact( const Box &protoStart, const Box &protoEnd, const Point &deuter ) + { // Bisection with 5 levels of detail + Float t = 0.5f; + Box b; + for( int i = 0; i < 5; ++i ) + { + Nlerp( protoStart, protoEnd, t, b ); + if( Intersect(b, deuter) ) + { + t *= 0.5f; + } + else + { + t *= 1.5f; + } + } + return t; + } + } } } \ No newline at end of file diff --git a/Code/OysterPhysics3D/OysterCollision3D.h b/Code/OysterPhysics3D/OysterCollision3D.h index 20a55a18..83a6239e 100644 --- a/Code/OysterPhysics3D/OysterCollision3D.h +++ b/Code/OysterPhysics3D/OysterCollision3D.h @@ -121,6 +121,9 @@ namespace Oyster { namespace Collision3D { namespace Utility // bool Contains( const Frustrum &container, const BoxAxisAligned &box ); // bool Contains( const Frustrum &container, const Box &box ); // bool Contains( const Frustrum &container, const Frustrum &frustrum ); + + ::Oyster::Math::Float TimeOfContact( const Sphere &protoStart, const Sphere &protoEnd, const Point &deuter ); + ::Oyster::Math::Float TimeOfContact( const Box &protoStart, const Box &protoEnd, const Point &deuter ); } } } #endif \ No newline at end of file diff --git a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters index da336ce5..f6b6d934 100644 --- a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters +++ b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters @@ -27,9 +27,6 @@ - - Header Files\Collision - Header Files\Collision @@ -81,6 +78,9 @@ Header Files\Physics + + Header Files\Collision + diff --git a/Code/OysterPhysics3D/Plane.cpp b/Code/OysterPhysics3D/Plane.cpp index 59ffbc47..2923a802 100644 --- a/Code/OysterPhysics3D/Plane.cpp +++ b/Code/OysterPhysics3D/Plane.cpp @@ -83,4 +83,16 @@ bool Plane::Contains( const ICollideable &target ) const //case Type_triangle: return false; // TODO: 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; + } } \ No newline at end of file diff --git a/Code/OysterPhysics3D/Plane.h b/Code/OysterPhysics3D/Plane.h index f148ed8e..a66e7f3b 100644 --- a/Code/OysterPhysics3D/Plane.h +++ b/Code/OysterPhysics3D/Plane.h @@ -31,6 +31,8 @@ namespace Oyster { namespace Collision3D bool Intersects( const ICollideable &target ) const; bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const; bool Contains( const ICollideable &target ) const; + + ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const; }; } } diff --git a/Code/OysterPhysics3D/Point.cpp b/Code/OysterPhysics3D/Point.cpp index 788ab32d..dd879e27 100644 --- a/Code/OysterPhysics3D/Point.cpp +++ b/Code/OysterPhysics3D/Point.cpp @@ -81,4 +81,18 @@ bool Point::Contains( const ICollideable &target ) const case Type_point: return Utility::Intersect( *this, (const Point&)target ); 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; + } } \ No newline at end of file diff --git a/Code/OysterPhysics3D/Point.h b/Code/OysterPhysics3D/Point.h index 60486373..15abc488 100644 --- a/Code/OysterPhysics3D/Point.h +++ b/Code/OysterPhysics3D/Point.h @@ -31,6 +31,8 @@ namespace Oyster { namespace Collision3D bool Intersects( const ICollideable &target ) const; bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const; bool Contains( const ICollideable &target ) const; + + ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const; }; } } diff --git a/Code/OysterPhysics3D/Ray.cpp b/Code/OysterPhysics3D/Ray.cpp index e7f21de8..5e58d14b 100644 --- a/Code/OysterPhysics3D/Ray.cpp +++ b/Code/OysterPhysics3D/Ray.cpp @@ -92,4 +92,16 @@ bool Ray::Contains( const ICollideable &target ) const case Type_ray: return Utility::Contains( *this, (const Ray&)target ); 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; + } } \ No newline at end of file diff --git a/Code/OysterPhysics3D/Ray.h b/Code/OysterPhysics3D/Ray.h index a85580b3..cd797539 100644 --- a/Code/OysterPhysics3D/Ray.h +++ b/Code/OysterPhysics3D/Ray.h @@ -39,6 +39,8 @@ namespace Oyster { namespace Collision3D bool Intersects( const ICollideable &target ) const; bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const; bool Contains( const ICollideable &target ) const; + + ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const; }; } } diff --git a/Code/OysterPhysics3D/RigidBody.cpp b/Code/OysterPhysics3D/RigidBody.cpp index 70ded863..68f435e9 100644 --- a/Code/OysterPhysics3D/RigidBody.cpp +++ b/Code/OysterPhysics3D/RigidBody.cpp @@ -53,13 +53,9 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength ) //! HACK: @todo Add real solution with fluid drag this->momentum_Linear = this->momentum_Linear*0.99f; this->momentum_Angular = this->momentum_Angular*0.99f; + // ds = dt * Formula::LinearVelocity( m, avg_G ) = dt * avg_G / m = (dt / m) * avg_G - Float3 deltaPos = ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear ); - if( deltaPos.GetLength() < 0.001f ) - { - deltaPos = Float3::null; - } - this->centerPos += deltaPos; + this->centerPos += ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear ); // updating the angular // dO = dt * Formula::AngularVelocity( (RI)^-1, avg_H ) = dt * (RI)^-1 * avg_H @@ -185,6 +181,12 @@ void RigidBody::SetMass_KeepMomentum( const Float &m ) } } +void RigidBody::SetRotation( const Float3 &axis ) +{ // by Dan Andersson + this->axis = axis; + this->rotation = Rotation( this->axis ); +} + void RigidBody::SetMomentum_Linear( const Float3 &worldG, const Float3 &atWorldPos ) { // by Dan Andersson Float3 worldOffset = atWorldPos - this->centerPos; diff --git a/Code/OysterPhysics3D/RigidBody.h b/Code/OysterPhysics3D/RigidBody.h index c666662a..f7aebd22 100644 --- a/Code/OysterPhysics3D/RigidBody.h +++ b/Code/OysterPhysics3D/RigidBody.h @@ -64,7 +64,7 @@ namespace Oyster { namespace Physics3D void SetMass_KeepMomentum( const ::Oyster::Math::Float &m ); //void SetOrientation( const ::Oyster::Math::Float4x4 &o ); - //void SetRotation( const ::Oyster::Math::Float4x4 &r ); + void SetRotation( const ::Oyster::Math::Float3 &axis ); void SetSize( const ::Oyster::Math::Float3 &widthHeight ); void SetMomentum_Linear( const ::Oyster::Math::Float3 &worldG, const ::Oyster::Math::Float3 &atWorldPos ); diff --git a/Code/OysterPhysics3D/Sphere.cpp b/Code/OysterPhysics3D/Sphere.cpp index c402b2ef..86230508 100644 --- a/Code/OysterPhysics3D/Sphere.cpp +++ b/Code/OysterPhysics3D/Sphere.cpp @@ -86,4 +86,30 @@ bool Sphere::Contains( const ICollideable &target ) const //case Type_frustrum: return false; // TODO: default: return false; } -} \ No newline at end of file +} + +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; + } +} } \ No newline at end of file diff --git a/Code/OysterPhysics3D/Sphere.h b/Code/OysterPhysics3D/Sphere.h index 2f483ecd..c3cc32a3 100644 --- a/Code/OysterPhysics3D/Sphere.h +++ b/Code/OysterPhysics3D/Sphere.h @@ -9,29 +9,42 @@ #include "OysterMath.h" #include "ICollideable.h" -namespace Oyster { namespace Collision3D +namespace Oyster { - class Sphere : public ICollideable + namespace Collision3D { - public: - union + class Sphere : public ICollideable { - struct{ ::Oyster::Math::Float4 center; ::Oyster::Math::Float radius; }; - char byte[sizeof(::Oyster::Math::Float4) + sizeof(::Oyster::Math::Float)]; + public: + union + { + struct{ ::Oyster::Math::Float4 center; ::Oyster::Math::Float radius; }; + char byte[sizeof(::Oyster::Math::Float4) + sizeof(::Oyster::Math::Float)]; + }; + + Sphere( ); + Sphere( const ::Oyster::Math::Float3 ¢er, const ::Oyster::Math::Float &radius ); + Sphere( const ::Oyster::Math::Float4 ¢er, const ::Oyster::Math::Float &radius ); + virtual ~Sphere( ); + + Sphere & operator = ( const Sphere &sphere ); + + virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; + bool Intersects( const ICollideable &target ) const; + bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const; + bool Contains( const ICollideable &target ) const; + + ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const; }; + } - Sphere( ); - Sphere( const ::Oyster::Math::Float3 ¢er, const ::Oyster::Math::Float &radius ); - Sphere( const ::Oyster::Math::Float4 ¢er, const ::Oyster::Math::Float &radius ); - virtual ~Sphere( ); - - Sphere & operator = ( const Sphere &sphere ); - - virtual ::Utility::DynamicMemory::UniquePointer Clone( ) const; - bool Intersects( const ICollideable &target ) const; - bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const; - bool Contains( const ICollideable &target ) 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 \ No newline at end of file diff --git a/Code/OysterPhysics3D/Universe.cpp b/Code/OysterPhysics3D/Universe.cpp index 7eb788ae..a3548ad9 100644 --- a/Code/OysterPhysics3D/Universe.cpp +++ b/Code/OysterPhysics3D/Universe.cpp @@ -78,4 +78,9 @@ bool Universe::Intersects( const ICollideable &target, Float4 &worldPointOfConta bool Universe::Contains( const ICollideable &target ) const { // universe contains everything return true; +} + +Float Universe::TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const +{ + return 0.0f; } \ No newline at end of file diff --git a/Code/OysterPhysics3D/Universe.h b/Code/OysterPhysics3D/Universe.h index 5f009e0b..7b5fb969 100644 --- a/Code/OysterPhysics3D/Universe.h +++ b/Code/OysterPhysics3D/Universe.h @@ -23,6 +23,8 @@ namespace Oyster { namespace Collision3D bool Intersects( const ICollideable &target ) const; bool Intersects( const ICollideable &target, ::Oyster::Math::Float4 &worldPointOfContact ) const; bool Contains( const ICollideable &target ) const; + + ::Oyster::Math::Float TimeOfContact( const ICollideable &deuterStart, const ICollideable &deuterEnd ) const; }; } } From a3886c4f1f688a5b95cafee0ccc829891d67fcf1 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Mon, 3 Feb 2014 15:52:00 +0100 Subject: [PATCH 36/74] GL - added models and started to fix camera movement --- .../DanBiasGame/GameClientState/GameState.cpp | 45 ++++++++++++++--- Code/Game/GameLogic/Game.h | 2 +- Code/Game/GameLogic/GameAPI.h | 2 +- Code/Game/GameLogic/Game_PlayerData.cpp | 9 +++- Code/Game/GameLogic/Object.cpp | 48 ++++++++++--------- Code/Game/GameLogic/Object.h | 7 +-- Code/Game/GameLogic/Player.cpp | 43 +++++++++++------ Code/Game/GameLogic/Player.h | 2 +- Code/Game/GameProtocols/PlayerProtocols.h | 6 +++ .../Implementation/GameSession_Gameplay.cpp | 3 +- 10 files changed, 115 insertions(+), 52 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index cd281717..638d954d 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -107,7 +107,7 @@ bool GameState::LoadModels(std::wstring mapFile) modelData.world = modelData.world * translate; modelData.visible = true; - modelData.modelPath = L"..\\Content\\Models\\char_white.dan"; + modelData.modelPath = L"char_renderTest.dan"; modelData.id = 2; // load models obj = new C_Player(); @@ -116,17 +116,43 @@ bool GameState::LoadModels(std::wstring mapFile) // add player model 2 modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 320, 0)); + translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(50, 320, 0)); modelData.world = modelData.world * translate; modelData.visible = true; - modelData.modelPath = L"..\\Content\\Models\\char_white.dan"; + modelData.modelPath = L"char_renderTest.dan"; modelData.id = 3; // 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, 300, 0)); + //Oyster::Math3D::RotationMatrix_AxisZ() + modelData.world = modelData.world * translate; + modelData.visible = true; + modelData.modelPath = L"building_corporation.dan"; + modelData.id = 4; + // load models + obj = new C_Player(); + privData->object.push_back(obj); + privData->object[privData->object.size() -1 ]->Init(modelData); + + // add crystal model + modelData.world = Oyster::Math3D::Float4x4::identity; + translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 305, 0)); + + modelData.world = modelData.world * translate; + modelData.visible = true; + modelData.modelPath = L"crystalformation_b.dan"; + modelData.id = 5; + // load models + obj = new C_Player(); + privData->object.push_back(obj); + privData->object[privData->object.size() -1 ]->Init(modelData); + return true; } @@ -282,14 +308,16 @@ void GameState::readKeyInput(InputClass* KeyInput) //send delta mouse movement if (KeyInput->IsMousePressed()) { - camera->Yaw(KeyInput->GetYaw()); + camera->Yaw(-KeyInput->GetYaw()); camera->Pitch(KeyInput->GetPitch()); camera->UpdateViewMatrix(); GameLogic::Protocol_PlayerLook playerLookDir; - Oyster::Math::Float3 look = camera->GetLook(); + Oyster::Math::Float4 look = camera->GetLook(); playerLookDir.lookDirX = look.x; playerLookDir.lookDirY = look.y; playerLookDir.lookDirZ = look.z; + playerLookDir.deltaX = -KeyInput->GetYaw(); + privData->nwClient->Send(playerLookDir); } @@ -357,11 +385,14 @@ void GameState::Protocol( ObjPos* pos ) { privData->object[i]->setPos(world); //camera->setRight((Oyster::Math::Float3(world[0], world[1], world[2]))); - //camera->setUp((Oyster::Math::Float3(world[4], world[5], world[6]))); + // //camera->setLook((Oyster::Math::Float3(world[8], world[9], world[10]))); if(i == myId) // playerobj { - camera->SetPosition(Oyster::Math::Float3(world[12], world[13]+2.2f, world[14]-1)); + Oyster::Math::Float3 up = (Oyster::Math::Float3(world[4], world[5]+2, world[6])); + Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13]+2, world[14]); + Oyster::Math::Float3 cameraPos = up + pos; + camera->SetPosition(pos); camera->UpdateViewMatrix(); } } diff --git a/Code/Game/GameLogic/Game.h b/Code/Game/GameLogic/Game.h index 3ea76b61..55f3e4cf 100644 --- a/Code/Game/GameLogic/Game.h +++ b/Code/Game/GameLogic/Game.h @@ -39,7 +39,7 @@ namespace GameLogic Oyster::Math::Float4x4 GetOrientation() override; int GetID() const override; OBJECT_TYPE GetObjectType() const override; - void Rotate(const Oyster::Math3D::Float3 lookDir) override; + void Rotate(const Oyster::Math3D::Float4 lookDir) override; Player *player; }; diff --git a/Code/Game/GameLogic/GameAPI.h b/Code/Game/GameLogic/GameAPI.h index ee4bad83..f0ce50b1 100644 --- a/Code/Game/GameLogic/GameAPI.h +++ b/Code/Game/GameLogic/GameAPI.h @@ -79,7 +79,7 @@ namespace GameLogic * @param x: The relative x axis * @param y: The relative y axis **/ - virtual void Rotate(const Oyster::Math3D::Float3 lookDir) = 0; + virtual void Rotate(const Oyster::Math3D::Float4 lookDir) = 0; /******************************************************** * Uses the chosen players weapon based on input diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index e19af2f3..18d058d0 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -11,13 +11,18 @@ Game::PlayerData::PlayerData() sbDesc.size = Oyster::Math::Float3(4,7,4); sbDesc.mass = 70; sbDesc.restitutionCoeff = 0.5; + sbDesc.rotation = Oyster::Math3D::RotationMatrix_AxisY(Utility::Value::Radian(180)); //create rigid body Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); //create player with this rigid body this->player = new Player(rigidBody,Object::DefaultCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER); this->player->GetRigidBody()->SetCustomTag(this); - + Oyster::Physics::ICustomBody::State state; + this->player->GetRigidBody()->GetState(state); + state.SetRotation(Oyster::Math::Float3(0, Oyster::Math::pi, 0)); + this->player->GetRigidBody()->SetState(state); + player->EndFrame(); } Game::PlayerData::PlayerData(int playerID,int teamID) { @@ -61,7 +66,7 @@ OBJECT_TYPE Game::PlayerData::GetObjectType() const { return this->player->GetObjectType(); } -void Game::PlayerData::Rotate(const Oyster::Math3D::Float3 lookDir) +void Game::PlayerData::Rotate(const Oyster::Math3D::Float4 lookDir) { this->player->Rotate(lookDir); } \ No newline at end of file diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index a0823247..8692aa72 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -22,8 +22,8 @@ Object::Object() this->type = OBJECT_TYPE::OBJECT_TYPE_UNKNOWN; this->objectID = GID(); - this->getState = this->rigidBody->GetState(); - this->setState = this->getState; + this->currPhysicsState = this->rigidBody->GetState(); + this->newPhysicsState = this->currPhysicsState; } Object::Object(OBJECT_TYPE type) @@ -34,8 +34,8 @@ Object::Object(OBJECT_TYPE type) Oyster::Physics::API::Instance().AddObject(rigidBody); this->type = type; this->objectID = GID(); - this->getState = this->rigidBody->GetState(); - this->setState = this->getState; + this->currPhysicsState = this->rigidBody->GetState(); + this->newPhysicsState = this->currPhysicsState; } Object::Object(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type) @@ -44,8 +44,8 @@ Object::Object(Oyster::Physics::ICustomBody *rigidBody, OBJECT_TYPE type) this->rigidBody = rigidBody; this->type = type; this->objectID = GID(); - this->getState = this->rigidBody->GetState(); - this->setState = this->getState; + this->currPhysicsState = this->rigidBody->GetState(); + this->newPhysicsState = this->currPhysicsState; } Object::Object(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type) @@ -57,8 +57,8 @@ Object::Object(void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE this->type = type; this->objectID = GID(); - this->getState = this->rigidBody->GetState(); - this->setState = this->getState; + this->currPhysicsState = this->rigidBody->GetState(); + this->newPhysicsState = this->currPhysicsState; } Object::Object(Oyster::Physics::ICustomBody *rigidBody ,void* collisionFuncBefore, void* collisionFuncAfter, OBJECT_TYPE type) @@ -71,8 +71,8 @@ Object::Object(Oyster::Physics::ICustomBody *rigidBody ,void* collisionFuncBefor this->type = type; this->objectID = GID(); - this->getState = this->rigidBody->GetState(); - this->setState = this->getState; + this->currPhysicsState = this->rigidBody->GetState(); + this->newPhysicsState = this->currPhysicsState; } Object::Object(Oyster::Physics::ICustomBody *rigidBody ,Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter), Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncAfter)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), OBJECT_TYPE type) @@ -86,13 +86,13 @@ Object::Object(Oyster::Physics::ICustomBody *rigidBody ,Oyster::Physics::ICustom this->type = type; this->objectID = GID(); - this->getState = this->rigidBody->GetState(); - this->setState = this->getState; + this->currPhysicsState = this->rigidBody->GetState(); + this->newPhysicsState = this->currPhysicsState; } void Object::ApplyLinearImpulse(Oyster::Math::Float3 force) { - setState.ApplyLinearImpulse(force); + newPhysicsState.ApplyLinearImpulse(force); } @@ -118,24 +118,28 @@ Oyster::Physics::ICustomBody* Object::GetRigidBody() void Object::BeginFrame() { + + this->rigidBody->SetState(this->newPhysicsState); + this->rigidBody->GetState(this->newPhysicsState); + Oyster::Math::Float4 axis; - if(setState.GetGravityNormal()!= Float3::null) + if(newPhysicsState.GetGravityNormal()!= Float3::null) { - Oyster::Math3D::SnapAngularAxis(Oyster::Math::Float4(setState.GetAngularAxis(), 0), Oyster::Math::Float4::standard_unit_y, -Oyster::Math::Float4(setState.GetGravityNormal()), axis); - setState.SetRotation(axis.xyz); - setState.SetAngularMomentum(Float3::null); + Oyster::Math3D::SnapAngularAxis(Oyster::Math::Float4(newPhysicsState.GetAngularAxis(), 0), Oyster::Math::Float4::standard_unit_y, -Oyster::Math::Float4(newPhysicsState.GetGravityNormal()), axis); + newPhysicsState.SetRotation(axis.xyz); + newPhysicsState.SetAngularMomentum(Float3::null); Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y); - debug += setState.GetGravityNormal(); + debug += newPhysicsState.GetGravityNormal(); } + - - this->rigidBody->SetState(this->setState); + this->rigidBody->SetState(this->newPhysicsState); } // update physic void Object::EndFrame() { - this->getState = this->rigidBody->GetState(); - this->setState = this->getState; + this->currPhysicsState = this->rigidBody->GetState(); + this->newPhysicsState = this->currPhysicsState; } void Object::setBeforeCollisonFunc(Oyster::Physics::ICustomBody::SubscriptMessage (*collisionFuncBefore)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter)) diff --git a/Code/Game/GameLogic/Object.h b/Code/Game/GameLogic/Object.h index d3a3690f..07437661 100644 --- a/Code/Game/GameLogic/Object.h +++ b/Code/Game/GameLogic/Object.h @@ -49,11 +49,12 @@ namespace GameLogic protected: Oyster::Physics::ICustomBody *rigidBody; - Oyster::Physics::ICustomBody::State setState; - Oyster::Physics::ICustomBody::State getState; + Oyster::Physics::ICustomBody::State newPhysicsState; + Oyster::Physics::ICustomBody::State currPhysicsState; static const Game* gameInstance; - + Oyster::Math::Float3 currLook; + Oyster::Math::Float3 newLook; }; } diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index ea36b284..1ab58d11 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -86,24 +86,28 @@ void Player::Move(const PLAYER_MOVEMENT &movement) void Player::MoveForward() { - setState.ApplyLinearImpulse(this->lookDir * (2000 * this->gameInstance->GetFrameTime())); + Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + newPhysicsState.ApplyLinearImpulse(forward * (2000 * this->gameInstance->GetFrameTime())); } void Player::MoveBackwards() { - setState.ApplyLinearImpulse(-this->lookDir * 2000 * this->gameInstance->GetFrameTime()); + Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + newPhysicsState.ApplyLinearImpulse(-forward * 2000 * this->gameInstance->GetFrameTime()); } void Player::MoveRight() { //Do cross product with forward vector and negative gravity vector - Oyster::Math::Float3 r = (-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)this->lookDir); - setState.ApplyLinearImpulse(r * 2000 * this->gameInstance->GetFrameTime()); + Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); + newPhysicsState.ApplyLinearImpulse(r * 2000 * this->gameInstance->GetFrameTime()); } void Player::MoveLeft() { //Do cross product with forward vector and negative gravity vector - Oyster::Math::Float3 r = -(-rigidBody->GetGravityNormal()).Cross((Oyster::Math::Float3)this->lookDir); //Still get zero - setState.ApplyLinearImpulse(-r * 2000 * this->gameInstance->GetFrameTime()); + Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); //Still get zero + newPhysicsState.ApplyLinearImpulse(-r * 2000 * this->gameInstance->GetFrameTime()); } void Player::UseWeapon(const WEAPON_FIRE &usage) @@ -119,20 +123,31 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint) this->lookDir = Oyster::Math::Float4(1,0,0); } -void Player::Rotate(const Oyster::Math3D::Float3 lookDir) +void Player::Rotate(const Oyster::Math3D::Float4 lookDir) { - this->lookDir = lookDir; - - Oyster::Math::Float4 up = -setState.GetGravityNormal(); - Oyster::Math::Float4 pos = setState.GetCenterPosition(); - Oyster::Math::Float4x4 world = Oyster::Math3D::OrientationMatrix_LookAtDirection(lookDir, up.xyz, pos.xyz); + Oyster::Math::Float dx = lookDir.w; + //deltaLook = this->lookDir - lookDir; + + //Oyster::Math::Float4 up = -setState.GetGravityNormal(); + //Oyster::Math::Float4 pos = setState.GetCenterPosition(); + //Oyster::Math::Float4x4 world = Oyster::Math3D::OrientationMatrix_LookAtDirection(lookDir, up.xyz, pos.xyz); + // cant set rotation + //setState.AddRotation(); + + Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; + Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; + //setState.SetOrientation(world); + newPhysicsState.AddRotation(deltaAxis); + //setState.SetOrientation() //this->lookDir = lookDir - up.xyz; //this->lookDir = lookDir; //this->setState.AddRotation(Oyster::Math::Float4(x, y)); //this->setState.SetRotation(); + + this->lookDir = lookDir.xyz; } void Player::Jump() @@ -155,11 +170,11 @@ bool Player::IsIdle() Oyster::Math::Float3 Player::GetPosition() const { - return (Oyster::Math::Float3)getState.GetCenterPosition(); + return (Oyster::Math::Float3)currPhysicsState.GetCenterPosition(); } Oyster::Math::Float4x4 Player::GetOrientation() const { - return this->getState.GetOrientation(); + return this->currPhysicsState.GetOrientation(); } Oyster::Math::Float3 Player::GetLookDir() const { diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index 0df0d040..0dcb6043 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -48,7 +48,7 @@ namespace GameLogic void Respawn(Oyster::Math::Float3 spawnPoint); - void Rotate(const Oyster::Math3D::Float3 lookDir); + void Rotate(const Oyster::Math3D::Float4 lookDir); /******************************************************** * Collision function for player, this is to be sent to physics through the subscribe function with the rigidbody diff --git a/Code/Game/GameProtocols/PlayerProtocols.h b/Code/Game/GameProtocols/PlayerProtocols.h index 2413aa92..216dec73 100644 --- a/Code/Game/GameProtocols/PlayerProtocols.h +++ b/Code/Game/GameProtocols/PlayerProtocols.h @@ -69,6 +69,7 @@ namespace GameLogic float lookDirX; float lookDirY; float lookDirZ; + float deltaX; Protocol_PlayerLook() { @@ -78,6 +79,7 @@ namespace GameLogic this->protocol[1].type = Oyster::Network::NetAttributeType_Float; this->protocol[2].type = Oyster::Network::NetAttributeType_Float; this->protocol[3].type = Oyster::Network::NetAttributeType_Float; + this->protocol[4].type = Oyster::Network::NetAttributeType_Float; } Protocol_PlayerLook(Oyster::Network::CustomNetProtocol& p) @@ -85,12 +87,14 @@ namespace GameLogic lookDirX = p[1].value.netFloat; lookDirY = p[2].value.netFloat; lookDirZ = p[3].value.netFloat; + deltaX = p[4].value.netFloat; } const Protocol_PlayerLook& operator=(Oyster::Network::CustomNetProtocol& val) { lookDirX = val[1].value.netFloat; lookDirY = val[2].value.netFloat; lookDirZ = val[3].value.netFloat; + deltaX = val[4].value.netFloat; return *this; } @@ -99,6 +103,8 @@ namespace GameLogic this->protocol[1].value = lookDirX; this->protocol[2].value = lookDirY; this->protocol[3].value = lookDirZ; + this->protocol[4].value = deltaX; + return &protocol; } diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index 8235c903..826cfd7c 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -172,10 +172,11 @@ namespace DanBias } void GameSession::Gameplay_PlayerLookDir ( Protocol_PlayerLook& p, DanBias::GameClient* c ) { - Oyster::Math3D::Float3 lookDir; + Oyster::Math3D::Float4 lookDir; lookDir.x = p.lookDirX; lookDir.y = p.lookDirY; lookDir.z = p.lookDirZ; + lookDir.w = p.deltaX; c->GetPlayer()->Rotate(lookDir); } void GameSession::Gameplay_PlayerChangeWeapon ( Protocol_PlayerChangeWeapon& p, DanBias::GameClient* c ) From 7f29b62c6fd4214ecfd07ebb5ef6e693cce22ca7 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Mon, 3 Feb 2014 16:19:24 +0100 Subject: [PATCH 37/74] GL - YOU CAN NOW SHOOT STUFF YAAAAY --- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 27 ++++++++++++++----- .../Implementation/GameSession_Gameplay.cpp | 4 ++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index d5de9baa..babb4916 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -39,6 +39,12 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage, ForcePush(usage,dt); break; case WEAPON_FIRE::WEAPON_USE_SECONDARY_PRESS: + + if(hasObject) + { + ForcePush(usage,dt);//WARNING THIS IS A CRAP TEST TO MAKE SURE YOU CAN SHOOT BOXES + break; + } ForcePull(usage,dt); break; case WEAPON_FIRE::WEAPON_USE_UTILLITY_PRESS: @@ -56,8 +62,9 @@ void AttatchmentMassDriver::Update(float dt) { Oyster::Physics::ICustomBody::State state; state = heldObject->GetState(); - - Oyster::Math::Float3 pos = owner->GetPosition() + owner->GetLookDir().GetNormalized(); + Oyster::Math::Float3 ownerPos = owner->GetPosition(); + ownerPos.y += 2; + Oyster::Math::Float3 pos = ownerPos + owner->GetLookDir().GetNormalized()*2; state.SetCenterPosition(pos); @@ -76,11 +83,12 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float if(hasObject) { - pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (800 * dt); + Oyster::Physics::API::Instance().ReleaseFromLimbo(heldObject); + pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (2000); Oyster::Physics::ICustomBody::State state = heldObject->GetState(); state.ApplyLinearImpulse((Oyster::Math::Float3)pushForce); heldObject->SetState(state); - Oyster::Physics::API::Instance().ReleaseFromLimbo(heldObject); + hasObject = false; heldObject = NULL; return; @@ -134,9 +142,14 @@ void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt) void AttatchmentMassDriver::PickUpObject(const WEAPON_FIRE &usage, float dt) { - Oyster::Math::Float4 pos = owner->GetPosition() + owner->GetLookDir().GetNormalized(); - Oyster::Collision3D::Sphere hitSphere = Oyster::Collision3D::Sphere(pos,1); + //Oyster::Math::Float4 pos = owner->GetPosition() + owner->GetLookDir().GetNormalized(); + //Oyster::Collision3D::Sphere hitSphere = Oyster::Collision3D::Sphere(pos,2000); + Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); - Oyster::Physics::API::Instance().ApplyEffect(hitSphere,this,AttemptPickUp); + 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(hitFrustum,this,AttemptPickUp); } diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index 8235c903..2b87e9cc 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -184,7 +184,9 @@ namespace DanBias } void GameSession::Gameplay_PlayerShot ( Protocol_PlayerShot& p, DanBias::GameClient* c ) { - c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS); + //c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS); + c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_SECONDARY_PRESS); + //c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS); } void GameSession::Gameplay_PlayerJump ( Protocol_PlayerJump& p, DanBias::GameClient* c ) { From ab962eea99671e0ca079ea286e3e6e9b94af99f1 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Mon, 3 Feb 2014 16:20:05 +0100 Subject: [PATCH 38/74] GL - added error check --- Code/Game/GameLogic/Game_PlayerData.cpp | 6 +++--- Code/Game/GameLogic/Object.cpp | 7 ++++++- Code/Game/GameLogic/Player.cpp | 18 ------------------ 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index 18d058d0..bfd352ae 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -11,18 +11,18 @@ Game::PlayerData::PlayerData() sbDesc.size = Oyster::Math::Float3(4,7,4); sbDesc.mass = 70; sbDesc.restitutionCoeff = 0.5; - sbDesc.rotation = Oyster::Math3D::RotationMatrix_AxisY(Utility::Value::Radian(180)); + sbDesc.rotation = Oyster::Math::Float3(0, Oyster::Math::pi, 0); //create rigid body Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); //create player with this rigid body this->player = new Player(rigidBody,Object::DefaultCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER); this->player->GetRigidBody()->SetCustomTag(this); - Oyster::Physics::ICustomBody::State state; + /*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(); + player->EndFrame();*/ } Game::PlayerData::PlayerData(int playerID,int teamID) { diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index 8692aa72..e04e1b8f 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -126,13 +126,18 @@ void Object::BeginFrame() if(newPhysicsState.GetGravityNormal()!= Float3::null) { Oyster::Math3D::SnapAngularAxis(Oyster::Math::Float4(newPhysicsState.GetAngularAxis(), 0), Oyster::Math::Float4::standard_unit_y, -Oyster::Math::Float4(newPhysicsState.GetGravityNormal()), axis); + if(axis !=axis) + { + //error + int i =0 ; + } newPhysicsState.SetRotation(axis.xyz); newPhysicsState.SetAngularMomentum(Float3::null); Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y); debug += newPhysicsState.GetGravityNormal(); } - + this->rigidBody->SetState(this->newPhysicsState); } // update physic diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 1ab58d11..b891ac25 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -117,7 +117,6 @@ void Player::UseWeapon(const WEAPON_FIRE &usage) void Player::Respawn(Oyster::Math::Float3 spawnPoint) { - this->life = 100; this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE; this->lookDir = Oyster::Math::Float4(1,0,0); @@ -126,26 +125,9 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint) void Player::Rotate(const Oyster::Math3D::Float4 lookDir) { Oyster::Math::Float dx = lookDir.w; - //deltaLook = this->lookDir - lookDir; - - //Oyster::Math::Float4 up = -setState.GetGravityNormal(); - //Oyster::Math::Float4 pos = setState.GetCenterPosition(); - //Oyster::Math::Float4x4 world = Oyster::Math3D::OrientationMatrix_LookAtDirection(lookDir, up.xyz, pos.xyz); - - // cant set rotation - //setState.AddRotation(); - Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; - - //setState.SetOrientation(world); newPhysicsState.AddRotation(deltaAxis); - //setState.SetOrientation() - //this->lookDir = lookDir - up.xyz; - //this->lookDir = lookDir; - - //this->setState.AddRotation(Oyster::Math::Float4(x, y)); - //this->setState.SetRotation(); this->lookDir = lookDir.xyz; } From 358cddfd9a159e41fc5a3a7e31e93bd99f39938a Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Mon, 3 Feb 2014 16:20:16 +0100 Subject: [PATCH 39/74] SnapAngularAxis fix floating point error there acos param could be slightly higher than 1. Caused it to return undefined. A clamp ought to fix it. --- Code/OysterMath/LinearMath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/OysterMath/LinearMath.h b/Code/OysterMath/LinearMath.h index ebb1e375..9b21fc02 100644 --- a/Code/OysterMath/LinearMath.h +++ b/Code/OysterMath/LinearMath.h @@ -794,7 +794,7 @@ namespace LinearAlgebra3D { ::LinearAlgebra::Vector4 worldStartNormal( WorldAxisOf(Rotation(startAngularAxis.xyz), localStartNormal.xyz), (ScalarType)0 ); targetMem = ::LinearAlgebra::Vector4( worldStartNormal.xyz.Cross(worldEndNormal.xyz), (ScalarType)0); - targetMem *= (ScalarType)::std::acos( worldStartNormal.Dot(worldEndNormal) ); + targetMem *= (ScalarType)::std::acos( ::Utility::Value::Clamp(worldStartNormal.Dot(worldEndNormal), (ScalarType)0, (ScalarType)1) ); return targetMem += startAngularAxis; } From 2c3b1e50382dd5012e8ec1eb9b449dbb1ef5f239 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Mon, 3 Feb 2014 16:20:50 +0100 Subject: [PATCH 40/74] GL - using real dmg algorithm --- Code/Game/GameLogic/CollisionManager.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index d1e9a324..5c226362 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -11,7 +11,6 @@ using namespace Oyster; using namespace GameLogic; - void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss); void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss); //Physics::ICustomBody::SubscriptMessage @@ -29,7 +28,7 @@ using namespace GameLogic; break; case OBJECT_TYPE::OBJECT_TYPE_BOX: - PlayerVBox(*player,(*(DynamicObject*) realObj), kineticEnergyLoss); + PlayerVObject(*player,*realObj, kineticEnergyLoss); //return Physics::ICustomBody::SubscriptMessage_none; break; case OBJECT_TYPE::OBJECT_TYPE_PLAYER: @@ -42,13 +41,7 @@ using namespace GameLogic; //return Physics::ICustomBody::SubscriptMessage_none; } - - void PlayerVBox(Player &player, DynamicObject &box, Oyster::Math::Float kineticEnergyLoss) - { - //use kinetic energyloss of the collision in order too determin how much damage to take - //use as part of the damage algorithm - player.DamageLife(20); - } + void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss) { From 1f28c0598396b8c757fc7b495530fd8358f4c385 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Mon, 3 Feb 2014 16:30:47 +0100 Subject: [PATCH 41/74] GL - added jump --- Code/Game/GameLogic/Player.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index bc862553..235fab13 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -146,7 +146,8 @@ void Player::Rotate(const Oyster::Math3D::Float4 lookDir) void Player::Jump() { - + Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; + newPhysicsState.ApplyLinearImpulse(up * 2000 * this->gameInstance->GetFrameTime()); } bool Player::IsWalking() From d4bd72bb4a9210dd6349e31da11a072f6a7bcd1c Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 08:55:57 +0100 Subject: [PATCH 42/74] Friction fix special case; no movement special case; movement directly into surface .. dealt with --- Code/GamePhysics/PhysicsFormula-Impl.h | 36 +++++++++++++++----------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/Code/GamePhysics/PhysicsFormula-Impl.h b/Code/GamePhysics/PhysicsFormula-Impl.h index 323fd732..189691f6 100644 --- a/Code/GamePhysics/PhysicsFormula-Impl.h +++ b/Code/GamePhysics/PhysicsFormula-Impl.h @@ -48,26 +48,32 @@ namespace Oyster { namespace Physics { namespace Formula // Relative momentum after normal impulse ::Oyster::Math::Float4 relativeMomentum = momB - momA; - ::Oyster::Math::Float4 tanFriction = relativeMomentum - relativeMomentum.Dot( iN )*iN; - tanFriction.Normalize(); + ::Oyster::Math::Float4 tanFriction = relativeMomentum - relativeMomentum.Dot( iN ) * iN; - ::Oyster::Math::Float magnitudeFriction = -relativeMomentum.Dot( tanFriction ); - magnitudeFriction = magnitudeFriction*mA*mB/( mA + mB ); + if( tanFriction.Dot(tanFriction) > 0.0f ) + { // no friction if moving directly into surface, or not at all. + tanFriction.Normalize(); - ::Oyster::Math::Float mu = 0.5f*( sFA + sFB ); + ::Oyster::Math::Float magnitudeFriction = -relativeMomentum.Dot( tanFriction ); + magnitudeFriction = magnitudeFriction * mA * mB / ( mA + mB ); + + ::Oyster::Math::Float mu = 0.5f * ( sFA + sFB ); - ::Oyster::Math::Float4 frictionImpulse; - if( abs(magnitudeFriction) < i*mu ) - { - frictionImpulse = magnitudeFriction*tanFriction; + ::Oyster::Math::Float4 frictionImpulse; + if( abs(magnitudeFriction) < i * mu ) + { + frictionImpulse = magnitudeFriction * tanFriction; + } + else + { + ::Oyster::Math::Float dynamicFriction = 0.5f * ( dFA + dFB ); + frictionImpulse = ( -i * dynamicFriction ) * tanFriction; + } + + return ( 1 / mA ) * frictionImpulse; } else - { - ::Oyster::Math::Float dynamicFriction = 0.5f*( dFA + dFB ); - frictionImpulse = -i*tanFriction*dynamicFriction; - } - - return ( 1 / mA )*frictionImpulse; + return ::Oyster::Math::Float4::null; } } From 9817f844efe289201ffb8772ea66f788e4e59596 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 10:23:14 +0100 Subject: [PATCH 43/74] Rebound adjustment trial Rebound had a strong friction-like effect. Testing to see if it works better if applied before the leapfrog update --- Code/GamePhysics/Implementation/SimpleRigidBody.cpp | 6 +++--- Code/GamePhysics/Implementation/SphericalRigidBody.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index d1be7d61..46abac8f 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -333,23 +333,23 @@ UpdateState SimpleRigidBody::Update( Float timeStepLength ) // this->isForwarded = false; //} - this->rigid.Update_LeapFrog( timeStepLength ); - { // Rebound if needed if( this->collisionRebound.timeOfContact < 1.0f ) { this->rigid.centerPos = Lerp( this->collisionRebound.previousSpatial.center, this->rigid.centerPos, this->collisionRebound.timeOfContact ); this->rigid.SetRotation( Lerp(this->collisionRebound.previousSpatial.axis, this->rigid.axis, this->collisionRebound.timeOfContact) ); this->rigid.boundingReach = Lerp( this->collisionRebound.previousSpatial.reach, this->rigid.boundingReach, this->collisionRebound.timeOfContact ); + this->collisionRebound.timeOfContact = 1.0f; } // Update rebound data 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->rigid.Update_LeapFrog( timeStepLength ); + { // Maintain rotation resolution by keeping axis within [0, 2pi] (trigonometric methods gets faster too) Float3 n; ::std::modf( this->rigid.axis * (0.5f / pi), n ); diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index 49aed408..a3eecae2 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -254,23 +254,23 @@ UpdateState SphericalRigidBody::Update( Float timeStepLength ) // this->isForwarded = false; //} - this->rigid.Update_LeapFrog( timeStepLength ); - { // Rebound if needed if( this->collisionRebound.timeOfContact < 1.0f ) { this->rigid.centerPos = Lerp( this->collisionRebound.previousSpatial.center, this->rigid.centerPos, this->collisionRebound.timeOfContact ); this->rigid.SetRotation( Lerp(this->collisionRebound.previousSpatial.axis, this->rigid.axis, this->collisionRebound.timeOfContact) ); this->rigid.boundingReach = Lerp( this->collisionRebound.previousSpatial.reach, this->rigid.boundingReach, this->collisionRebound.timeOfContact ); + this->collisionRebound.timeOfContact = 1.0f; } // Update rebound data 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->rigid.Update_LeapFrog( timeStepLength ); + { // Maintain rotation resolution by keeping axis within [0, 2pi] (trigonometric methods gets faster too) Float3 n; ::std::modf( this->rigid.axis * (0.5f / pi), n ); From fcadd5b4c30cc698b6c2bcdb1298649fe435101a Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Tue, 4 Feb 2014 10:29:02 +0100 Subject: [PATCH 44/74] GL - testing physics --- Code/Game/DanBiasGame/DanBiasGame_Impl.cpp | 6 ++-- .../DanBiasGame/GameClientState/GameState.cpp | 6 ++-- Code/Game/GameLogic/Level.cpp | 5 ++-- Code/Game/GameLogic/Object.cpp | 8 +++--- Code/Game/GameLogic/Player.cpp | 28 +++++++++++-------- .../Implementation/GameSession_Gameplay.cpp | 2 +- Code/OysterPhysics3D/RigidBody.cpp | 4 +-- 7 files changed, 34 insertions(+), 25 deletions(-) diff --git a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp index d0a435b2..83e48713 100644 --- a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp +++ b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp @@ -85,6 +85,9 @@ namespace DanBias float dt = (float)m_data->timer.getElapsedSeconds(); m_data->timer.reset(); + if(m_data->recieverObj->IsConnected()) + m_data->recieverObj->Update(); + capFrame += dt; if(capFrame > 0.03) { @@ -130,8 +133,7 @@ namespace DanBias HRESULT DanBiasGame::Update(float deltaTime) { - if(m_data->recieverObj->IsConnected()) - m_data->recieverObj->Update(); + m_data->inputObj->Update(); diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index 638d954d..b1bc4881 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -378,7 +378,7 @@ void GameState::Protocol( ObjPos* pos ) { world[i] = pos->worldPos[i]; } - + //printf("pos for obj %d, ",pos->object_ID ); for (unsigned int i = 0; i < privData->object.size(); i++) { if(privData->object[i]->GetId() == pos->object_ID) @@ -389,10 +389,10 @@ void GameState::Protocol( ObjPos* pos ) //camera->setLook((Oyster::Math::Float3(world[8], world[9], world[10]))); if(i == myId) // playerobj { - Oyster::Math::Float3 up = (Oyster::Math::Float3(world[4], world[5]+2, world[6])); + Oyster::Math::Float3 up = (Oyster::Math::Float3(world[4], world[5], world[6])); Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13]+2, world[14]); Oyster::Math::Float3 cameraPos = up + pos; - camera->SetPosition(pos); + camera->SetPosition(cameraPos); camera->UpdateViewMatrix(); } } diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index b070eb56..858818f6 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -27,7 +27,8 @@ void Level::InitiateLevel(float radius) sbDesc.ignoreGravity = true; sbDesc.radius = 300; sbDesc.mass = 10e12f; - + sbDesc.frictionCoeff_Static = 0; + sbDesc.frictionCoeff_Dynamic = 0; ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release(); ICustomBody::State state; @@ -61,7 +62,7 @@ void Level::InitiateLevel(float radius) // add gravitation API::Gravity gravityWell; gravityWell.gravityType = API::Gravity::GravityType_Well; - gravityWell.well.mass = 1e15f; + gravityWell.well.mass = 1e18f; gravityWell.well.position = Oyster::Math::Float4(0,0,0,1); API::Instance().AddGravity(gravityWell); } diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index e04e1b8f..b55ed661 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -118,9 +118,9 @@ Oyster::Physics::ICustomBody* Object::GetRigidBody() void Object::BeginFrame() { - - this->rigidBody->SetState(this->newPhysicsState); - this->rigidBody->GetState(this->newPhysicsState); + //newPhysicsState.SetAngularMomentum(Float3::null); + //this->rigidBody->SetState(this->newPhysicsState); + //this->rigidBody->GetState(this->newPhysicsState); Oyster::Math::Float4 axis; if(newPhysicsState.GetGravityNormal()!= Float3::null) @@ -131,7 +131,7 @@ void Object::BeginFrame() //error int i =0 ; } - newPhysicsState.SetRotation(axis.xyz); + //newPhysicsState.SetRotation(axis.xyz); newPhysicsState.SetAngularMomentum(Float3::null); Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y); debug += newPhysicsState.GetGravityNormal(); diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 235fab13..f205a516 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -98,28 +98,32 @@ void Player::Move(const PLAYER_MOVEMENT &movement) void Player::MoveForward() { - Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; - newPhysicsState.ApplyLinearImpulse(forward * (2000 * this->gameInstance->GetFrameTime())); + //Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + Oyster::Math::Float3 forward = lookDir; + newPhysicsState.ApplyLinearImpulse(forward * (30000 * this->gameInstance->GetFrameTime())); } void Player::MoveBackwards() { - Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; - newPhysicsState.ApplyLinearImpulse(-forward * 2000 * this->gameInstance->GetFrameTime()); + //Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + Oyster::Math::Float3 forward = lookDir; + newPhysicsState.ApplyLinearImpulse(-forward * 30000 * this->gameInstance->GetFrameTime()); } void Player::MoveRight() { //Do cross product with forward vector and negative gravity vector - Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + //Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + Oyster::Math::Float3 forward = lookDir; Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); - newPhysicsState.ApplyLinearImpulse(r * 2000 * this->gameInstance->GetFrameTime()); + newPhysicsState.ApplyLinearImpulse(-r * 30000 * this->gameInstance->GetFrameTime()); } void Player::MoveLeft() { //Do cross product with forward vector and negative gravity vector - Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + //Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + Oyster::Math::Float3 forward = lookDir; Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); //Still get zero - newPhysicsState.ApplyLinearImpulse(-r * 2000 * this->gameInstance->GetFrameTime()); + newPhysicsState.ApplyLinearImpulse(r * 30000 * this->gameInstance->GetFrameTime()); } void Player::UseWeapon(const WEAPON_FIRE &usage) @@ -138,8 +142,10 @@ void Player::Rotate(const Oyster::Math3D::Float4 lookDir) { Oyster::Math::Float dx = lookDir.w; Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; - Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; - newPhysicsState.AddRotation(deltaAxis); + Oyster::Math::Float3 deltaAxis = up * (-dx * 0.2) ; + Oyster::Math::Float3 oldOrt = currPhysicsState.GetRotation(); + + //newPhysicsState.SetRotation(oldOrt + deltaAxis); this->lookDir = lookDir.xyz; } @@ -147,7 +153,7 @@ void Player::Rotate(const Oyster::Math3D::Float4 lookDir) void Player::Jump() { Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; - newPhysicsState.ApplyLinearImpulse(up * 2000 * this->gameInstance->GetFrameTime()); + newPhysicsState.ApplyLinearImpulse(up * 30000 * this->gameInstance->GetFrameTime()); } bool Player::IsWalking() diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index 4325f955..73ccba1a 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -106,7 +106,7 @@ namespace DanBias Oyster::Math::Float4x4 world =obj->GetOrientation(); Protocol_ObjectPosition p(world, id); - GameSession::gameSession->Send(*p.GetProtocol()); + //GameSession::gameSession->Send(*p.GetProtocol()); } } diff --git a/Code/OysterPhysics3D/RigidBody.cpp b/Code/OysterPhysics3D/RigidBody.cpp index 68f435e9..ca6dcdec 100644 --- a/Code/OysterPhysics3D/RigidBody.cpp +++ b/Code/OysterPhysics3D/RigidBody.cpp @@ -51,8 +51,8 @@ void RigidBody::Update_LeapFrog( Float updateFrameLength ) // 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.99f; - this->momentum_Angular = this->momentum_Angular*0.99f; + 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 this->centerPos += ( updateFrameLength / this->mass ) * AverageWithDelta( this->momentum_Linear, this->impulse_Linear ); From 42cb1dab1dc935206bb62d36ed54db7417b8be2a Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 10:32:43 +0100 Subject: [PATCH 45/74] API::SimpleBodyDescription API::SphericalBodyDescription fix 3 coeffs were not saved in factory constructor --- Code/GamePhysics/Implementation/SimpleRigidBody.cpp | 9 ++++++--- .../Implementation/SphericalRigidBody.cpp | 13 ++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index 46abac8f..9c66e736 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -64,12 +64,15 @@ SimpleRigidBody::SimpleRigidBody( const API::SimpleBodyDescription &desc ) { 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.restitutionCoeff = desc.restitutionCoeff; + this->rigid.frictionCoeff_Static = desc.frictionCoeff_Static; + this->rigid.frictionCoeff_Kinetic = desc.frictionCoeff_Dynamic; this->rigid.SetMass_KeepMomentum( desc.mass ); this->rigid.SetMomentOfInertia_KeepMomentum( desc.inertiaTensor ); - this->deltaPos = Float4::null; - this->deltaAxis = Float4::null; + this->deltaPos = Float4::null; + this->deltaAxis = Float4::null; this->gravityNormal = Float3::null; diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index a3eecae2..448dbb4f 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -29,14 +29,17 @@ SphericalRigidBody::SphericalRigidBody() SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc ) { - this->rigid = RigidBody(); + this->rigid = RigidBody(); this->rigid.SetRotation( desc.rotation ); - this->rigid.centerPos = desc.centerPosition; - this->rigid.boundingReach = Float4( desc.radius, desc.radius, desc.radius, 0.0f ); + this->rigid.centerPos = desc.centerPosition; + this->rigid.boundingReach = Float4( desc.radius, desc.radius, desc.radius, 0.0f ); + this->rigid.restitutionCoeff = desc.restitutionCoeff; + this->rigid.frictionCoeff_Static = desc.frictionCoeff_Static; + this->rigid.frictionCoeff_Kinetic = desc.frictionCoeff_Dynamic; this->rigid.SetMass_KeepMomentum( desc.mass ); this->rigid.SetMomentOfInertia_KeepMomentum( MomentOfInertia::Sphere(desc.mass, desc.radius) ); - this->deltaPos = Float4::null; - this->deltaAxis = Float4::null; + this->deltaPos = Float4::null; + this->deltaAxis = Float4::null; this->gravityNormal = Float3::null; From 00400a7d32bdb789761112f71b3654c94699e39b Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Tue, 4 Feb 2014 10:38:59 +0100 Subject: [PATCH 46/74] GL - camera testing --- Code/Game/DanBiasGame/GameClientState/GameState.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index b1bc4881..e57d004d 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -389,10 +389,12 @@ void GameState::Protocol( ObjPos* pos ) //camera->setLook((Oyster::Math::Float3(world[8], world[9], world[10]))); if(i == myId) // playerobj { - Oyster::Math::Float3 up = (Oyster::Math::Float3(world[4], world[5], world[6])); - Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13]+2, world[14]); - Oyster::Math::Float3 cameraPos = up + pos; - camera->SetPosition(cameraPos); + camera->setRight((Oyster::Math::Float3(world[0], world[1], world[2]))); + camera->setUp(Oyster::Math::Float3(world[4], world[5], world[6])); + //camera->setLook((Oyster::Math::Float3(world[8], world[9], world[10]))); + Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13]+2, world[14]+2); + //Oyster::Math::Float3 cameraPos = up + pos; + camera->SetPosition(pos); camera->UpdateViewMatrix(); } } From 3bf9f59f5a752311104a1c53c768b63457910661 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Tue, 4 Feb 2014 11:13:02 +0100 Subject: [PATCH 47/74] GL - Player dies and respawns --- Code/Game/GameLogic/CollisionManager.cpp | 2 +- Code/Game/GameLogic/Player.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 5c226362..37916799 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -35,7 +35,7 @@ using namespace GameLogic; //return Physics::ICustomBody::SubscriptMessage_none; break; case OBJECT_TYPE::OBJECT_TYPE_WORLD: - int test = 5; + PlayerVObject(*player,*realObj, kineticEnergyLoss); break; } diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 235fab13..81c1b6d8 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -61,6 +61,7 @@ Player::~Player(void) void Player::BeginFrame() { weapon->Update(0.002f); + if(playerState == PLAYER_STATE_DEAD) Respawn(Oyster::Math::Float3(0,308,0)); Object::BeginFrame(); } @@ -132,6 +133,7 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint) this->life = 100; this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE; this->lookDir = Oyster::Math::Float4(1,0,0); + this->setState.SetCenterPosition(spawnPoint); } void Player::Rotate(const Oyster::Math3D::Float4 lookDir) @@ -187,5 +189,13 @@ PLAYER_STATE Player::GetState() const void Player::DamageLife(int damage) { this->life -= damage; + this->life = 0; + + if(this->life <= 0) + { + this->life = 0; + playerState = PLAYER_STATE_DEAD; + //do stuff that makes you dead + } } From 1261ed734fd4547f614e6ffca42a0d22586311cc Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Tue, 4 Feb 2014 11:36:10 +0100 Subject: [PATCH 48/74] GL - Updated level loader. --- .../GameLogic/LevelLoader/LevelParser.cpp | 50 +++++++++++++++---- .../GameLogic/LevelLoader/ObjectDefines.h | 16 +++--- .../GameLogic/LevelLoader/ParseFunctions.cpp | 30 ++++++++++- .../GameLogic/LevelLoader/ParseFunctions.h | 1 + 4 files changed, 78 insertions(+), 19 deletions(-) diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp index 3a20f192..088c3916 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp @@ -30,13 +30,14 @@ std::vector> LevelParser::Parse(std::string filen //Read format version FormatVersion levelFormatVersion; - //ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion)); + ParseObject(&buffer[counter], &levelFormatVersion, sizeof(levelFormatVersion)); + counter += sizeof(levelFormatVersion); if(this->formatVersion != levelFormatVersion) { //Do something if it's not the same version } - while(counter < bufferSize) + while(counter < bufferSize) { //Get typeID ObjectTypeHeader typeID; @@ -55,9 +56,8 @@ std::vector> LevelParser::Parse(std::string filen case ObjectType_Static: case ObjectType_Dynamic: { ObjectHeader* header = new ObjectHeader; - ParseObject(&buffer[counter], header, sizeof(*header)); + ParseObject(&buffer[counter], *header, counter); objects.push_back(header); - counter += sizeof(*header); break; } @@ -124,7 +124,8 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) //Read format version FormatVersion levelFormatVersion; - //ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion)); + ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion)); + counter += sizeof(levelFormatVersion); if(this->formatVersion != levelFormatVersion) { //Do something if it's not the same version @@ -142,11 +143,42 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) ParseLevelMetaData(&buffer[counter], levelHeader, counter); return levelHeader; break; - case ObjectType_Dynamic: - //Do not call parse this object, since we are only interested in the LevelMetaData - //Only increase the counter size - counter += sizeof(ObjectHeader); + + //This is by design, static and dynamic is using the same converter. Do not add anything inbetween them. + case ObjectType_Static: case ObjectType_Dynamic: + { + ObjectHeader header; + ParseObject(&buffer[counter], header, counter); break; + } + + case ObjectType_Light: + { + LightType lightType; + ParseObject(&buffer[counter+4], &lightType, sizeof(lightType)); + + switch(lightType) + { + case LightType_PointLight: + { + counter += sizeof(PointLight); + break; + } + case LightType_DirectionalLight: + { + counter += sizeof(DirectionalLight); + break; + } + case LightType_SpotLight: + { + counter += sizeof(SpotLight); + break; + } + default: + //Undefined LightType. + break; + } + } default: //Couldn't find typeID. FAIL!!!!!! diff --git a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h index 21e3a7e3..553db824 100644 --- a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h +++ b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h @@ -28,6 +28,7 @@ namespace GameLogic UsePhysics_UseFullPhysics, UsePhysics_IgnoreGravity, UsePhysics_IgnorePhysics, + UsePhysics_IgnoreCollision, UsePhysics_Count, UsePhysics_Unknown = -1 @@ -82,12 +83,13 @@ namespace GameLogic struct PhysicsObject { + UsePhysics usePhysics; float mass; - float elasticity; + float inertiaMagnitude[3]; + float inertiaRotation[3]; float frictionCoeffStatic; float frictionCoeffDynamic; - float inertiaTensor[16]; - UsePhysics usePhysics; + }; struct LevelMetaData : ObjectTypeHeader @@ -97,17 +99,15 @@ namespace GameLogic std::string levelDescription; std::string levelAuthor; int maxNumberOfPlayer; - float worldSize; - int overviewPictureID; + int worldSize; + std::string overviewPicturePath; std::vector gameModesSupported; }; struct ObjectHeader : public ObjectTypeHeader { //Model, - int ModelID; - //Texture - int TextureID; + std::string ModelFile; //Position float position[3]; //Rotation diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp index f456b2d7..8d51f308 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp @@ -20,11 +20,33 @@ namespace GameLogic memcpy(header, buffer, size); } + void ParseObject(char* buffer, ObjectHeader& header, int& size) + { + char tempName[128]; + int tempSize = 0; + int start = 0; + + memcpy(&header.typeID, &buffer[start], 4); + start += 4; + + memcpy(&tempSize, &buffer[start], 4); + start += 4; + + memcpy(&tempName, &buffer[start], tempSize); + header.ModelFile.assign(&tempName[0], &tempName[tempSize]); + start += tempSize; + + memcpy(&header.position, &buffer[start], 36); + start += 36; + + size += start; + } + void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size) { int start = 0; int tempSize; - char tempName[100]; + char tempName[128]; memcpy(&header.typeID, &buffer[start], 4); start += 4; @@ -59,9 +81,13 @@ namespace GameLogic memcpy(&header.worldSize, &buffer[start], 4); start += 4; - memcpy(&header.overviewPictureID, &buffer[start], 4); + memcpy(&tempSize, &buffer[start], 4); start += 4; + memcpy(&tempName, &buffer[start], tempSize); + header.overviewPicturePath.assign(&tempName[0], &tempName[tempSize]); + start += tempSize; + memcpy(&tempSize, &buffer[start], 4); start += 4; diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.h b/Code/Game/GameLogic/LevelLoader/ParseFunctions.h index 554b95db..f68a9289 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.h +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.h @@ -19,6 +19,7 @@ namespace GameLogic */ void ParseObject(char* buffer, void *header, int size); + void ParseObject(char* buffer, ObjectHeader& header, int& size); void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size); } } From e39eb5fb4b91dd9380e698535d37b8a6ebcc3044 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 11:48:50 +0100 Subject: [PATCH 49/74] RigidBody update adjusted Spherical and Simple --- .../Implementation/SimpleRigidBody.cpp | 52 ++++++++----------- .../Implementation/SphericalRigidBody.cpp | 51 ++++++++---------- 2 files changed, 46 insertions(+), 57 deletions(-) diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index 9c66e736..034cedea 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -325,41 +325,30 @@ void * SimpleRigidBody::GetCustomTag() const // return this->rigid.GetLinearVelocity(); //} - UpdateState SimpleRigidBody::Update( Float timeStepLength ) { - //if( this->isForwarded ) - //{ - // this->rigid.Move( this->deltaPos.xyz, this->deltaAxis.xyz ); - // this->deltaPos = Float4::null; - // this->deltaAxis = Float4::null; - // this->isForwarded = false; - //} - + if( this->collisionRebound.timeOfContact < 1.0f ) { // Rebound if needed - if( this->collisionRebound.timeOfContact < 1.0f ) - { - this->rigid.centerPos = Lerp( this->collisionRebound.previousSpatial.center, this->rigid.centerPos, this->collisionRebound.timeOfContact ); - this->rigid.SetRotation( Lerp(this->collisionRebound.previousSpatial.axis, this->rigid.axis, this->collisionRebound.timeOfContact) ); - this->rigid.boundingReach = Lerp( this->collisionRebound.previousSpatial.reach, this->rigid.boundingReach, this->collisionRebound.timeOfContact ); - this->collisionRebound.timeOfContact = 1.0f; - } - - // Update rebound data - this->collisionRebound.previousSpatial.center = this->rigid.centerPos; - this->collisionRebound.previousSpatial.axis = this->rigid.axis; - this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach; + this->rigid.centerPos = Lerp( this->collisionRebound.previousSpatial.center, this->rigid.centerPos, this->collisionRebound.timeOfContact ); + this->rigid.SetRotation( Lerp(this->collisionRebound.previousSpatial.axis, this->rigid.axis, this->collisionRebound.timeOfContact) ); + this->rigid.boundingReach = Lerp( this->collisionRebound.previousSpatial.reach, this->rigid.boundingReach, this->collisionRebound.timeOfContact ); + this->collisionRebound.timeOfContact = 1.0f; } - this->rigid.Update_LeapFrog( timeStepLength ); + // 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; - { // Maintain rotation resolution by keeping axis within [0, 2pi] (trigonometric methods gets faster too) - Float3 n; - ::std::modf( this->rigid.axis * (0.5f / pi), n ); - this->rigid.axis -= (2.0f * pi) * n; - } + // 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 + // 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) ) + { unsigned char resting = 0; if( this->rigid.momentum_Linear.Dot(this->rigid.momentum_Linear) <= (Constant::epsilon * Constant::epsilon) ) { @@ -371,9 +360,14 @@ UpdateState SimpleRigidBody::Update( Float timeStepLength ) this->rigid.momentum_Angular = Float3::null; ++resting; } - if( resting == 2 ) return UpdateState_resting; + if( resting == 2 ) + { + this->rigid.impulse_Linear = this->rigid.impulse_Angular = Float3::null; + return UpdateState_resting; + } } + this->rigid.Update_LeapFrog( timeStepLength ); return UpdateState_altered; } diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index 448dbb4f..6b4cd4ed 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -249,38 +249,28 @@ void * SphericalRigidBody::GetCustomTag() const UpdateState SphericalRigidBody::Update( Float timeStepLength ) { - //if( this->isForwarded ) - //{ - // this->rigid.Move( this->deltaPos.xyz, this->deltaAxis.xyz ); - // this->deltaPos = Float4::null; - // this->deltaAxis = Float4::null; - // this->isForwarded = false; - //} - + if( this->collisionRebound.timeOfContact < 1.0f ) { // Rebound if needed - if( this->collisionRebound.timeOfContact < 1.0f ) - { - this->rigid.centerPos = Lerp( this->collisionRebound.previousSpatial.center, this->rigid.centerPos, this->collisionRebound.timeOfContact ); - this->rigid.SetRotation( Lerp(this->collisionRebound.previousSpatial.axis, this->rigid.axis, this->collisionRebound.timeOfContact) ); - this->rigid.boundingReach = Lerp( this->collisionRebound.previousSpatial.reach, this->rigid.boundingReach, this->collisionRebound.timeOfContact ); - this->collisionRebound.timeOfContact = 1.0f; - } - - // Update rebound data - this->collisionRebound.previousSpatial.center = this->rigid.centerPos; - this->collisionRebound.previousSpatial.axis = this->rigid.axis; - this->collisionRebound.previousSpatial.reach = this->rigid.boundingReach; + this->rigid.centerPos = Lerp( this->collisionRebound.previousSpatial.center, this->rigid.centerPos, this->collisionRebound.timeOfContact ); + this->rigid.SetRotation( Lerp(this->collisionRebound.previousSpatial.axis, this->rigid.axis, this->collisionRebound.timeOfContact) ); + this->rigid.boundingReach = Lerp( this->collisionRebound.previousSpatial.reach, this->rigid.boundingReach, this->collisionRebound.timeOfContact ); + this->collisionRebound.timeOfContact = 1.0f; } - this->rigid.Update_LeapFrog( timeStepLength ); + // 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; - { // Maintain rotation resolution by keeping axis within [0, 2pi] (trigonometric methods gets faster too) - Float3 n; - ::std::modf( this->rigid.axis * (0.5f / pi), n ); - this->rigid.axis -= (2.0f * pi) * n; - } + // 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 + // 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) ) + { unsigned char resting = 0; if( this->rigid.momentum_Linear.Dot(this->rigid.momentum_Linear) <= (Constant::epsilon * Constant::epsilon) ) { @@ -292,9 +282,14 @@ UpdateState SphericalRigidBody::Update( Float timeStepLength ) this->rigid.momentum_Angular = Float3::null; ++resting; } - if( resting == 2 ) return UpdateState_resting; + if( resting == 2 ) + { + this->rigid.impulse_Linear = this->rigid.impulse_Angular = Float3::null; + return UpdateState_resting; + } } + this->rigid.Update_LeapFrog( timeStepLength ); return UpdateState_altered; } From d54cffee8e0c785daedb0bc6457f71e52db5a3b4 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Tue, 4 Feb 2014 11:50:15 +0100 Subject: [PATCH 50/74] GL - camera follows player --- .../DanBiasGame/GameClientState/GameState.cpp | 24 +++++++++---- .../DanBiasGame/GameClientState/GameState.h | 1 + Code/Game/GameLogic/Object.cpp | 34 +++++++++---------- Code/Game/GameLogic/Player.cpp | 24 +++++++------ 4 files changed, 50 insertions(+), 33 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index e57d004d..3e058619 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -43,7 +43,7 @@ bool GameState::Init(Oyster::Network::NetworkClient* nwClient) privData->state = gameStateState_loading; privData->nwClient = nwClient; privData->state = LoadGame(); - + pitch = 0; return true; } GameState::gameStateState GameState::LoadGame() @@ -309,7 +309,8 @@ void GameState::readKeyInput(InputClass* KeyInput) if (KeyInput->IsMousePressed()) { camera->Yaw(-KeyInput->GetYaw()); - camera->Pitch(KeyInput->GetPitch()); + //camera->Pitch(KeyInput->GetPitch()); + //pitch = KeyInput->GetPitch(); camera->UpdateViewMatrix(); GameLogic::Protocol_PlayerLook playerLookDir; Oyster::Math::Float4 look = camera->GetLook(); @@ -391,10 +392,21 @@ void GameState::Protocol( ObjPos* pos ) { camera->setRight((Oyster::Math::Float3(world[0], world[1], world[2]))); camera->setUp(Oyster::Math::Float3(world[4], world[5], world[6])); - //camera->setLook((Oyster::Math::Float3(world[8], world[9], world[10]))); - Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13]+2, world[14]+2); - //Oyster::Math::Float3 cameraPos = up + pos; - camera->SetPosition(pos); + Oyster::Math::Float3 cameraLook = camera->GetLook(); + Oyster::Math::Float3 objForward = (Oyster::Math::Float3(world[8], world[9], world[10])); + + camera->setLook(objForward); + camera->UpdateViewMatrix(); + Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13], world[14]); + Oyster::Math::Float3 up = Oyster::Math::Float3(world[4], world[5], world[6]); + + up *= 2; + objForward *= -3; + Oyster::Math::Float3 cameraPos = up + pos + objForward; + //camera->Pitch(pitch); + camera->SetPosition(cameraPos); + //camera->LookAt(pos, dir, up); + //Oyster::Math::Float3 newLook = objForward; camera->UpdateViewMatrix(); } } diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.h b/Code/Game/DanBiasGame/GameClientState/GameState.h index 04d5b791..d555134c 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.h +++ b/Code/Game/DanBiasGame/GameClientState/GameState.h @@ -27,6 +27,7 @@ private: Camera* camera; int myId; + float pitch; struct myData; myData* privData; public: diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index b55ed661..a000eaed 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -118,24 +118,9 @@ Oyster::Physics::ICustomBody* Object::GetRigidBody() void Object::BeginFrame() { - //newPhysicsState.SetAngularMomentum(Float3::null); - //this->rigidBody->SetState(this->newPhysicsState); - //this->rigidBody->GetState(this->newPhysicsState); - Oyster::Math::Float4 axis; - if(newPhysicsState.GetGravityNormal()!= Float3::null) - { - Oyster::Math3D::SnapAngularAxis(Oyster::Math::Float4(newPhysicsState.GetAngularAxis(), 0), Oyster::Math::Float4::standard_unit_y, -Oyster::Math::Float4(newPhysicsState.GetGravityNormal()), axis); - if(axis !=axis) - { - //error - int i =0 ; - } - //newPhysicsState.SetRotation(axis.xyz); - newPhysicsState.SetAngularMomentum(Float3::null); - Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y); - debug += newPhysicsState.GetGravityNormal(); - } + + this->rigidBody->SetState(this->newPhysicsState); @@ -144,6 +129,21 @@ void Object::BeginFrame() void Object::EndFrame() { this->currPhysicsState = this->rigidBody->GetState(); + + if(currPhysicsState.GetGravityNormal()!= Float3::null) + { + Oyster::Math::Float4 axis; + Oyster::Math3D::SnapAngularAxis(Oyster::Math::Float4(currPhysicsState.GetAngularAxis(), 0), Oyster::Math::Float4::standard_unit_y, -Oyster::Math::Float4(currPhysicsState.GetGravityNormal()), axis); + if(axis !=axis) + { + //error + int i =0 ; + } + currPhysicsState.SetRotation(axis.xyz); + currPhysicsState.SetAngularMomentum(Float3::null); + Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y); + debug += currPhysicsState.GetGravityNormal(); + } this->newPhysicsState = this->currPhysicsState; } diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index f205a516..2ca1cc2d 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -98,21 +98,21 @@ void Player::Move(const PLAYER_MOVEMENT &movement) void Player::MoveForward() { - //Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; - Oyster::Math::Float3 forward = lookDir; + Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + //Oyster::Math::Float3 forward = lookDir; newPhysicsState.ApplyLinearImpulse(forward * (30000 * this->gameInstance->GetFrameTime())); } void Player::MoveBackwards() { - //Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; - Oyster::Math::Float3 forward = lookDir; + Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + //Oyster::Math::Float3 forward = lookDir; newPhysicsState.ApplyLinearImpulse(-forward * 30000 * this->gameInstance->GetFrameTime()); } void Player::MoveRight() { //Do cross product with forward vector and negative gravity vector - //Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; - Oyster::Math::Float3 forward = lookDir; + Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + //Oyster::Math::Float3 forward = lookDir; Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); newPhysicsState.ApplyLinearImpulse(-r * 30000 * this->gameInstance->GetFrameTime()); @@ -120,8 +120,8 @@ void Player::MoveRight() void Player::MoveLeft() { //Do cross product with forward vector and negative gravity vector - //Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; - Oyster::Math::Float3 forward = lookDir; + Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; + //Oyster::Math::Float3 forward = lookDir; Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); //Still get zero newPhysicsState.ApplyLinearImpulse(r * 30000 * this->gameInstance->GetFrameTime()); } @@ -141,11 +141,15 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint) void Player::Rotate(const Oyster::Math3D::Float4 lookDir) { Oyster::Math::Float dx = lookDir.w; + if(dx > 0.0f) + { + int i =0 ; + } Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; - Oyster::Math::Float3 deltaAxis = up * (-dx * 0.2) ; + Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; Oyster::Math::Float3 oldOrt = currPhysicsState.GetRotation(); - //newPhysicsState.SetRotation(oldOrt + deltaAxis); + newPhysicsState.SetRotation(oldOrt + deltaAxis); this->lookDir = lookDir.xyz; } From e859df65d39136a6abe507a0722a17c11857983d Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Tue, 4 Feb 2014 11:51:31 +0100 Subject: [PATCH 51/74] GL - compiles --- Code/Game/GameLogic/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 81c1b6d8..5b18dabf 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -133,7 +133,7 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint) this->life = 100; this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE; this->lookDir = Oyster::Math::Float4(1,0,0); - this->setState.SetCenterPosition(spawnPoint); + this->newPhysicsState.SetCenterPosition(spawnPoint); } void Player::Rotate(const Oyster::Math3D::Float4 lookDir) From f88e16c5810838e76078ec16b109fdd4d9a1eecf Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Tue, 4 Feb 2014 11:53:40 +0100 Subject: [PATCH 52/74] GL - merge --- Code/Game/GameLogic/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 6d6d8bf7..ccd3e8f4 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -137,7 +137,7 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint) this->life = 100; this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE; this->lookDir = Oyster::Math::Float4(1,0,0); - this->setState.SetCenterPosition(spawnPoint); + this->newPhysicsState.SetCenterPosition(spawnPoint); } void Player::Rotate(const Oyster::Math3D::Float4 lookDir) From 54deef7f2b6092b77096936de8ecdeeafea27ccf Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 12:16:06 +0100 Subject: [PATCH 53/74] Project file fixes for GL --- Code/Game/DanBiasLauncher/DanBiasLauncher.vcxproj | 5 +++++ Code/Game/GameLogic/Player.cpp | 2 +- Code/Game/GameServer/GameServer.vcxproj | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Code/Game/DanBiasLauncher/DanBiasLauncher.vcxproj b/Code/Game/DanBiasLauncher/DanBiasLauncher.vcxproj index 5e543af9..fec9d7dd 100644 --- a/Code/Game/DanBiasLauncher/DanBiasLauncher.vcxproj +++ b/Code/Game/DanBiasLauncher/DanBiasLauncher.vcxproj @@ -173,6 +173,11 @@ + + + {2a1bc987-af42-4500-802d-89cd32fc1309} + + diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index ccd3e8f4..6d6d8bf7 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -137,7 +137,7 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint) this->life = 100; this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE; this->lookDir = Oyster::Math::Float4(1,0,0); - this->newPhysicsState.SetCenterPosition(spawnPoint); + this->setState.SetCenterPosition(spawnPoint); } void Player::Rotate(const Oyster::Math3D::Float4 lookDir) diff --git a/Code/Game/GameServer/GameServer.vcxproj b/Code/Game/GameServer/GameServer.vcxproj index 6c0f3ea9..23bf0eb0 100644 --- a/Code/Game/GameServer/GameServer.vcxproj +++ b/Code/Game/GameServer/GameServer.vcxproj @@ -200,6 +200,9 @@ {f10cbc03-9809-4cba-95d8-327c287b18ee} + + {b1195bb9-b3a5-47f0-906c-8dea384d1520} + From 9efa4fcb23db82779d0cd0d9c5fa3c74aa02e31f Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 13:08:03 +0100 Subject: [PATCH 54/74] Commit error fix for some odd reason Player.cpp change followed the last one --- Code/Game/GameLogic/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 6d6d8bf7..ccd3e8f4 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -137,7 +137,7 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint) this->life = 100; this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE; this->lookDir = Oyster::Math::Float4(1,0,0); - this->setState.SetCenterPosition(spawnPoint); + this->newPhysicsState.SetCenterPosition(spawnPoint); } void Player::Rotate(const Oyster::Math3D::Float4 lookDir) From bd9e4599cbf4a2a933b59d9b818f7e52567673e9 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Tue, 4 Feb 2014 13:58:37 +0100 Subject: [PATCH 55/74] GL - fixed respawning and also fixed weapon --- .../DanBiasGame/GameClientState/GameState.cpp | 2 +- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 19 +++++++++++-------- Code/Game/GameLogic/CollisionManager.cpp | 2 +- Code/OysterPhysics3D/Frustrum.cpp | 12 ++++++------ 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index 3e058619..ad86797f 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -132,7 +132,7 @@ bool GameState::LoadModels(std::wstring mapFile) translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(50, 300, 0)); //Oyster::Math3D::RotationMatrix_AxisZ() modelData.world = modelData.world * translate; - modelData.visible = true; + modelData.visible = false; modelData.modelPath = L"building_corporation.dan"; modelData.id = 4; // load models diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index babb4916..1d8e06a4 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -93,11 +93,14 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float 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()) * (500 * dt); - Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); + pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (50000 * dt); + Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(look, up, pos); - Oyster::Math::Float4x4 hitSpace = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/4,1,1,20); + Oyster::Math::Float4x4 hitSpace = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/8,1,1,5); Oyster::Collision3D::Frustrum hitFrustum = Oyster::Collision3D::Frustrum(Oyster::Math3D::ViewProjectionMatrix(aim,hitSpace)); forcePushData args; args.pushForce = pushForce; @@ -142,14 +145,14 @@ void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt) void AttatchmentMassDriver::PickUpObject(const WEAPON_FIRE &usage, float dt) { - //Oyster::Math::Float4 pos = owner->GetPosition() + owner->GetLookDir().GetNormalized(); - //Oyster::Collision3D::Sphere hitSphere = Oyster::Collision3D::Sphere(pos,2000); - Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); + 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(hitFrustum,this,AttemptPickUp); + Oyster::Physics::API::Instance().ApplyEffect(hitSphere,this,AttemptPickUp); } diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 37916799..d5311ece 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -49,7 +49,7 @@ using namespace GameLogic; //use kinetic energyloss of the collision in order too determin how much damage to take //use as part of the damage algorithm int damageDone = 0; - int forceThreashHold = 200; + int forceThreashHold = 200000; if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough { diff --git a/Code/OysterPhysics3D/Frustrum.cpp b/Code/OysterPhysics3D/Frustrum.cpp index 32e6357b..ea7a49d2 100644 --- a/Code/OysterPhysics3D/Frustrum.cpp +++ b/Code/OysterPhysics3D/Frustrum.cpp @@ -15,37 +15,37 @@ namespace PrivateStatic Float4x4 m = vp.GetTranspose(); // left - lp.normal = m.v[3].xyz + m.v[0].xyz; + lp.normal = Float4(m.v[3].xyz + m.v[0].xyz,0); lp.phasing = lp.normal.GetMagnitude(); lp.normal /= lp.phasing; lp.phasing = (m.v[3].w + m.v[0].w) / lp.phasing; // right - rp.normal = m.v[3].xyz - m.v[0].xyz; + rp.normal = Float4(m.v[3].xyz - m.v[0].xyz,0); rp.phasing = rp.normal.GetMagnitude(); rp.normal /= rp.phasing; rp.phasing = (m.v[3].w - m.v[0].w) / rp.phasing; // bottom - bp.normal = m.v[3].xyz + m.v[1].xyz; + bp.normal = Float4(m.v[3].xyz + m.v[1].xyz,0); bp.phasing = bp.normal.GetMagnitude(); bp.normal /= bp.phasing; bp.phasing = (m.v[3].w + m.v[1].w) / bp.phasing; // top - tp.normal = m.v[3].xyz - m.v[1].xyz; + tp.normal = Float4(m.v[3].xyz - m.v[1].xyz,0); tp.phasing = tp.normal.GetMagnitude(); tp.normal /= tp.phasing; tp.phasing = (m.v[3].w - m.v[1].w) / tp.phasing; // near leftHanded DirectX - np.normal = m.v[2].xyz; + np.normal = Float4(m.v[2].xyz,0); np.phasing = np.normal.GetMagnitude(); np.normal /= np.phasing; np.phasing = m.v[2].w / np.phasing; // far lefthanded - fp.normal = m.v[3].xyz - m.v[2].xyz; + fp.normal = Float4(m.v[3].xyz - m.v[2].xyz,0); fp.phasing = fp.normal.GetMagnitude(); fp.normal /= fp.phasing; fp.phasing = (m.v[3].w - m.v[2].w) / fp.phasing; From 15798bfca9bf61b53461b3ffc56ec495d4ab1bfe Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 14:00:33 +0100 Subject: [PATCH 56/74] minor bug found and fixed in rebound --- Code/OysterPhysics3D/OysterCollision3D.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Code/OysterPhysics3D/OysterCollision3D.cpp b/Code/OysterPhysics3D/OysterCollision3D.cpp index cc68d536..41e11875 100644 --- a/Code/OysterPhysics3D/OysterCollision3D.cpp +++ b/Code/OysterPhysics3D/OysterCollision3D.cpp @@ -1064,38 +1064,42 @@ namespace Oyster { namespace Collision3D { namespace Utility Float TimeOfContact( const Sphere &protoStart, const Sphere &protoEnd, const Point &deuter ) { // Bisection with 5 levels of detail - Float t = 0.5f; + 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 *= 0.5f; + t -= d; } else { - t *= 1.5f; + 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; + 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 *= 0.5f; + t -= d; } else { - t *= 1.5f; + t += d; } + d *= 0.5f; } return t; } From 502d0c85861b0ca6693790607fbe4a5e95e44139 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Tue, 4 Feb 2014 14:07:02 +0100 Subject: [PATCH 57/74] GL - actually fixed respawning(turned off) --- Code/Game/GameLogic/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index ccd3e8f4..29fc77cb 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -61,7 +61,7 @@ Player::~Player(void) void Player::BeginFrame() { weapon->Update(0.002f); - if(playerState == PLAYER_STATE_DEAD) Respawn(Oyster::Math::Float3(0,308,0)); + //if(playerState == PLAYER_STATE_DEAD) Respawn(Oyster::Math::Float3(0,308,0)); Object::BeginFrame(); } From 8834f6a2ec17e90a34ac3925e8ca7782680d54f3 Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Tue, 4 Feb 2014 14:30:45 +0100 Subject: [PATCH 58/74] GL - LevelLoader update. --- Code/Game/GameLogic/LevelLoader/ObjectDefines.h | 2 +- Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h index 553db824..7c924976 100644 --- a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h +++ b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h @@ -95,7 +95,7 @@ namespace GameLogic struct LevelMetaData : ObjectTypeHeader { std::string levelName; - FormatVersion levelVersion; + int levelVersion; std::string levelDescription; std::string levelAuthor; int maxNumberOfPlayer; diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp index 8d51f308..68631bf0 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp @@ -58,8 +58,8 @@ namespace GameLogic header.levelName.assign(&tempName[0], &tempName[tempSize]); start += tempSize; - memcpy(&header.levelVersion, &buffer[start], 8); - start += 8; + memcpy(&header.levelVersion, &buffer[start], 4); + start += 4; memcpy(&tempSize, &buffer[start], 4); start +=4; From 9622d37d3f8f33f4068e864be8b7b9872c05554b Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 15:43:17 +0100 Subject: [PATCH 59/74] bug fixes in Physics collision handling --- .../Implementation/PhysicsAPI_Impl.cpp | 39 +++++++++++++------ Code/GamePhysics/PhysicsStructs-Impl.h | 7 +++- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 614014e2..8ca9235b 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -15,7 +15,7 @@ API_Impl API_instance; namespace { void OnPossibleCollision( Octree& worldScene, unsigned int protoTempRef, unsigned int deuterTempRef ) - { /** @todo TODO: OnPossibleCollision is a temporary solution .*/ + { auto proto = worldScene.GetCustomBody( protoTempRef ); auto deuter = worldScene.GetCustomBody( deuterTempRef ); @@ -26,13 +26,30 @@ namespace ICustomBody::State protoState; proto->GetState( protoState ); ICustomBody::State deuterState; deuter->GetState( deuterState ); - Float4 protoG = protoState.GetLinearMomentum(worldPointOfContact.xyz ), - deuterG = deuterState.GetLinearMomentum( worldPointOfContact.xyz ); - // calc from perspective of deuter Float4 normal; deuter->GetNormalAt( worldPointOfContact, normal ); + + if( normal.Dot(normal) == 0.0f ) + { // 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; + } + + Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact.xyz ), + deuterG = deuterState.GetLinearMomentum( worldPointOfContact.xyz ); + Float protoG_Magnitude = protoG.Dot( normal ), - deuterG_Magnitude = deuterG.Dot( normal ); + deuterG_Magnitude = deuterG.Dot( normal ); // if they are not relatively moving towards eachother, there is no collision Float deltaPos = normal.Dot( Float4(deuterState.GetCenterPosition(), 1) - Float4(protoState.GetCenterPosition(), 1) ); @@ -65,8 +82,8 @@ namespace // bounce Float4 bounceD = normal * -Formula::CollisionResponse::Bounce( deuterState.GetRestitutionCoeff(), - deuterState.GetMass(), deuterG_Magnitude, - protoState.GetMass(), protoG_Magnitude ); + deuterState.GetMass(), deuterG_Magnitude, + protoState.GetMass(), protoG_Magnitude ); // calc from perspective of proto @@ -76,14 +93,14 @@ namespace // bounce Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(), - protoState.GetMass(), protoG_Magnitude, - deuterState.GetMass(), deuterG_Magnitude ); + protoState.GetMass(), protoG_Magnitude, + deuterState.GetMass(), deuterG_Magnitude ); 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()); + 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() ); diff --git a/Code/GamePhysics/PhysicsStructs-Impl.h b/Code/GamePhysics/PhysicsStructs-Impl.h index 311b81f8..d3907b54 100644 --- a/Code/GamePhysics/PhysicsStructs-Impl.h +++ b/Code/GamePhysics/PhysicsStructs-Impl.h @@ -159,7 +159,12 @@ namespace Oyster 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 From d8c72205695d16e2f421083559c70ceeb350211b Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Tue, 4 Feb 2014 16:08:28 +0100 Subject: [PATCH 60/74] GL - added some testing things in player and more objects to the world --- Code/Game/DanBiasGame/DanBiasGame_Impl.cpp | 4 +- .../DanBiasGame/GameClientState/GameState.cpp | 94 ++++++++++--------- Code/Game/GameLogic/Level.cpp | 54 +++++++++-- Code/Game/GameLogic/Level.h | 1 - Code/Game/GameLogic/Object.cpp | 26 ++++- Code/Game/GameLogic/Player.cpp | 32 ++++--- Code/Game/GameLogic/Player.h | 1 + .../Implementation/GameSession_Gameplay.cpp | 12 +++ 8 files changed, 155 insertions(+), 69 deletions(-) diff --git a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp index 83e48713..581a7505 100644 --- a/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp +++ b/Code/Game/DanBiasGame/DanBiasGame_Impl.cpp @@ -163,9 +163,9 @@ namespace DanBias DanBias::GameServerAPI::GameStart(); m_data->recieverObj->gameClientState = new Client::GameState(); if(m_data->serverOwner) - ((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(2); + ((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(0); else - ((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(3); + ((Client::GameState*)m_data->recieverObj->gameClientState)->setClientId(1); break; default: return E_FAIL; diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index ad86797f..bdab4dfb 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -74,8 +74,9 @@ bool GameState::LoadModels(std::wstring mapFile) // open file // read file // init models - privData->modelCount = 2; - + privData->modelCount = 4; + myId += privData->modelCount; + int id = 0; // add world model ModelInitData modelData; Oyster::Math3D::Float4x4 translate; @@ -83,7 +84,7 @@ bool GameState::LoadModels(std::wstring mapFile) translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0,0,0)); modelData.world = translate ;//modelData.world * translate modelData.modelPath = L"world_earth.dan"; - modelData.id = 0; + modelData.id = id++; obj = new C_Player(); privData->object.push_back(obj); @@ -94,34 +95,21 @@ bool GameState::LoadModels(std::wstring mapFile) translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(4,320,0)); modelData.world = modelData.world * translate; modelData.modelPath = L"..\\Content\\Models\\box.dan"; - modelData.id = 1; + modelData.id = id++; obj = new C_Player(); privData->object.push_back(obj); privData->object[privData->object.size() -1 ]->Init(modelData); modelData.world = Oyster::Math3D::Float4x4::identity; - // add player model + // add crystal model modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0, 320, 0)); + translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 305, 0)); modelData.world = modelData.world * translate; modelData.visible = true; - modelData.modelPath = L"char_renderTest.dan"; - modelData.id = 2; - // 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_renderTest.dan"; - modelData.id = 3; + modelData.modelPath = L"crystalformation_b.dan"; + modelData.id = id++; // load models obj = new C_Player(); privData->object.push_back(obj); @@ -134,25 +122,39 @@ bool GameState::LoadModels(std::wstring mapFile) modelData.world = modelData.world * translate; modelData.visible = false; modelData.modelPath = L"building_corporation.dan"; - modelData.id = 4; + modelData.id = id++; // load models obj = new C_Player(); privData->object.push_back(obj); privData->object[privData->object.size() -1 ]->Init(modelData); - // add crystal model + // add player model modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 305, 0)); + translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0, 320, 0)); modelData.world = modelData.world * translate; modelData.visible = true; - modelData.modelPath = L"crystalformation_b.dan"; - modelData.id = 5; + modelData.modelPath = L"char_renderTest.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_renderTest.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; } @@ -309,8 +311,8 @@ void GameState::readKeyInput(InputClass* KeyInput) if (KeyInput->IsMousePressed()) { camera->Yaw(-KeyInput->GetYaw()); - //camera->Pitch(KeyInput->GetPitch()); - //pitch = KeyInput->GetPitch(); + camera->Pitch(KeyInput->GetPitch()); + pitch = KeyInput->GetPitch(); camera->UpdateViewMatrix(); GameLogic::Protocol_PlayerLook playerLookDir; Oyster::Math::Float4 look = camera->GetLook(); @@ -385,28 +387,34 @@ void GameState::Protocol( ObjPos* pos ) if(privData->object[i]->GetId() == pos->object_ID) { privData->object[i]->setPos(world); - //camera->setRight((Oyster::Math::Float3(world[0], world[1], world[2]))); - // - //camera->setLook((Oyster::Math::Float3(world[8], world[9], world[10]))); + if(i == myId) // playerobj { - camera->setRight((Oyster::Math::Float3(world[0], world[1], world[2]))); - camera->setUp(Oyster::Math::Float3(world[4], world[5], world[6])); - Oyster::Math::Float3 cameraLook = camera->GetLook(); - Oyster::Math::Float3 objForward = (Oyster::Math::Float3(world[8], world[9], world[10])); - - camera->setLook(objForward); - camera->UpdateViewMatrix(); - Oyster::Math::Float3 pos = Oyster::Math::Float3(world[12], world[13], world[14]); + Oyster::Math::Float3 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 *= 2; objForward *= -3; Oyster::Math::Float3 cameraPos = up + pos + objForward; - //camera->Pitch(pitch); camera->SetPosition(cameraPos); - //camera->LookAt(pos, dir, up); - //Oyster::Math::Float3 newLook = objForward; + camera->UpdateViewMatrix(); } } diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index 858818f6..a80c76f2 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -39,30 +39,64 @@ void Level::InitiateLevel(float radius) levelObj = new StaticObject(rigidBody, LevelCollisionBefore, LevelCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_WORLD); rigidBody->SetCustomTag(levelObj); - + //this->dynamicObjects = new DynamicArray< DynamicObject>; // add box API::SimpleBodyDescription sbDesc_TestBox; sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10,320,0,0); sbDesc_TestBox.ignoreGravity = false; sbDesc_TestBox.mass = 50; - sbDesc_TestBox.size = Oyster::Math::Float4(4,4,4,0); + sbDesc_TestBox.size = Oyster::Math::Float4(2,2,2,0); ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); - testBox = new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX); - rigidBody_TestBox->SetCustomTag(testBox); + this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); + rigidBody_TestBox->SetCustomTag(this->dynamicObjects[0]); rigidBody_TestBox->GetState(state); state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,0)); rigidBody_TestBox->SetState(state); + + // 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[1]); + rigidBody_Crystal->GetState(state); + state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,0)); + rigidBody_Crystal->SetState(state); + + // add house + API::SimpleBodyDescription sbDesc_House; + sbDesc_House.centerPosition = Oyster::Math::Float4(50, 300, 0, 0); + sbDesc_House.ignoreGravity = false; + + sbDesc_House.mass = 70; + sbDesc_House.size = Oyster::Math::Float4(2,3,2,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); + state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,0)); + rigidBody_House->SetState(state); // add gravitation API::Gravity gravityWell; gravityWell.gravityType = API::Gravity::GravityType_Well; - gravityWell.well.mass = 1e18f; + gravityWell.well.mass = 1e17f; gravityWell.well.position = Oyster::Math::Float4(0,0,0,1); API::Instance().AddGravity(gravityWell); } @@ -84,10 +118,12 @@ void Level::RespawnPlayer(Player *player) Object* Level::GetObj( int ID) const { - if( ID == 0 ) - return (Object*)levelObj; - else - return (Object*)testBox; + for (int i = 0; i< this->dynamicObjects.Size(); i++) + { + if(this->dynamicObjects[i]->GetID() == ID) + return this->dynamicObjects[i]; + } + return NULL; } void Level::PhysicsOnMoveLevel(const ICustomBody *object) { diff --git a/Code/Game/GameLogic/Level.h b/Code/Game/GameLogic/Level.h index 60f7a932..00fb76ef 100644 --- a/Code/Game/GameLogic/Level.h +++ b/Code/Game/GameLogic/Level.h @@ -71,7 +71,6 @@ namespace GameLogic GameMode gameMode; Utility::DynamicMemory::SmartPointer rigidBodyLevel; StaticObject *levelObj; - DynamicObject *testBox; }; diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index a000eaed..c7813e61 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -120,9 +120,21 @@ void Object::BeginFrame() { - - - + 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 @@ -130,6 +142,11 @@ void Object::EndFrame() { this->currPhysicsState = this->rigidBody->GetState(); + if(currPhysicsState.GetGravityNormal() !=currPhysicsState.GetGravityNormal()) + { + //error + int i =0 ; + } if(currPhysicsState.GetGravityNormal()!= Float3::null) { Oyster::Math::Float4 axis; @@ -144,6 +161,9 @@ void Object::EndFrame() Oyster::Math::Float3 debug = ::LinearAlgebra3D::WorldAxisOf(::LinearAlgebra3D::Rotation(axis.xyz), Oyster::Math::Float3::standard_unit_y); debug += currPhysicsState.GetGravityNormal(); } + + + this->newPhysicsState = this->currPhysicsState; } diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 29fc77cb..aa649461 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -6,7 +6,7 @@ using namespace GameLogic; using namespace Oyster::Physics; - +const int MOVE_FORCE = 50000; Player::Player() :DynamicObject() { @@ -67,8 +67,17 @@ void Player::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) ; + Oyster::Math::Float3 oldOrt = currPhysicsState.GetRotation(); + + currPhysicsState.AddRotation(deltaAxis); + dx = 0; + this->newPhysicsState = this->currPhysicsState; } void Player::Move(const PLAYER_MOVEMENT &movement) @@ -101,13 +110,13 @@ void Player::MoveForward() { Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; //Oyster::Math::Float3 forward = lookDir; - newPhysicsState.ApplyLinearImpulse(forward * (30000 * this->gameInstance->GetFrameTime())); + newPhysicsState.ApplyLinearImpulse(forward * (MOVE_FORCE * this->gameInstance->GetFrameTime())); } void Player::MoveBackwards() { Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; //Oyster::Math::Float3 forward = lookDir; - newPhysicsState.ApplyLinearImpulse(-forward * 30000 * this->gameInstance->GetFrameTime()); + newPhysicsState.ApplyLinearImpulse(-forward * MOVE_FORCE * this->gameInstance->GetFrameTime()); } void Player::MoveRight() { @@ -115,7 +124,7 @@ void Player::MoveRight() Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; //Oyster::Math::Float3 forward = lookDir; Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); - newPhysicsState.ApplyLinearImpulse(-r * 30000 * this->gameInstance->GetFrameTime()); + newPhysicsState.ApplyLinearImpulse(-r * MOVE_FORCE * this->gameInstance->GetFrameTime()); } void Player::MoveLeft() @@ -124,7 +133,7 @@ void Player::MoveLeft() Oyster::Math::Float3 forward = currPhysicsState.GetOrientation().v[2]; //Oyster::Math::Float3 forward = lookDir; Oyster::Math::Float3 r = (-currPhysicsState.GetGravityNormal()).Cross(forward); //Still get zero - newPhysicsState.ApplyLinearImpulse(r * 30000 * this->gameInstance->GetFrameTime()); + newPhysicsState.ApplyLinearImpulse(r * MOVE_FORCE * this->gameInstance->GetFrameTime()); } void Player::UseWeapon(const WEAPON_FIRE &usage) @@ -147,19 +156,20 @@ void Player::Rotate(const Oyster::Math3D::Float4 lookDir) { int i =0 ; } - Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; - Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; - Oyster::Math::Float3 oldOrt = currPhysicsState.GetRotation(); + //Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; + //Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; + //Oyster::Math::Float3 oldOrt = currPhysicsState.GetRotation(); - newPhysicsState.SetRotation(oldOrt + deltaAxis); + //newPhysicsState.SetRotation(oldOrt + deltaAxis); this->lookDir = lookDir.xyz; + this->dx = lookDir.w; } void Player::Jump() { Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; - newPhysicsState.ApplyLinearImpulse(up * 30000 * this->gameInstance->GetFrameTime()); + newPhysicsState.ApplyLinearImpulse(up * MOVE_FORCE * this->gameInstance->GetFrameTime()); } bool Player::IsWalking() diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index fddf4b44..f609d197 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -83,6 +83,7 @@ namespace GameLogic Weapon *weapon; PLAYER_STATE playerState; Oyster::Math::Float3 lookDir; + Oyster::Math::Float dx; bool hasTakenDamage; float invincibleCooldown; diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index 73ccba1a..ee6cc385 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -122,6 +122,18 @@ namespace DanBias GameSession::gameSession->Send(*p.GetProtocol()); } } + obj = NULL; + obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(2); + if(obj) + { + if(obj->GetObjectType() == OBJECT_TYPE_BOX) + { + int id = obj->GetID(); + Oyster::Math::Float4x4 world = obj->GetOrientation(); + Protocol_ObjectPosition p(world, id); + GameSession::gameSession->Send(*p.GetProtocol()); + } + } } } From 1952ff9aba78dd6a5bc6d09fca8ea1d0e7ae11d1 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 16:10:18 +0100 Subject: [PATCH 61/74] more fixes of potential bugs in Physics collision handling --- .../Implementation/PhysicsAPI_Impl.cpp | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 8ca9235b..61bcb706 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -26,12 +26,15 @@ namespace ICustomBody::State protoState; proto->GetState( protoState ); ICustomBody::State deuterState; deuter->GetState( deuterState ); - // calc from perspective of deuter - Float4 normal; deuter->GetNormalAt( worldPointOfContact, normal ); - - if( normal.Dot(normal) == 0.0f ) + // calc from perspective of deuter. + Float4 normal = worldPointOfContact - Float4(deuterState.GetCenterPosition(), 1.0f ); // 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 @@ -87,9 +90,22 @@ namespace // calc from perspective of proto - proto->GetNormalAt( worldPointOfContact, normal ); - protoG_Magnitude = protoG.Dot( normal ), - deuterG_Magnitude = deuterG.Dot( normal ); + + normal = worldPointOfContact - Float4(protoState.GetCenterPosition(), 1.0f ); + if( normal.Dot(normal) > 0.0f ) + { + proto->GetNormalAt( worldPointOfContact, normal ); + protoG_Magnitude = protoG.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; + } // bounce Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(), From 4ad86ae83b89e7aa69d01852d79e5aca5444bc5c Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Tue, 4 Feb 2014 16:24:37 +0100 Subject: [PATCH 62/74] GL - Added jumppad(implemented but not tested) --- Code/Game/GameLogic/CollisionManager.cpp | 30 ++++++++++++++++++++++++ Code/Game/GameLogic/Game.cpp | 6 ++--- Code/Game/GameLogic/Game.h | 4 +--- Code/Game/GameLogic/GameLogic.vcxproj | 2 ++ Code/Game/GameLogic/JumpPad.cpp | 21 +++++++++++++++++ Code/Game/GameLogic/JumpPad.h | 26 ++++++++++++++++++++ Code/Game/GameLogic/Player.cpp | 5 ++-- 7 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 Code/Game/GameLogic/JumpPad.cpp create mode 100644 Code/Game/GameLogic/JumpPad.h diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index d5311ece..24bb6bba 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -6,12 +6,14 @@ #include "AttatchmentMassDriver.h" #include "Game.h" #include "CollisionManager.h" +#include "JumpPad.h" using namespace Oyster; using namespace GameLogic; void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss); + void SendObjectFlying(Oyster::Physics::ICustomBody &obj, Oyster::Math::Float3 force); //Physics::ICustomBody::SubscriptMessage void Player::PlayerCollision(Oyster::Physics::ICustomBody *rigidBodyPlayer, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) @@ -41,6 +43,34 @@ using namespace GameLogic; //return Physics::ICustomBody::SubscriptMessage_none; } + + void JumpPad::JumpPadActivated(Oyster::Physics::ICustomBody *rigidBodyJumpPad, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) + { + JumpPad *jumpPad = (JumpPad*)(rigidBodyJumpPad->GetCustomTag()); + Object *realObj = (Object*)obj->GetCustomTag(); //needs to be changed? + + switch (realObj->GetObjectType()) + { + case OBJECT_TYPE::OBJECT_TYPE_GENERIC: + break; + case OBJECT_TYPE::OBJECT_TYPE_BOX: + break; + case OBJECT_TYPE::OBJECT_TYPE_PLAYER: + SendObjectFlying(*obj, jumpPad->pushForce); + break; + case OBJECT_TYPE::OBJECT_TYPE_WORLD: + break; + } + } + + void SendObjectFlying(Oyster::Physics::ICustomBody &obj, Oyster::Math::Float3 force) + { + Oyster::Physics::ICustomBody::State state; + + state = obj.GetState(); + state.ApplyLinearImpulse(force); + obj.SetState(state); + } void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss) diff --git a/Code/Game/GameLogic/Game.cpp b/Code/Game/GameLogic/Game.cpp index d9973821..6aecc900 100644 --- a/Code/Game/GameLogic/Game.cpp +++ b/Code/Game/GameLogic/Game.cpp @@ -42,7 +42,7 @@ GameAPI& GameAPI::Instance() Game::Game(void) : initiated(false) , onMoveFnc(0) - , onDeadFnc(0) + , onDisableFnc(0) , frameTime(1.0f/120.0f) {} @@ -151,7 +151,7 @@ void Game::SetSubscription(GameEvent::ObjectEventFunctionType type, GameEvent::O this->onMoveFnc = functionPointer; break; case GameLogic::GameEvent::ObjectEventFunctionType_OnDead: - this->onDeadFnc = functionPointer; + this->onDisableFnc = functionPointer; break; } @@ -183,6 +183,6 @@ void Game::PhysicsOnMove(const ICustomBody *object) } void Game::PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer proto) { - if(gameInstance.onDeadFnc) gameInstance.onDeadFnc(0); + if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0); } diff --git a/Code/Game/GameLogic/Game.h b/Code/Game/GameLogic/Game.h index 55f3e4cf..ddcfc086 100644 --- a/Code/Game/GameLogic/Game.h +++ b/Code/Game/GameLogic/Game.h @@ -73,16 +73,14 @@ namespace GameLogic float GetFrameTime() const; - private: static void PhysicsOnMove(const Oyster::Physics::ICustomBody *object); static void PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer proto); - private: Utility::DynamicMemory::DynamicArray players; LevelData* level; float frameTime; bool initiated; - GameEvent::ObjectEventFunction onDeadFnc; + GameEvent::ObjectEventFunction onDisableFnc; GameEvent::ObjectEventFunction onMoveFnc; }; diff --git a/Code/Game/GameLogic/GameLogic.vcxproj b/Code/Game/GameLogic/GameLogic.vcxproj index 809c82b5..674773bf 100644 --- a/Code/Game/GameLogic/GameLogic.vcxproj +++ b/Code/Game/GameLogic/GameLogic.vcxproj @@ -183,6 +183,7 @@ + @@ -206,6 +207,7 @@ + diff --git a/Code/Game/GameLogic/JumpPad.cpp b/Code/Game/GameLogic/JumpPad.cpp new file mode 100644 index 00000000..c60e248c --- /dev/null +++ b/Code/Game/GameLogic/JumpPad.cpp @@ -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) +{ +} diff --git a/Code/Game/GameLogic/JumpPad.h b/Code/Game/GameLogic/JumpPad.h new file mode 100644 index 00000000..b9fe2253 --- /dev/null +++ b/Code/Game/GameLogic/JumpPad.h @@ -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 diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 29fc77cb..e9510f57 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -60,8 +60,7 @@ Player::~Player(void) void Player::BeginFrame() { - weapon->Update(0.002f); - //if(playerState == PLAYER_STATE_DEAD) Respawn(Oyster::Math::Float3(0,308,0)); + weapon->Update(0.002f); Object::BeginFrame(); } @@ -205,7 +204,7 @@ void Player::DamageLife(int damage) { this->life = 0; playerState = PLAYER_STATE_DEAD; - //do stuff that makes you dead + this->gameInstance->onDisableFnc(this); } } From 68dc5be9cbb798a6efe33684072d1ef9ade62298 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 16:33:52 +0100 Subject: [PATCH 63/74] added lost rebound deltatime compensation --- Code/GamePhysics/Implementation/SimpleRigidBody.cpp | 1 + Code/GamePhysics/Implementation/SphericalRigidBody.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index 034cedea..b57c2a97 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -332,6 +332,7 @@ UpdateState SimpleRigidBody::Update( Float timeStepLength ) 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; } diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp index 6b4cd4ed..ac566abd 100644 --- a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp @@ -254,6 +254,7 @@ UpdateState SphericalRigidBody::Update( Float timeStepLength ) 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; } From c8e8d3510d495dfb2eb94cd0de5bda9139e63410 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 16:38:42 +0100 Subject: [PATCH 64/74] Added debug traps --- .../Implementation/PhysicsAPI_Impl.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 61bcb706..ede0c289 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -51,6 +51,15 @@ namespace Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact.xyz ), deuterG = deuterState.GetLinearMomentum( worldPointOfContact.xyz ); + 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"; + Float protoG_Magnitude = protoG.Dot( normal ), deuterG_Magnitude = deuterG.Dot( normal ); @@ -106,7 +115,10 @@ namespace protoG_Magnitude = -protoG_Magnitude; deuterG_Magnitude = -deuterG_Magnitude; } - + + if( normal != normal ) // debug: trap + const char *breakpoint = "This should never happen"; + // bounce Float4 bounceP = normal * Formula::CollisionResponse::Bounce( protoState.GetRestitutionCoeff(), protoState.GetMass(), protoG_Magnitude, @@ -223,6 +235,9 @@ void API_Impl::Update() } } + if( gravityImpulse != gravityImpulse ) // debug: trap + const char *breakpoint = "This should never happen"; + if( gravityImpulse != Float4::null ) { state.ApplyLinearImpulse( gravityImpulse.xyz ); From ec4d34b131bb5f699417d38215be9deb01d72967 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Tue, 4 Feb 2014 16:39:01 +0100 Subject: [PATCH 65/74] GL - added error checking --- Code/Game/GameLogic/Object.cpp | 16 +++++++++++++++- Code/Game/GameLogic/Player.cpp | 3 +-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index c7813e61..8cb57aae 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -140,8 +140,17 @@ void Object::BeginFrame() // update physic 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 @@ -163,6 +172,11 @@ void Object::EndFrame() } + if(currPhysicsState.GetLinearMomentum() !=currPhysicsState.GetLinearMomentum()) + { + //error + int i =0 ; + } this->newPhysicsState = this->currPhysicsState; } diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index aa649461..f01e4d46 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -6,7 +6,7 @@ using namespace GameLogic; using namespace Oyster::Physics; -const int MOVE_FORCE = 50000; +const int MOVE_FORCE = 5000; Player::Player() :DynamicObject() { @@ -73,7 +73,6 @@ void Player::EndFrame() Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; - Oyster::Math::Float3 oldOrt = currPhysicsState.GetRotation(); currPhysicsState.AddRotation(deltaAxis); dx = 0; From fb4025eb1a2c37af089c8af1d16f15346a72f865 Mon Sep 17 00:00:00 2001 From: Dander7BD Date: Tue, 4 Feb 2014 16:56:31 +0100 Subject: [PATCH 66/74] bug fix --- Code/GamePhysics/PhysicsStructs-Impl.h | 10 +++++++--- Code/OysterPhysics3D/RigidBody.cpp | 7 ++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Code/GamePhysics/PhysicsStructs-Impl.h b/Code/GamePhysics/PhysicsStructs-Impl.h index d3907b54..30e1a605 100644 --- a/Code/GamePhysics/PhysicsStructs-Impl.h +++ b/Code/GamePhysics/PhysicsStructs-Impl.h @@ -322,10 +322,14 @@ namespace Oyster 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 deltaAngularImpulse = ::Oyster::Physics3D::Formula::AngularMomentum( j, offset ); - this->linearImpulse += j - ::Oyster::Physics3D::Formula::TangentialLinearMomentum( deltaAngularImpulse, offset ); + if( offset.Dot(offset) > 0.0f ) + { + ::Oyster::Math::Float3 deltaAngularImpulse = ::Oyster::Physics3D::Formula::AngularMomentum( j, offset ); - this->angularImpulse += deltaAngularImpulse; + this->linearImpulse -= ::Oyster::Physics3D::Formula::TangentialLinearMomentum( deltaAngularImpulse, offset ); + this->angularImpulse += deltaAngularImpulse; + } + this->linearImpulse += j; this->isDisturbed = true; } diff --git a/Code/OysterPhysics3D/RigidBody.cpp b/Code/OysterPhysics3D/RigidBody.cpp index 68f435e9..47a055e2 100644 --- a/Code/OysterPhysics3D/RigidBody.cpp +++ b/Code/OysterPhysics3D/RigidBody.cpp @@ -148,7 +148,12 @@ Float3 RigidBody::GetVelocity_Angular() const Float3 RigidBody::GetLinearMomentum( const Float3 &atWorldPos ) const { // 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 ) From 6818dda2b95ae64c10441b975e53f4dab8787350 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Wed, 5 Feb 2014 09:06:33 +0100 Subject: [PATCH 67/74] GL - testing --- Code/Game/GameLogic/CollisionManager.cpp | 2 +- Code/Game/GameLogic/Game_PlayerData.cpp | 2 ++ Code/Game/GameLogic/Object.cpp | 14 ++++++++++++++ Code/Game/GameLogic/Player.cpp | 4 ++-- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 24bb6bba..cb6862bb 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -84,7 +84,7 @@ using namespace GameLogic; if(kineticEnergyLoss > forceThreashHold) //should only take damage if the force is high enough { damageDone = kineticEnergyLoss * 0.10f; - player.DamageLife(damageDone); + //player.DamageLife(damageDone); } } diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index bf2cbcbe..e73b8255 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -11,6 +11,8 @@ Game::PlayerData::PlayerData() sbDesc.size = Oyster::Math::Float3(4,7,4); 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 diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index 8cb57aae..6f3ef28b 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -156,6 +156,8 @@ void Object::EndFrame() //error int i =0 ; } + + if(currPhysicsState.GetGravityNormal()!= Float3::null) { Oyster::Math::Float4 axis; @@ -170,6 +172,18 @@ void Object::EndFrame() 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()) diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 54e246a7..6b7129d2 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -6,7 +6,7 @@ using namespace GameLogic; using namespace Oyster::Physics; -const int MOVE_FORCE = 5000; +const int MOVE_FORCE = 500; Player::Player() :DynamicObject() { @@ -73,7 +73,7 @@ void Player::EndFrame() Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; - currPhysicsState.AddRotation(deltaAxis); + //currPhysicsState.AddRotation(deltaAxis); dx = 0; this->newPhysicsState = this->currPhysicsState; } From 426444ca343c49a627a85075261e15ca0ee0ffc0 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Wed, 5 Feb 2014 11:46:04 +0100 Subject: [PATCH 68/74] GL - added more boxes and weaponfunctionality --- .../DanBiasGame/GameClientState/GameState.cpp | 82 +++++++++++++++---- .../GameClientState/LoginState.cpp | 13 +-- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 2 +- Code/Game/GameLogic/CollisionManager.cpp | 8 ++ Code/Game/GameLogic/Game.h | 1 + Code/Game/GameLogic/GameAPI.h | 1 + Code/Game/GameLogic/Game_LevelData.cpp | 5 +- Code/Game/GameLogic/Game_PlayerData.cpp | 2 +- Code/Game/GameLogic/Level.cpp | 69 ++++++++++++---- Code/Game/GameLogic/Level.h | 3 +- Code/Game/GameLogic/Object.cpp | 2 +- Code/Game/GameLogic/Player.cpp | 2 +- Code/Game/GameLogic/Player.h | 3 + Code/Game/GameProtocols/PlayerProtocols.h | 18 +++- .../Implementation/GameSession_Gameplay.cpp | 36 ++++---- .../Implementation/PhysicsAPI_Impl.cpp | 21 ++++- Code/GamePhysics/PhysicsAPI.h | 3 +- 17 files changed, 193 insertions(+), 78 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index bdab4dfb..ff30a596 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -49,15 +49,25 @@ bool GameState::Init(Oyster::Network::NetworkClient* nwClient) GameState::gameStateState GameState::LoadGame() { Oyster::Graphics::Definitions::Pointlight plight; - plight.Pos = Oyster::Math::Float3(0,15,5); - plight.Color = Oyster::Math::Float3(0,1,0); - plight.Radius = 50; - plight.Bright = 2; + plight.Pos = Oyster::Math::Float3(315, 0 ,5); + plight.Color = Oyster::Math::Float3(0.9,0.7,0.2); + plight.Radius = 100; + plight.Bright = 0.9; Oyster::Graphics::API::AddLight(plight); - plight.Pos = Oyster::Math::Float3(10,15,5); - plight.Color = Oyster::Math::Float3(1,0,0); - plight.Radius = 50; - plight.Bright = 2; + plight.Pos = Oyster::Math::Float3(10,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(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); plight.Pos = Oyster::Math::Float3(10,-15,5); plight.Color = Oyster::Math::Float3(0,0,1); @@ -74,7 +84,8 @@ bool GameState::LoadModels(std::wstring mapFile) // open file // read file // init models - privData->modelCount = 4; + int nrOfBoxex = 5; + privData->modelCount = 3+nrOfBoxex; myId += privData->modelCount; int id = 0; // add world model @@ -92,15 +103,20 @@ bool GameState::LoadModels(std::wstring mapFile) // add box model modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(4,320,0)); - modelData.world = modelData.world * translate; modelData.modelPath = L"..\\Content\\Models\\box.dan"; - modelData.id = id++; - obj = new C_Player(); - privData->object.push_back(obj); - privData->object[privData->object.size() -1 ]->Init(modelData); - modelData.world = Oyster::Math3D::Float4x4::identity; + + for(int i =0; i< nrOfBoxex; i ++) + { + translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(4,320,0)); + modelData.world = modelData.world * translate; + modelData.id = id++; + + obj = new C_Player(); + privData->object.push_back(obj); + privData->object[privData->object.size() -1 ]->Init(modelData); + modelData.world = Oyster::Math3D::Float4x4::identity; + } // add crystal model modelData.world = Oyster::Math3D::Float4x4::identity; @@ -330,7 +346,37 @@ void GameState::readKeyInput(InputClass* KeyInput) if(!key_Shoot) { 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); key_Shoot = true; } @@ -339,7 +385,7 @@ void GameState::readKeyInput(InputClass* KeyInput) key_Shoot = false; // jump - if(KeyInput->IsKeyPressed(DIK_X)) + if(KeyInput->IsKeyPressed(DIK_SPACE)) { if(!key_Jump) { diff --git a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp index 9beb6657..301ab791 100644 --- a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp @@ -41,9 +41,9 @@ bool LoginState::Init(Oyster::Network::NetworkClient* nwClient) bool LoginState::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.Pos = Oyster::Math::Float3(0,0,5.4f); + plight.Color = Oyster::Math::Float3(1,1,1); + plight.Radius = 100; plight.Bright = 1; Oyster::Graphics::API::AddLight(plight); // open file @@ -55,12 +55,13 @@ bool LoginState::LoadModels(std::wstring file) modelData.world = Oyster::Math3D::Float4x4::identity; modelData.visible = true; - modelData.modelPath = L"..\\Content\\Models\\box_2.dan"; + modelData.modelPath = L"..\\Content\\Models\\box.dan"; // load models - privData->object[0] = new C_StaticObj(); + Oyster::Math3D::Float4x4 translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(2,2,2)); + privData->object[0] = new C_DynamicObj(); 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(-2,-2,-2)); modelData.world = modelData.world * translate; privData->object[1] = new C_DynamicObj(); diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index 1d8e06a4..e0ca6c0f 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -42,7 +42,7 @@ void AttatchmentMassDriver::UseAttatchment(const GameLogic::WEAPON_FIRE &usage, if(hasObject) { - ForcePush(usage,dt);//WARNING THIS IS A CRAP TEST TO MAKE SURE YOU CAN SHOOT BOXES + //ForcePush(usage,dt);//WARNING THIS IS A CRAP TEST TO MAKE SURE YOU CAN SHOOT BOXES break; } ForcePull(usage,dt); diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index cb6862bb..21c073f8 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -96,6 +96,14 @@ using namespace GameLogic; { 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 Level::LevelCollisionBefore(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj) { diff --git a/Code/Game/GameLogic/Game.h b/Code/Game/GameLogic/Game.h index ddcfc086..b57520e0 100644 --- a/Code/Game/GameLogic/Game.h +++ b/Code/Game/GameLogic/Game.h @@ -53,6 +53,7 @@ namespace GameLogic Oyster::Math::Float4x4 GetOrientation() override; int GetID() const override; OBJECT_TYPE GetObjectType() const override; + int getNrOfDynamicObj()const override; IObjectData* GetObjectAt(int ID) const override; Level *level; }; diff --git a/Code/Game/GameLogic/GameAPI.h b/Code/Game/GameLogic/GameAPI.h index f0ce50b1..53931063 100644 --- a/Code/Game/GameLogic/GameAPI.h +++ b/Code/Game/GameLogic/GameAPI.h @@ -100,6 +100,7 @@ namespace GameLogic class ILevelData :public IObjectData { public: + virtual int getNrOfDynamicObj()const = 0; virtual IObjectData* GetObjectAt(int ID) const = 0; }; diff --git a/Code/Game/GameLogic/Game_LevelData.cpp b/Code/Game/GameLogic/Game_LevelData.cpp index 1a5973e6..9bd3275a 100644 --- a/Code/Game/GameLogic/Game_LevelData.cpp +++ b/Code/Game/GameLogic/Game_LevelData.cpp @@ -35,7 +35,10 @@ OBJECT_TYPE Game::LevelData::GetObjectType() const return ((IObjectData*)this->level)->GetObjectType(); //return OBJECT_TYPE_UNKNOWN; } - +int Game::LevelData::getNrOfDynamicObj()const +{ + return this->level->getNrOfDynamicObj(); +} IObjectData* Game::LevelData::GetObjectAt(int ID) const { return this->level->GetObj(ID); diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index e73b8255..da441539 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -19,7 +19,7 @@ Game::PlayerData::PlayerData() Oyster::Physics::ICustomBody *rigidBody = Oyster::Physics::API::Instance().CreateRigidBody(sbDesc).Release(); //create player with this rigid body - this->player = new Player(rigidBody,Object::DefaultCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER); + this->player = new Player(rigidBody,Player::PlayerCollisionBefore, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER); this->player->GetRigidBody()->SetCustomTag(this); /*Oyster::Physics::ICustomBody::State state; this->player->GetRigidBody()->GetState(state); diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index a80c76f2..4abec0ab 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -20,6 +20,35 @@ void Level::InitiateLevel(std::string levelPath) } 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 API::SphericalBodyDescription sbDesc; @@ -29,6 +58,7 @@ void Level::InitiateLevel(float radius) sbDesc.mass = 10e12f; sbDesc.frictionCoeff_Static = 0; sbDesc.frictionCoeff_Dynamic = 0; + //sbDesc.rotation = ICustomBody* rigidBody = API::Instance().CreateRigidBody(sbDesc).Release(); ICustomBody::State state; @@ -49,31 +79,35 @@ void Level::InitiateLevel(float radius) sbDesc_TestBox.size = Oyster::Math::Float4(2,2,2,0); - ICustomBody* rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); - rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); + ICustomBody* rigidBody_TestBox; + + int nrOfBoxex = 5; + for(int i =0; i< nrOfBoxex; i ++) + { + sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10 + ( i*5) ,320,0,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]); + } + + + - this->dynamicObjects.Push(new DynamicObject(rigidBody_TestBox,Object::DefaultCollisionBefore, Object::DefaultCollisionAfter, OBJECT_TYPE::OBJECT_TYPE_BOX)); - rigidBody_TestBox->SetCustomTag(this->dynamicObjects[0]); - rigidBody_TestBox->GetState(state); - state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,0)); - rigidBody_TestBox->SetState(state); // 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[1]); - rigidBody_Crystal->GetState(state); - state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,0)); - rigidBody_Crystal->SetState(state); + rigidBody_Crystal->SetCustomTag(this->dynamicObjects[nrOfBoxex]); + // add house API::SimpleBodyDescription sbDesc_House; @@ -88,10 +122,7 @@ void Level::InitiateLevel(float radius) 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); - state.ApplyLinearImpulse(Oyster::Math::Float3(0,0,0)); - rigidBody_House->SetState(state); - + // add gravitation API::Gravity gravityWell; @@ -116,6 +147,10 @@ void Level::RespawnPlayer(Player *player) this->teamManager.RespawnPlayerRandom(player); } +int Level::getNrOfDynamicObj() +{ + return this->dynamicObjects.Size(); +} Object* Level::GetObj( int ID) const { for (int i = 0; i< this->dynamicObjects.Size(); i++) diff --git a/Code/Game/GameLogic/Level.h b/Code/Game/GameLogic/Level.h index 00fb76ef..cc34408b 100644 --- a/Code/Game/GameLogic/Level.h +++ b/Code/Game/GameLogic/Level.h @@ -59,7 +59,8 @@ namespace GameLogic ********************************************************/ 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); - + + int getNrOfDynamicObj(); Object* GetObj( int ID ) const; static void PhysicsOnMoveLevel(const Oyster::Physics::ICustomBody *object); diff --git a/Code/Game/GameLogic/Object.cpp b/Code/Game/GameLogic/Object.cpp index 6f3ef28b..68297d46 100644 --- a/Code/Game/GameLogic/Object.cpp +++ b/Code/Game/GameLogic/Object.cpp @@ -182,7 +182,7 @@ void Object::EndFrame() Oyster::Math::Float moveUp = 303.5 - pos.GetLength(); up *= moveUp; - //currPhysicsState.SetCenterPosition(pos + up); + currPhysicsState.SetCenterPosition(pos + up); } diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 6b7129d2..5b3657fe 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -73,7 +73,7 @@ void Player::EndFrame() Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; - //currPhysicsState.AddRotation(deltaAxis); + currPhysicsState.AddRotation(deltaAxis); dx = 0; this->newPhysicsState = this->currPhysicsState; } diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index f609d197..4f406e31 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -73,6 +73,9 @@ namespace GameLogic 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: void Jump(); diff --git a/Code/Game/GameProtocols/PlayerProtocols.h b/Code/Game/GameProtocols/PlayerProtocols.h index 216dec73..2192b361 100644 --- a/Code/Game/GameProtocols/PlayerProtocols.h +++ b/Code/Game/GameProtocols/PlayerProtocols.h @@ -142,7 +142,9 @@ namespace GameLogic struct Protocol_PlayerShot :public Oyster::Network::CustomProtocolObject { - bool hasShot; + bool primaryPressed; + bool secondaryPressed; + bool utilityPressed; Protocol_PlayerShot() { @@ -150,19 +152,27 @@ namespace GameLogic this->protocol[0].type = Oyster::Network::NetAttributeType_Short; 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) { - 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) { - hasShot = val[1].value.netBool; + primaryPressed = val[1].value.netBool; + secondaryPressed = val[2].value.netBool; + utilityPressed = val[3].value.netBool; return *this; } 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; } diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index ee6cc385..367048f7 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -111,27 +111,19 @@ namespace DanBias } obj = NULL; - obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(1); - if(obj) + int count = ((GameLogic::ILevelData*)movedObject)->getNrOfDynamicObj(); + for( int i = 0; i < count; i++ ) { - if(obj->GetObjectType() == OBJECT_TYPE_BOX) + obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(i+1); + if(obj) { - int id = obj->GetID(); - Oyster::Math::Float4x4 world = obj->GetOrientation(); - Protocol_ObjectPosition p(world, id); - GameSession::gameSession->Send(*p.GetProtocol()); - } - } - obj = NULL; - obj =((GameLogic::ILevelData*)movedObject)->GetObjectAt(2); - if(obj) - { - if(obj->GetObjectType() == OBJECT_TYPE_BOX) - { - int id = obj->GetID(); - Oyster::Math::Float4x4 world = obj->GetOrientation(); - Protocol_ObjectPosition p(world, id); - GameSession::gameSession->Send(*p.GetProtocol()); + if(obj->GetObjectType() == OBJECT_TYPE_BOX) + { + int id = obj->GetID(); + Oyster::Math::Float4x4 world = obj->GetOrientation(); + Protocol_ObjectPosition p(world, id); + GameSession::gameSession->Send(*p.GetProtocol()); + } } } } @@ -197,9 +189,9 @@ namespace DanBias } void GameSession::Gameplay_PlayerShot ( Protocol_PlayerShot& p, DanBias::GameClient* c ) { - //c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS); - c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_SECONDARY_PRESS); - //c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS); + if(p.primaryPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS); + if(p.secondaryPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_SECONDARY_PRESS); + if(p.utilityPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_UTILLITY_PRESS); } void GameSession::Gameplay_PlayerJump ( Protocol_PlayerJump& p, DanBias::GameClient* c ) { diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index ede0c289..e6f96c3e 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -27,7 +27,7 @@ namespace ICustomBody::State deuterState; deuter->GetState( deuterState ); // calc from perspective of deuter. - Float4 normal = worldPointOfContact - Float4(deuterState.GetCenterPosition(), 1.0f ); // Init value is only borrowed + Float4 normal = (worldPointOfContact - Float4(deuterState.GetCenterPosition(), 1.0f )).GetNormalized(); // Init value is only borrowed if( normal.Dot(normal) > 0.0f ) { deuter->GetNormalAt( worldPointOfContact, normal ); @@ -47,9 +47,10 @@ namespace proto->GetNormalAt( worldPointOfContact, normal ); normal = -normal; } + normal.Normalize(); - Float4 protoG = protoState.GetLinearMomentum( worldPointOfContact.xyz ), - deuterG = deuterState.GetLinearMomentum( worldPointOfContact.xyz ); + 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"; @@ -89,6 +90,18 @@ namespace 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 ); @@ -100,7 +113,7 @@ namespace // calc from perspective of proto - normal = worldPointOfContact - Float4(protoState.GetCenterPosition(), 1.0f ); + normal = (worldPointOfContact - Float4(protoState.GetCenterPosition(), 1.0f )).GetNormalized(); if( normal.Dot(normal) > 0.0f ) { proto->GetNormalAt( worldPointOfContact, normal ); diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h index f636bb73..c3efef3e 100644 --- a/Code/GamePhysics/PhysicsAPI.h +++ b/Code/GamePhysics/PhysicsAPI.h @@ -242,7 +242,8 @@ namespace Oyster { SubscriptMessage_none, SubscriptMessage_kineticLoss, - SubscriptMessage_ignore_collision_response + SubscriptMessage_ignore_collision_response, + SubscriptMessage_player_collision_response }; typedef SubscriptMessage (*EventAction_BeforeCollisionResponse)( const ICustomBody *proto, const ICustomBody *deuter ); From 70a2cf27e3b68967dc8db26fb75d2afb259ec91e Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Wed, 5 Feb 2014 11:53:38 +0100 Subject: [PATCH 69/74] GL - almost ok, at least on the top of the world --- Code/Game/DanBiasGame/GameClientState/GameState.cpp | 2 +- Code/Game/GameLogic/Level.cpp | 2 +- Code/Game/GameLogic/Player.cpp | 5 ----- Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp | 4 ++-- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index ff30a596..0102a027 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -454,7 +454,7 @@ void GameState::Protocol( ObjPos* pos ) camera->setRight(right); camera->setUp(up); - //camera->setLook(objForward); + camera->setLook(objForward); up *= 2; objForward *= -3; diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index 4abec0ab..0a2fd31b 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -84,7 +84,7 @@ void Level::InitiateLevel(float radius) int nrOfBoxex = 5; for(int i =0; i< nrOfBoxex; i ++) { - sbDesc_TestBox.centerPosition = Oyster::Math::Float4(10 + ( i*5) ,320,0,0); + sbDesc_TestBox.centerPosition = Oyster::Math::Float4(20 ,320,0 + ( i*7),0); rigidBody_TestBox = API::Instance().CreateRigidBody(sbDesc_TestBox).Release(); rigidBody_TestBox->SetSubscription(Level::PhysicsOnMoveLevel); diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 5b3657fe..9b0c29ee 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -154,11 +154,6 @@ void Player::Rotate(const Oyster::Math3D::Float4 lookDir) { int i =0 ; } - //Oyster::Math::Float3 up = currPhysicsState.GetOrientation().v[1]; - //Oyster::Math::Float3 deltaAxis = up * (-dx * 0.02) ; - //Oyster::Math::Float3 oldOrt = currPhysicsState.GetRotation(); - - //newPhysicsState.SetRotation(oldOrt + deltaAxis); this->lookDir = lookDir.xyz; this->dx = lookDir.w; diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index e6f96c3e..7981322f 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -91,7 +91,7 @@ namespace } // PLayerHAck - /*if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_player_collision_response ) + if( proto->CallSubscription_BeforeCollisionResponse(proto) == ICustomBody::SubscriptMessage_player_collision_response ) { Float3 linearMomentum = protoState.GetLinearMomentum(); Float3 up = -protoState.GetGravityNormal(); @@ -101,7 +101,7 @@ namespace protoState.SetLinearMomentum(noBounceForce); proto->SetState(protoState); return; - }*/ + } // calculate and store time interpolation value, for later rebound. proto->SetTimeOfContact( worldPointOfContact ); From b39a6703477decfd76935c7879018f7324565a11 Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Wed, 5 Feb 2014 15:46:45 +0100 Subject: [PATCH 70/74] GL - Updated LevelLoader, works with Fredricks level editor. --- .../GameLogic/LevelLoader/LevelLoader.cpp | 3 ++ .../GameLogic/LevelLoader/ObjectDefines.h | 38 +++++++++++++++---- .../GameLogic/LevelLoader/ParseFunctions.cpp | 13 +++++-- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/Code/Game/GameLogic/LevelLoader/LevelLoader.cpp b/Code/Game/GameLogic/LevelLoader/LevelLoader.cpp index 5bb916ab..55a39725 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelLoader.cpp +++ b/Code/Game/GameLogic/LevelLoader/LevelLoader.cpp @@ -4,17 +4,20 @@ #include "LevelLoader.h" #include "LevelParser.h" + using namespace GameLogic; using namespace GameLogic::LevelFileLoader; struct LevelLoader::PrivData { LevelParser parser; + std::string folderPath; }; LevelLoader::LevelLoader() : pData(new PrivData) { + pData->folderPath = "Standard path"; } LevelLoader::~LevelLoader() diff --git a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h index 7c924976..8287dafb 100644 --- a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h +++ b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h @@ -34,6 +34,15 @@ namespace GameLogic UsePhysics_Unknown = -1 }; + enum CollisionGeometryType + { + CollisionGeometryType_Box, + CollisionGeometryType_Sphere, + + CollisionGeometryType_Count, + CollisionGeometryType_Unknown = -1 + }; + enum LightType { LightType_PointLight, @@ -55,6 +64,18 @@ namespace GameLogic GameMode_Unknown = -1 }; + enum WorldSize + { + WorldSize_Tiny, + WorldSize_Small, + WorldSize_Medium, + WorldSize_Big, + WorldSize_Humongous, + + WorldSize_Count, + WorldSize_Unknown = -1 + }; + /************************************ Structs @@ -62,8 +83,8 @@ namespace GameLogic struct FormatVersion { - int formatVersionMajor; - int formatVersionMinor; + unsigned int formatVersionMajor; + unsigned int formatVersionMinor; bool operator ==(const FormatVersion& obj) { @@ -89,22 +110,22 @@ namespace GameLogic float inertiaRotation[3]; float frictionCoeffStatic; float frictionCoeffDynamic; - + CollisionGeometryType geometryType; }; - struct LevelMetaData : ObjectTypeHeader + struct LevelMetaData : public ObjectTypeHeader { std::string levelName; - int levelVersion; + unsigned int levelVersion; std::string levelDescription; std::string levelAuthor; - int maxNumberOfPlayer; - int worldSize; + unsigned int maxNumberOfPlayer; + WorldSize worldSize; std::string overviewPicturePath; std::vector gameModesSupported; }; - struct ObjectHeader : public ObjectTypeHeader + struct ObjectHeader : public ObjectTypeHeader, public PhysicsObject { //Model, std::string ModelFile; @@ -112,6 +133,7 @@ namespace GameLogic float position[3]; //Rotation float rotation[3]; + float angle; //Scale float scale[3]; }; diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp index 68631bf0..95236c05 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp @@ -23,7 +23,7 @@ namespace GameLogic void ParseObject(char* buffer, ObjectHeader& header, int& size) { char tempName[128]; - int tempSize = 0; + unsigned int tempSize = 0; int start = 0; memcpy(&header.typeID, &buffer[start], 4); @@ -36,8 +36,13 @@ namespace GameLogic header.ModelFile.assign(&tempName[0], &tempName[tempSize]); start += tempSize; - memcpy(&header.position, &buffer[start], 36); - start += 36; + //3 float[3], 1 float + memcpy(&header.position, &buffer[start], 40); + start += 40; + + //2 float[3], 3 float, 2 uint + memcpy(&header.usePhysics, &buffer[start], 44); + start += 44; size += start; } @@ -45,7 +50,7 @@ namespace GameLogic void ParseLevelMetaData(char* buffer, LevelMetaData &header, int &size) { int start = 0; - int tempSize; + unsigned int tempSize; char tempName[128]; memcpy(&header.typeID, &buffer[start], 4); From 91db71fe0e1643f82c9af0d6d2bdf1c6ae1f04a4 Mon Sep 17 00:00:00 2001 From: lindaandersson Date: Wed, 5 Feb 2014 15:54:48 +0100 Subject: [PATCH 71/74] GL - 20 boxes and a house --- .../DanBiasGame/GameClientState/GameState.cpp | 51 +++++++++++++++---- .../GameClientState/LoginState.cpp | 19 ++++--- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 12 +++-- Code/Game/GameLogic/Game_PlayerData.cpp | 2 +- Code/Game/GameLogic/Level.cpp | 44 ++++++++++++++-- .../Implementation/GameSession_Gameplay.cpp | 9 ++-- 6 files changed, 105 insertions(+), 32 deletions(-) diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index 0102a027..d8547943 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -84,7 +84,7 @@ bool GameState::LoadModels(std::wstring mapFile) // open file // read file // init models - int nrOfBoxex = 5; + int nrOfBoxex = 20; privData->modelCount = 3+nrOfBoxex; myId += privData->modelCount; int id = 0; @@ -103,7 +103,7 @@ bool GameState::LoadModels(std::wstring mapFile) // add box model modelData.world = Oyster::Math3D::Float4x4::identity; - modelData.modelPath = L"..\\Content\\Models\\box.dan"; + modelData.modelPath = L"crate_colonists.dan"; for(int i =0; i< nrOfBoxex; i ++) @@ -120,7 +120,7 @@ bool GameState::LoadModels(std::wstring mapFile) // add crystal model modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 305, 0)); + translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(10, 301, 0)); modelData.world = modelData.world * translate; modelData.visible = true; @@ -133,10 +133,11 @@ bool GameState::LoadModels(std::wstring mapFile) // add house model modelData.world = Oyster::Math3D::Float4x4::identity; - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(50, 300, 0)); - //Oyster::Math3D::RotationMatrix_AxisZ() - modelData.world = modelData.world * translate; - modelData.visible = false; + 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 @@ -144,13 +145,14 @@ bool GameState::LoadModels(std::wstring mapFile) privData->object.push_back(obj); 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_renderTest.dan"; + modelData.modelPath = L"char_still_sizeref.dan"; modelData.id = id++; // load models obj = new C_Player(); @@ -163,14 +165,41 @@ bool GameState::LoadModels(std::wstring mapFile) modelData.world = modelData.world * translate; modelData.visible = true; - modelData.modelPath = L"char_renderTest.dan"; + 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; } @@ -456,8 +485,8 @@ void GameState::Protocol( ObjPos* pos ) camera->setUp(up); camera->setLook(objForward); - up *= 2; - objForward *= -3; + up *= 1; + objForward *= -2; Oyster::Math::Float3 cameraPos = up + pos + objForward; camera->SetPosition(cameraPos); diff --git a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp index 301ab791..4a244a8b 100644 --- a/Code/Game/DanBiasGame/GameClientState/LoginState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LoginState.cpp @@ -41,7 +41,7 @@ bool LoginState::Init(Oyster::Network::NetworkClient* nwClient) bool LoginState::LoadModels(std::wstring file) { Oyster::Graphics::Definitions::Pointlight plight; - plight.Pos = Oyster::Math::Float3(0,0,5.4f); + plight.Pos = Oyster::Math::Float3(0,0,5); plight.Color = Oyster::Math::Float3(1,1,1); plight.Radius = 100; plight.Bright = 1; @@ -55,14 +55,22 @@ bool LoginState::LoadModels(std::wstring file) modelData.world = Oyster::Math3D::Float4x4::identity; modelData.visible = true; - modelData.modelPath = L"..\\Content\\Models\\box.dan"; + modelData.modelPath = L"identityPlane.dan"; // load models - Oyster::Math3D::Float4x4 translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(2,2,2)); + 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); - translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(-2,-2,-2)); - modelData.world = modelData.world * translate; + translate = Oyster::Math3D::TranslationMatrix(Oyster::Math::Float3(0,0,-2)); + modelData.world = translate ;//* rot; privData->object[1] = new C_DynamicObj(); privData->object[1]->Init(modelData); @@ -127,7 +135,6 @@ bool LoginState::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++) diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index e0ca6c0f..59be4542 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -63,8 +63,10 @@ void AttatchmentMassDriver::Update(float dt) Oyster::Physics::ICustomBody::State state; state = heldObject->GetState(); Oyster::Math::Float3 ownerPos = owner->GetPosition(); - ownerPos.y += 2; - Oyster::Math::Float3 pos = ownerPos + owner->GetLookDir().GetNormalized()*2; + 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); @@ -84,7 +86,7 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float if(hasObject) { Oyster::Physics::API::Instance().ReleaseFromLimbo(heldObject); - pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (2000); + pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (700); Oyster::Physics::ICustomBody::State state = heldObject->GetState(); state.ApplyLinearImpulse((Oyster::Math::Float3)pushForce); heldObject->SetState(state); @@ -97,10 +99,10 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float Oyster::Math::Float3 look = owner->GetLookDir(); Oyster::Math::Float3 pos = owner->GetPosition(); - pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (50000 * dt); + 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,5); + 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; diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index da441539..61c36dd1 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -8,7 +8,7 @@ Game::PlayerData::PlayerData() //set some stats that are appropriate to a player Oyster::Physics::API::SimpleBodyDescription sbDesc; 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; diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index 0a2fd31b..49646e53 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -82,15 +82,46 @@ void Level::InitiateLevel(float radius) ICustomBody* rigidBody_TestBox; int nrOfBoxex = 5; + int offset = 0; for(int i =0; i< nrOfBoxex; i ++) { - sbDesc_TestBox.centerPosition = Oyster::Math::Float4(20 ,320,0 + ( i*7),0); + 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 += 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,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]); + } @@ -111,18 +142,21 @@ void Level::InitiateLevel(float radius) // add house API::SimpleBodyDescription sbDesc_House; - sbDesc_House.centerPosition = Oyster::Math::Float4(50, 300, 0, 0); + //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(2,3,2,0); + 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 API::Gravity gravityWell; diff --git a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp index 367048f7..beced0a4 100644 --- a/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp +++ b/Code/Game/GameServer/Implementation/GameSession_Gameplay.cpp @@ -188,10 +188,11 @@ namespace DanBias } void GameSession::Gameplay_PlayerShot ( Protocol_PlayerShot& p, DanBias::GameClient* c ) - { - if(p.primaryPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS); - if(p.secondaryPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_SECONDARY_PRESS); - if(p.utilityPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_UTILLITY_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 ) { From 9bdf258c5d80a17f97144f60c829314d8b59fcd8 Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Fri, 7 Feb 2014 14:12:54 +0100 Subject: [PATCH 72/74] GL - Updated LevelLoader 2.0. Bounding volume 1.0 The ObjectSpecialType enum is not correct. It has to be updated. --- .../GameLogic/LevelLoader/LevelParser.cpp | 97 ++++++++++-- Code/Game/GameLogic/LevelLoader/LevelParser.h | 2 +- .../GameLogic/LevelLoader/ObjectDefines.h | 145 ++++++++++++++---- .../GameLogic/LevelLoader/ParseFunctions.cpp | 55 ++++++- .../GameLogic/LevelLoader/ParseFunctions.h | 1 + 5 files changed, 256 insertions(+), 44 deletions(-) diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp index 088c3916..75fed5cf 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp @@ -9,7 +9,7 @@ using namespace Utility::DynamicMemory; LevelParser::LevelParser() { - formatVersion.formatVersionMajor = 1; + formatVersion.formatVersionMajor = 2; formatVersion.formatVersionMinor = 0; } @@ -29,12 +29,15 @@ std::vector> LevelParser::Parse(std::string filen char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize); //Read format version - FormatVersion levelFormatVersion; + LevelLoaderInternal::FormatVersion levelFormatVersion; ParseObject(&buffer[counter], &levelFormatVersion, sizeof(levelFormatVersion)); counter += sizeof(levelFormatVersion); if(this->formatVersion != levelFormatVersion) { //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) @@ -52,12 +55,74 @@ std::vector> LevelParser::Parse(std::string filen break; } - //This is by design, static and dynamic is using the same converter. Do not add anything inbetween them. + //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 = new ObjectHeader; - ParseObject(&buffer[counter], *header, counter); - objects.push_back(header); + //Get specialType. + 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); + + 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; } @@ -68,7 +133,12 @@ std::vector> LevelParser::Parse(std::string filen //Get Light type ParseObject(&buffer[counter+4], &lightType, sizeof(lightType)); - switch(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: { @@ -98,7 +168,7 @@ std::vector> LevelParser::Parse(std::string filen //Undefined LightType. break; } - break; + break;*/ } default: //Couldn't find typeID. FAIL!!!!!! @@ -123,12 +193,16 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) char* buffer = (char*)loader.LoadFile(filename.c_str(), bufferSize); //Read format version - FormatVersion levelFormatVersion; + LevelLoaderInternal::FormatVersion levelFormatVersion; ParseObject(&buffer[counter], &levelFormatVersion, sizeof(formatVersion)); counter += sizeof(levelFormatVersion); if(this->formatVersion != levelFormatVersion) { //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. @@ -157,6 +231,9 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) LightType lightType; ParseObject(&buffer[counter+4], &lightType, sizeof(lightType)); + //We only support pointlight for now. + counter += sizeof(BasicLight); + /* switch(lightType) { case LightType_PointLight: @@ -177,7 +254,7 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) default: //Undefined LightType. break; - } + }*/ } default: diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.h b/Code/Game/GameLogic/LevelLoader/LevelParser.h index 9ad30642..346b75b5 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.h +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.h @@ -23,7 +23,7 @@ namespace GameLogic LevelMetaData ParseHeader(std::string filename); private: - FormatVersion formatVersion; + LevelLoaderInternal::FormatVersion formatVersion; }; } diff --git a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h index 8287dafb..b1264162 100644 --- a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h +++ b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h @@ -9,7 +9,7 @@ namespace GameLogic /************************************ Enums *************************************/ - + enum ObjectType { ObjectType_LevelMetaData, @@ -23,6 +23,21 @@ namespace GameLogic ObjectType_Unknown = -1 }; + enum ObjectSpecialType + { + ObjectSpecialType_World, + ObjectSpecialType_Building, + ObjectSpecialType_Damaging, + ObjectSpecialType_Explosive, + ObjectSpecialType_JumpPad, + ObjectSpecialType_BoostPad, + ObjectSpecialType_Portal, + ObjectSpecialType_SpawnPoint, + + ObjectSpecialType_Count, + ObjectSpecialType_Unknown = -1 + }; + enum UsePhysics { UsePhysics_UseFullPhysics, @@ -43,11 +58,12 @@ namespace GameLogic CollisionGeometryType_Unknown = -1 }; + //Only supports Pointlight right now. enum LightType { LightType_PointLight, - LightType_DirectionalLight, - LightType_SpotLight, + //LightType_DirectionalLight, + //LightType_SpotLight, LightType_Count, LightType_Unknown = -1 @@ -80,38 +96,81 @@ namespace GameLogic /************************************ Structs *************************************/ - - struct FormatVersion + namespace LevelLoaderInternal { - unsigned int formatVersionMajor; - unsigned int formatVersionMinor; - - bool operator ==(const FormatVersion& obj) + struct FormatVersion { - return (this->formatVersionMajor != obj.formatVersionMajor && this->formatVersionMinor != obj.formatVersionMinor); - } + unsigned int formatVersionMajor; + unsigned int formatVersionMinor; + + FormatVersion() + : formatVersionMajor(0), formatVersionMinor(0) + {} - bool operator !=(const FormatVersion& obj) - { - return !(*this == obj); - } - }; + FormatVersion(unsigned int major, unsigned int minor) + : formatVersionMajor(major), formatVersionMinor(minor) + {} + + bool operator ==(const FormatVersion& obj) + { + return (this->formatVersionMajor == obj.formatVersionMajor && this->formatVersionMinor == obj.formatVersionMinor); + } + + bool operator !=(const FormatVersion& obj) + { + return !(*this == obj); + } + }; + } struct ObjectTypeHeader { ObjectType typeID; }; - struct PhysicsObject + namespace LevelLoaderInternal { - UsePhysics usePhysics; - float mass; - float inertiaMagnitude[3]; - float inertiaRotation[3]; - float frictionCoeffStatic; - float frictionCoeffDynamic; - CollisionGeometryType geometryType; - }; + 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 BoundingVolume + { + CollisionGeometryType geoType; + union + { + LevelLoaderInternal::BoundingVolumeBox box; + LevelLoaderInternal::BoundingVolumeSphere sphere; + }; + }; + + struct PhysicsObject + { + UsePhysics usePhysics; + float mass; + float inertiaMagnitude[3]; + float inertiaRotation[3]; + float frictionCoeffStatic; + float frictionCoeffDynamic; + float restitutionCoeff; + BoundingVolume boundingVolume; + }; + } struct LevelMetaData : public ObjectTypeHeader { @@ -125,8 +184,10 @@ namespace GameLogic std::vector gameModesSupported; }; - struct ObjectHeader : public ObjectTypeHeader, public PhysicsObject + struct ObjectHeader : public ObjectTypeHeader, public LevelLoaderInternal::PhysicsObject { + //Special type id for special objects: portal, jumppad, exploding objects, etc. + ObjectSpecialType specialTypeID; //Model, std::string ModelFile; //Position @@ -138,6 +199,25 @@ namespace GameLogic float scale[3]; }; + /************************************ + 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 @@ -145,12 +225,13 @@ namespace GameLogic struct BasicLight : public ObjectTypeHeader { - LightType lightType; - float ambientColor[3]; - float diffuseColor[3]; - float specularColor[3]; + 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]; @@ -166,7 +247,7 @@ namespace GameLogic float direction[3]; float range; float attenuation[3]; - }; + };*/ } #endif \ No newline at end of file diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp index 95236c05..baae678d 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp @@ -4,6 +4,7 @@ #include "ParseFunctions.h" #include "../../../Misc/Packing/Packing.h" +#include "Loader.h" #include using namespace Oyster::Packing; @@ -29,6 +30,9 @@ namespace GameLogic memcpy(&header.typeID, &buffer[start], 4); start += 4; + memcpy(&header.specialTypeID, &buffer[start], 4); + start += 4; + memcpy(&tempSize, &buffer[start], 4); start += 4; @@ -36,13 +40,18 @@ namespace GameLogic 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; - //2 float[3], 3 float, 2 uint + //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; } @@ -107,5 +116,49 @@ namespace GameLogic 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)); + int a = sizeof(volume.sphere); + a = 5; + //start += sizeof(volume.sphere); + break; + } + + size += start; + } } } \ No newline at end of file diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.h b/Code/Game/GameLogic/LevelLoader/ParseFunctions.h index f68a9289..f66351b4 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.h +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.h @@ -21,6 +21,7 @@ namespace GameLogic 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 ParseBoundingVolume(char* buffer, LevelLoaderInternal::BoundingVolume& volume, int &size); } } From fef40f58f9b2361b923427000abadd6dc92ea2d6 Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Fri, 7 Feb 2014 14:44:25 +0100 Subject: [PATCH 73/74] GL - Fixed memory leaks in LevelLoader. --- Code/Game/GameLogic/LevelLoader/LevelParser.cpp | 8 ++++---- Code/Game/GameLogic/LevelLoader/ObjectDefines.h | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp index 75fed5cf..667633f9 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp @@ -43,14 +43,14 @@ std::vector> LevelParser::Parse(std::string filen while(counter < bufferSize) { //Get typeID - ObjectTypeHeader typeID; + ObjectType typeID; ParseObject(&buffer[counter], &typeID, sizeof(typeID)); - switch((int)typeID.typeID) + switch((int)typeID) { case ObjectType_LevelMetaData: { - LevelMetaData* header = new LevelMetaData; - ParseLevelMetaData(&buffer[counter], *header, counter); + SmartPointer header = new LevelMetaData; + ParseLevelMetaData(&buffer[counter], *(LevelMetaData*)header.Get(), counter); objects.push_back(header); break; } diff --git a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h index b1264162..ff18553d 100644 --- a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h +++ b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h @@ -126,6 +126,9 @@ namespace GameLogic struct ObjectTypeHeader { ObjectType typeID; + + //Unless this is here the object destructor wont be called. + virtual ~ObjectTypeHeader(){} }; namespace LevelLoaderInternal @@ -182,6 +185,9 @@ namespace GameLogic WorldSize worldSize; std::string overviewPicturePath; std::vector gameModesSupported; + + virtual ~LevelMetaData(){} + }; struct ObjectHeader : public ObjectTypeHeader, public LevelLoaderInternal::PhysicsObject @@ -197,6 +203,8 @@ namespace GameLogic float angle; //Scale float scale[3]; + + virtual ~ObjectHeader(){} }; /************************************ From 0c4f70e400a88023513505e59f25debc25a9ad6e Mon Sep 17 00:00:00 2001 From: Pontus Fransson Date: Fri, 7 Feb 2014 15:20:34 +0100 Subject: [PATCH 74/74] GL - Updated loadLevelHeader() .Added Cylinder bounding volume. --- .../GameLogic/LevelLoader/LevelParser.cpp | 26 +++++++++++++++++-- .../GameLogic/LevelLoader/ObjectDefines.h | 12 ++++++++- .../GameLogic/LevelLoader/ParseFunctions.cpp | 10 +++++-- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp index 667633f9..33567cc9 100644 --- a/Code/Game/GameLogic/LevelLoader/LevelParser.cpp +++ b/Code/Game/GameLogic/LevelLoader/LevelParser.cpp @@ -1,3 +1,7 @@ +///////////////////////////////////// +// Created by Pontus Fransson 2013 // +///////////////////////////////////// + #include "LevelParser.h" #include "Loader.h" @@ -208,10 +212,10 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) //Find the header in the returned string. while(counter < bufferSize) { - ObjectTypeHeader typeID; + ObjectType typeID; ParseObject(&buffer[counter], &typeID, sizeof(typeID)); - switch(typeID.typeID) + switch(typeID) { case ObjectType_LevelMetaData: ParseLevelMetaData(&buffer[counter], levelHeader, counter); @@ -223,6 +227,24 @@ LevelMetaData LevelParser::ParseHeader(std::string filename) { ObjectHeader header; ParseObject(&buffer[counter], header, counter); + + switch(header.specialTypeID) + { + case ObjectSpecialType_JumpPad: + counter += sizeof(16); + 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; } diff --git a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h index ff18553d..d87e42b2 100644 --- a/Code/Game/GameLogic/LevelLoader/ObjectDefines.h +++ b/Code/Game/GameLogic/LevelLoader/ObjectDefines.h @@ -25,7 +25,7 @@ namespace GameLogic enum ObjectSpecialType { - ObjectSpecialType_World, + ObjectSpecialType_World, //Always the main celestial body ObjectSpecialType_Building, ObjectSpecialType_Damaging, ObjectSpecialType_Explosive, @@ -53,6 +53,7 @@ namespace GameLogic { CollisionGeometryType_Box, CollisionGeometryType_Sphere, + CollisionGeometryType_Cylinder, CollisionGeometryType_Count, CollisionGeometryType_Unknown = -1 @@ -152,6 +153,14 @@ namespace GameLogic float radius; }; + struct BoundingVolumeCylinder : public BoundingVolumeBase + { + float length; + float angularAxis[3]; + float angle; + float radius; + }; + struct BoundingVolume { CollisionGeometryType geoType; @@ -159,6 +168,7 @@ namespace GameLogic { LevelLoaderInternal::BoundingVolumeBox box; LevelLoaderInternal::BoundingVolumeSphere sphere; + LevelLoaderInternal::BoundingVolumeCylinder cylinder; }; }; diff --git a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp index baae678d..e8c055b3 100644 --- a/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp +++ b/Code/Game/GameLogic/LevelLoader/ParseFunctions.cpp @@ -152,10 +152,16 @@ namespace GameLogic case CollisionGeometryType_Sphere: memcpy(&volume.sphere, &buf[12], sizeof(volume.sphere)); - int a = sizeof(volume.sphere); - a = 5; //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;