From f35f96b8f2104f2b117c94785f50c0ec3ff90bdc Mon Sep 17 00:00:00 2001 From: lanariel Date: Tue, 25 Feb 2014 09:45:02 +0100 Subject: [PATCH 1/3] Instanced fix, render char, manual instanced flag per model, wireframe fix --- .../GameClient/GameClientState/GameState.cpp | 8 +- Code/OysterGraphics/DllInterfaces/GFXAPI.cpp | 11 ++- Code/OysterGraphics/Model/Model.h | 1 + .../OysterGraphics/Render/DefaultRenderer.cpp | 11 +-- Code/OysterGraphics/Render/Resources.cpp | 9 +-- .../Shader/Passes/Light/Defines.hlsli | 10 +++ .../Shader/Passes/Light/LightCalc.hlsli | 5 ++ .../Shader/Passes/Light/LightPass.hlsl | 78 ++++++++++++++++++- 8 files changed, 111 insertions(+), 22 deletions(-) diff --git a/Code/Game/GameClient/GameClientState/GameState.cpp b/Code/Game/GameClient/GameClientState/GameState.cpp index d08b1101..b608a4f3 100644 --- a/Code/Game/GameClient/GameClientState/GameState.cpp +++ b/Code/Game/GameClient/GameClientState/GameState.cpp @@ -114,8 +114,8 @@ void GameState::InitiatePlayer( int id, const std::string &modelName, const floa modelData.position = position; modelData.rotation = ArrayToQuaternion( rotation ); modelData.scale = scale; - StringToWstring( modelName, modelData.modelPath ); modelData.id = id; + StringToWstring(modelName,modelData.modelPath); // RB DEBUG RBInitData RBData; @@ -141,8 +141,8 @@ void GameState::InitiatePlayer( int id, const std::string &modelName, const floa this->privData->camera.SetPosition( p->getPos() ); Float3 offset = Float3( 0.0f ); // DEBUG position of camera so we can see the player model - //offset.y = p->getScale().y * 5.0f; - //offset.z = p->getScale().z * -5.0f; + offset.y = p->getScale().y * 5.0f; + offset.z = p->getScale().z * -5.0f; // !DEBUG this->privData->camera.SetHeadOffset( offset ); this->privData->camera.UpdateOrientation(); @@ -186,7 +186,7 @@ bool GameState::Render() { if(playerObject->second) { - if( this->privData->myId != playerObject->second->GetId() ) + //if( this->privData->myId != playerObject->second->GetId() ) { playerObject->second->Render(); } diff --git a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp index d4c48957..ee3d9f8a 100644 --- a/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp +++ b/Code/OysterGraphics/DllInterfaces/GFXAPI.cpp @@ -58,9 +58,11 @@ namespace Oyster debugSRV = (ID3D11ShaderResourceView*)API::CreateTexture(L"color_white.png"); cube = CreateModel(L"generic_cube.dan"); - cube->Tint = Math::Float3(0.0f,0.0f,1.0f); + cube->Tint = Math::Float3(1.0f,0.0f,0.0f); + cube->Instanced = false; sphere = CreateModel(L"generic_sphere.dan"); sphere->Tint = Math::Float3(1.0f,0.5f,182/255.0f); + sphere->Instanced = false; D3D11_RASTERIZER_DESC desc; @@ -158,7 +160,7 @@ namespace Oyster desc.Type = Core::Buffer::VERTEX_BUFFER; desc.Usage = Core::Buffer::BUFFER_CPU_WRITE_DISCARD; desc.InitData = 0; - desc.NumElements = maxModels; + desc.NumElements = maxModels+1; Render::Resources::Gather::InstancedData.Init(desc); } @@ -172,6 +174,7 @@ namespace Oyster m->Animation.AnimationPlaying = NULL; m->Tint = Math::Float3(1); m->GlowTint = Math::Float3(1); + m->Instanced = true; m->info = (Model::ModelInfo*)Core::loader.LoadResource((Core::modelPath + filename).c_str(),Oyster::Graphics::Loading::LoadDAN, Oyster::Graphics::Loading::UnloadDAN); Model::ModelInfo* mi = (Model::ModelInfo*)m->info; @@ -256,9 +259,9 @@ namespace Oyster void API::StartRenderWireFrame() { - Core::deviceContext->OMSetRenderTargets((UINT)Render::Resources::Gather::AnimatedPass.RTV.size(),&Render::Resources::Gather::AnimatedPass.RTV[0],NULL); + //Core::deviceContext->OMSetRenderTargets((UINT)Render::Resources::Gather::AnimatedPass.RTV.size(),&Render::Resources::Gather::AnimatedPass.RTV[0],NULL); Core::deviceContext->RSSetState(wire); - Core::deviceContext->OMSetRenderTargets((UINT)Render::Resources::Gather::AnimatedPass.RTV.size(),&Render::Resources::Gather::AnimatedPass.RTV[0],NULL); + //Core::deviceContext->OMSetRenderTargets((UINT)Render::Resources::Gather::AnimatedPass.RTV.size(),&Render::Resources::Gather::AnimatedPass.RTV[0],NULL); } void API::RenderDebugCube(Math::Matrix world) diff --git a/Code/OysterGraphics/Model/Model.h b/Code/OysterGraphics/Model/Model.h index 5985dbcd..6d4e96f2 100644 --- a/Code/OysterGraphics/Model/Model.h +++ b/Code/OysterGraphics/Model/Model.h @@ -26,6 +26,7 @@ namespace Oyster Oyster::Math::Float3 Tint; Oyster::Math::Float3 GlowTint; bool Visible; + bool Instanced; AnimationData Animation; }; } diff --git a/Code/OysterGraphics/Render/DefaultRenderer.cpp b/Code/OysterGraphics/Render/DefaultRenderer.cpp index a735f4b3..4b979be8 100644 --- a/Code/OysterGraphics/Render/DefaultRenderer.cpp +++ b/Code/OysterGraphics/Render/DefaultRenderer.cpp @@ -43,6 +43,8 @@ namespace Oyster { (*i).second->Models=0; } + + Core::PipelineManager::SetRenderPass(Resources::Gather::AnimatedPass); } void DefaultRenderer::RenderScene(Model::Model* models, int count, Math::Matrix View, Math::Matrix Projection, float deltaTime) @@ -53,7 +55,7 @@ namespace Oyster continue; Model::ModelInfo* info = models[i].info; - if(!info->Animated) + if(!info->Animated && models[i].Instanced) { Definitions::RenderInstanceData rid; Math::Float3x3 normalTransform; @@ -229,6 +231,8 @@ namespace Oyster void RenderModel(Model::ModelInfo* info, Definitions::RenderInstanceData* rid , int count) { + if(count < 1) + return; if(info->Material.size()) { Core::deviceContext->PSSetShaderResources(0,(UINT)info->Material.size(),&(info->Material[0])); @@ -263,10 +267,7 @@ namespace Oyster for(auto i = Render::Resources::RenderData.begin(); i != Render::Resources::RenderData.end(); i++ ) { - for(int m = 0; m <(*i).second->Models; ++m) - { - RenderModel((*i).first,(*i).second->rid, (*i).second->Models); - } + RenderModel((*i).first,(*i).second->rid, (*i).second->Models); } Core::PipelineManager::SetRenderPass(Resources::Light::Pass); diff --git a/Code/OysterGraphics/Render/Resources.cpp b/Code/OysterGraphics/Render/Resources.cpp index 91317114..cced13e9 100644 --- a/Code/OysterGraphics/Render/Resources.cpp +++ b/Code/OysterGraphics/Render/Resources.cpp @@ -366,8 +366,8 @@ namespace Oyster ////---------------- Geometry Pass Setup ---------------------------- #pragma region Animated Pass - Gather::AnimatedPass.Shaders.Pixel = GetShader::Pixel(L"Gather"); - Gather::AnimatedPass.Shaders.Vertex = GetShader::Vertex(L"Gather"); + Gather::AnimatedPass.Shaders.Pixel = GetShader::Pixel(L"AGather"); + Gather::AnimatedPass.Shaders.Vertex = GetShader::Vertex(L"AGather"); D3D11_INPUT_ELEMENT_DESC AnimInDesc[] = { @@ -378,7 +378,7 @@ namespace Oyster { "BONEWEIGHT", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 48, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; - Shader::CreateInputLayout(AnimInDesc,5,GetShader::Vertex(L"Gather"),Gather::AnimatedPass.IAStage.Layout); + Shader::CreateInputLayout(AnimInDesc,5,GetShader::Vertex(L"AGather"),Gather::AnimatedPass.IAStage.Layout); Gather::AnimatedPass.IAStage.Topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; Gather::AnimatedPass.CBuffers.Vertex.push_back(Gather::AnimationData); Gather::AnimatedPass.CBuffers.Vertex.push_back(Gather::ModelData); @@ -525,9 +525,6 @@ namespace Oyster Shader::CreateInputLayout(InstInDesc,15,GetShader::Vertex(L"IGather"),Gather::InstancedPass.IAStage.Layout); Gather::InstancedPass.IAStage.Topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - Gather::InstancedPass.CBuffers.Vertex.push_back(Gather::AnimationData); - Gather::InstancedPass.CBuffers.Vertex.push_back(Gather::ModelData); - Gather::InstancedPass.CBuffers.Pixel.push_back(Color); Gather::InstancedPass.RenderStates.Rasterizer = RenderStates::rs; Gather::InstancedPass.RenderStates.SampleCount = 1; Gather::InstancedPass.RenderStates.SampleState = RenderStates::ss; diff --git a/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli b/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli index adf01e9d..fb125b12 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli +++ b/Code/OysterGraphics/Shader/Passes/Light/Defines.hlsli @@ -25,6 +25,16 @@ cbuffer LightConstants : register(b0) float4x4 View; } +struct FrustrumPoints +{ + float3 v0; + float3 v1; + float3 v2; + float3 v3; + float3 v4; + float3 v5; +}; + Texture2D DiffuseGlow : register(t0); Texture2D NormalSpec : register(t1); Texture2D GUI : register(t2); diff --git a/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli b/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli index 3dc2b45e..81fa2fa1 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli +++ b/Code/OysterGraphics/Shader/Passes/Light/LightCalc.hlsli @@ -27,4 +27,9 @@ DiffSpec LightCalc(PointLight pl, float3 pos, int2 texCoord) float SpecCo = normalSpec.w < 1 ? 0.0f : 1.0f; output.Specular = output.Specular * SpecCo; return output; +} + +bool intersects(FrustrumPoints box, int Index) +{ + return true; } \ No newline at end of file diff --git a/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl b/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl index 89ed06d3..ddaed99e 100644 --- a/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl +++ b/Code/OysterGraphics/Shader/Passes/Light/LightPass.hlsl @@ -8,13 +8,85 @@ //Calc Ambience Done //Write Glow +#define EXPAND 1024.0f +#define SHRINK 1.0f/EXPAND +#define UINT_MAX 0xFFFFFFFF +#define FLOAT_MAX 3.402823466e+38 +#define BLOCKSIZE 16 +#define NUMTHREADS BLOCKSIZE * BLOCKSIZE +#define MAXLIGHTS 100 -[numthreads(16, 16, 1)] -void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID ) + +// -- Shared Memory ------------------------------------------------- // + +groupshared uint iMinDepth = UINT_MAX, + iMaxDepth = 0; +groupshared uint numVisiblePointLights = 0, + visiblePointlightIndex[MAXLIGHTS]; + +// ------------------------------------------------------------------ // + +[numthreads(BLOCKSIZE, BLOCKSIZE, 1)] +void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint3 Gid : SV_GroupID, uint GI : SV_GroupIndex ) { float2 UV = DTid.xy / Pixels; UV.x = UV.x * 2 - 1; UV.y = 1 - 2 * UV.y; + + float3 posN = float3(UV, DepthTexture[DTid.xy].x); + + // store and load shared minDepth and maxDepth + float minDepth = 0.0f, maxDepth = 0.0f, + depth = posN.z; + { + uint uidepth = (uint)( depth * EXPAND); + InterlockedMin( iMinDepth, uidepth ); + InterlockedMax( iMaxDepth, uidepth ); + + GroupMemoryBarrierWithGroupSync(); + minDepth = (float)( iMinDepth ) * SHRINK; + maxDepth = (float)( iMaxDepth ) * SHRINK; + } + + + // -- Switching to LightCulling ------------------------------------- // + + //define collision volume + float2 size = BLOCKSIZE / Pixels; + FrustrumPoints tile; + tile.v0 = float3(size * Gid,minDepth); + tile.v1 = float3(tile.v0.xy+size,maxDepth); + tile.v2 = float3(tile.v1.xy, minDepth); + tile.v3 = float3(tile.v0.x,tile.v1.y,minDepth); + tile.v4 = float3(tile.v1.x, tile.v0.y, minDepth); + tile.v5 = float3(tile.v0.xy, maxDepth); + + + + // culling the tile's near and far to minDepth & maxDepth ( with tolerance ) + + + uint numPass = (Lights + NUMTHREADS - 1) / NUMTHREADS; + numPass = min( numPass, MAXLIGHTS / NUMTHREADS ); + + for( uint passI = 0; passI < numPass; ++passI ) + { + uint lightIndex = (passI * NUMTHREADS) + GI; + lightIndex = min( lightIndex, Lights ); + + if( lightIndex < Lights ) + if( intersects(tile, lightIndex) ) + { + uint offset; + InterlockedAdd( numVisiblePointLights, 1, offset ); + visiblePointlightIndex[offset] = lightIndex; + } + } + + GroupMemoryBarrierWithGroupSync(); + + + float3 ViewPos = ToVpos(DTid.xy, UV); DiffSpec Shaded; Shaded.Diffuse = float3(0,0,0); @@ -47,7 +119,7 @@ void main( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID ) DepthBase = DepthBase /4; Ambient[DTid.xy/2] = float4(DiffBase.xyz, AmbValue); Ambient[DTid.xy/2 + float2(Pixels.x/2, 0)] = GUI[DTid.xy]; - Ambient[DTid.xy/2 + float2(0, Pixels.y/2)] = float4(DiffBase.xyz * DiffBase.w /* * (2-DepthBase) */,DiffBase.w); + Ambient[DTid.xy/2 + float2(0, Pixels.y/2)] = float4(DiffBase.xyz * DiffBase.w ,DiffBase.w); Ambient[DTid.xy/2 + Pixels/2] = float4(NormalSpec[DTid.xy].xyz * float3(1,1,-1),1); } From bc17a9f09ee3f2bc61b1ab7d367a40768c22379f Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Tue, 25 Feb 2014 10:37:33 +0100 Subject: [PATCH 2/3] merge --- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 2 + Code/Game/GameLogic/CollisionManager.cpp | 67 ++++++++++++++++++- Code/Game/GameLogic/DynamicObject.cpp | 26 +++++++ Code/Game/GameLogic/DynamicObject.h | 9 +++ Code/Game/GameLogic/GameLogicStates.h | 3 + Code/Game/GameLogic/Level.cpp | 10 +-- Code/Game/GameLogic/Player.cpp | 47 ++++++++++--- Code/Game/GameLogic/Player.h | 7 ++ 8 files changed, 156 insertions(+), 15 deletions(-) diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index b988451f..c6b0df0a 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -99,6 +99,7 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float forcePushData args; args.pushForce = pushForce; + args.p = this->owner; Oyster::Physics::API::Instance().ApplyEffect(hitCone,&args,ForcePushAction); @@ -136,6 +137,7 @@ void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt) Oyster::Collision3D::Cone *hitCone = new Oyster::Collision3D::Cone(lenght,pos,(Oyster::Math::Float4)owner->GetRigidBody()->GetState().quaternion,radius); forcePushData args; args.pushForce = -pushForce; + args.p = this->owner; Oyster::Physics::API::Instance().ApplyEffect(hitCone,&args,ForcePushAction); diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 90a2aefe..8a360059 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -113,7 +113,7 @@ using namespace GameLogic; Object *realObjA = ((Object*)(objA->GetCustomTag())); - Object *realObjB = (Object*)objB->GetCustomTag(); //needs to be changed? + Object *realObjB = (Object*)objB->GetCustomTag(); ExplosiveCrate* crate; if(!realObjA) @@ -166,9 +166,13 @@ using namespace GameLogic; Player *hitPlayer = (Player*)realObj; hitPlayer->DamageLife(ExplosionSource->extraDamageOnCollision); //hitPlayer->GetRigidBody()->ApplyImpulse(force); + + //hitPlayer->DamageLife(ExplosionSource->getExtraDamageOnCollision()); + realObj->GetRigidBody()->ApplyImpulse(force * 5); //do shredding damage } + } @@ -226,6 +230,58 @@ using namespace GameLogic; { return Physics::ICustomBody::SubscriptMessage_none; } + + void DynamicObject::DynamicDefaultOnCollision(Oyster::Physics::ICustomBody *objA, Oyster::Physics::ICustomBody *objB, Oyster::Math::Float kineticEnergyLoss) + { + + DynamicObject *realObjA = dynamic_cast((Object*)objA->GetCustomTag()); + + DynamicObject *realObjB = dynamic_cast((Object*)objB->GetCustomTag()); + + if(!realObjA || !realObjB) // one of the objects cannot be cast into a dynamicObject and so we leave the function + { + return; + } + + //check which obj is the one that is already affected, if both are then use the special case of changing ownership. + if(realObjA->getAffectingPlayer() == NULL && realObjB->getAffectingPlayer() == NULL) //None of the objects have a player affecting them + { + return;//leave function as the are not to transfer any ownership + } + + if(realObjA->getAffectingPlayer() != NULL && realObjB->getAffectingPlayer() == NULL) + { + //realobjA is the affectedObject, transfer this to realobjB + realObjB->SetAffectedBy(*realObjA->getAffectingPlayer()); + + } + if(realObjB->getAffectingPlayer() != NULL && realObjA->getAffectingPlayer() == NULL) + { + //realobjB is the affectedObject, transfer this to realobjA + realObjA->SetAffectedBy(*realObjB->getAffectingPlayer()); + + } + + if(realObjA->getAffectingPlayer() != NULL && realObjB->getAffectingPlayer() != NULL) + { + //Both objects have a player affecting them, now use the special case + if(realObjA->GetRigidBody()->GetState().previousVelocity.GetMagnitude() > realObjB->GetRigidBody()->GetState().previousVelocity.GetMagnitude() ) + { + //realObjA is the winner and will change Bs ownership to A + realObjB->SetAffectedBy(*realObjA->getAffectingPlayer()); + } + else + { + realObjA->SetAffectedBy(*realObjB->getAffectingPlayer()); + //realObjB is the winner and will change As ownership to B + } + } + + + + + } + Oyster::Physics::ICustomBody::SubscriptMessage Player::PlayerCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss) { return Physics::ICustomBody::SubscriptMessage_none; @@ -250,7 +306,16 @@ using namespace GameLogic; if(realObj->GetObjectType() == ObjectSpecialType::ObjectSpecialType_Player || realObj->GetObjectType() == ObjectSpecialType::ObjectSpecialType_World) return; + + obj->ApplyImpulse(((forcePushData*)(args))->pushForce); + + DynamicObject *dynamicObj = dynamic_cast(realObj); + + if(dynamicObj) + { + dynamicObj->SetAffectedBy(*((forcePushData*)(args))->p); + } } void AttatchmentMassDriver::AttemptPickUp(Oyster::Physics::ICustomBody *obj, void* args) diff --git a/Code/Game/GameLogic/DynamicObject.cpp b/Code/Game/GameLogic/DynamicObject.cpp index e6d9ff49..961d29fc 100644 --- a/Code/Game/GameLogic/DynamicObject.cpp +++ b/Code/Game/GameLogic/DynamicObject.cpp @@ -1,5 +1,6 @@ #include "DynamicObject.h" #include "CollisionManager.h" +#include "Player.h" using namespace GameLogic; using namespace Oyster::Math; @@ -10,6 +11,7 @@ DynamicObject::DynamicObject() { this->isReleased = false; this->isActive = true; + this->affectedBy = NULL; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID) @@ -17,12 +19,14 @@ DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*Ev { this->isReleased = false; this->isActive = true; + this->affectedBy = NULL; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID) :Object(rigidBody, EventOnCollision, type, objectID) { this->isReleased = false; this->isActive = true; + this->affectedBy = NULL; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision) @@ -31,6 +35,7 @@ DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*Ev this->extraDamageOnCollision = extraDamageOnCollision; this->isReleased = false; this->isActive = true; + this->affectedBy = NULL; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision) @@ -39,6 +44,7 @@ DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::P this->extraDamageOnCollision = extraDamageOnCollision; this->isReleased = false; this->isActive = true; + this->affectedBy = NULL; } DynamicObject::~DynamicObject(void) { @@ -74,4 +80,24 @@ void DynamicObject::Activate() { this->isActive = true; this->isReleased = false; +} + +void DynamicObject::SetAffectedBy(Player &player) +{ + this->affectedBy = &player; + if(this->type != ObjectSpecialType::ObjectSpecialType_Player) //should not add itself to its own list if its a player + { + player.AddAffectedObject(*this); + } + +} + +Player* DynamicObject::getAffectingPlayer() +{ + return this->affectedBy; +} + +void DynamicObject::RemoveAffectedBy() +{ + this->affectedBy = NULL; } \ No newline at end of file diff --git a/Code/Game/GameLogic/DynamicObject.h b/Code/Game/GameLogic/DynamicObject.h index 8a32e849..d1bb63bc 100644 --- a/Code/Game/GameLogic/DynamicObject.h +++ b/Code/Game/GameLogic/DynamicObject.h @@ -9,6 +9,7 @@ namespace GameLogic { + class Player; class DynamicObject : public Object { @@ -28,9 +29,17 @@ namespace GameLogic void Inactivate(); void Activate(); + void SetAffectedBy(GameLogic::Player &player); + void RemoveAffectedBy(); + GameLogic::Player* getAffectingPlayer(); + + static void DynamicObject::DynamicDefaultOnCollision(Oyster::Physics::ICustomBody *rigidBodyObject, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); + private: bool isActive; bool isReleased; + protected: + GameLogic::Player *affectedBy; }; diff --git a/Code/Game/GameLogic/GameLogicStates.h b/Code/Game/GameLogic/GameLogicStates.h index 9ae0d482..ae4e192f 100644 --- a/Code/Game/GameLogic/GameLogicStates.h +++ b/Code/Game/GameLogic/GameLogicStates.h @@ -2,8 +2,10 @@ #define GAMELOGICSTATES_H #include "OysterMath.h" + namespace GameLogic { + class Player; enum PLAYER_MOVEMENT { PLAYER_MOVEMENT_FORWARD = 0, @@ -41,6 +43,7 @@ namespace GameLogic struct forcePushData { Oyster::Math::Float3 pushForce; + Player *p; }; diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index 922d2a8f..a4252bc4 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -59,12 +59,12 @@ Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody) break; case ObjectSpecialType_Stone: { - gameObj = new DynamicObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); + gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); } break; case ObjectSpecialType_StandardBox: { - gameObj = new DynamicObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); + gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); } break; case ObjectSpecialType_RedExplosiveBox: @@ -81,12 +81,12 @@ Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody) // break; case ObjectSpecialType_SpikeBox: { - gameObj = new DynamicObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); + gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); } break; case ObjectSpecialType_Spike: { - gameObj = new DynamicObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); + gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); } break; case ObjectSpecialType_CrystalFormation: @@ -98,7 +98,7 @@ Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody) break; case ObjectSpecialType_CrystalShard: { - gameObj = new DynamicObject(rigidBody, Object::DefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); + gameObj = new DynamicObject(rigidBody, DynamicObject::DynamicDefaultOnCollision, (ObjectSpecialType)obj->specialTypeID, objID); } break; case ObjectSpecialType_JumpPad: diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 69569d44..4dcdacaa 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -18,6 +18,8 @@ Player::Player(Oyster::Physics::ICustomBody *rigidBody, void (*EventOnCollision) :DynamicObject(rigidBody, EventOnCollision, type, objectID) { weapon = new Weapon(2,this); + AffectedObjects.Reserve(15); + this->life = 100; this->teamID = teamID; @@ -46,6 +48,9 @@ Player::Player(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustom { weapon = new Weapon(2,this); + AffectedObjects.Reserve(15); + + this->life = 100; this->teamID = teamID; this->playerState = PLAYER_STATE_IDLE; @@ -213,6 +218,16 @@ void Player::BeginFrame() void Player::EndFrame() { + //check if there are any objects that can be removed from the AffectedObjects list + for(int i = 0; i < this->AffectedObjects.Size(); i++) + { + if((this->AffectedObjects[i]->GetRigidBody()->GetState().previousVelocity).GetMagnitude() <= 0.1f) + { + this->AffectedObjects[i]->RemoveAffectedBy(); + this->AffectedObjects.Remove(i); + } + + } } @@ -334,17 +349,31 @@ PLAYER_STATE Player::GetState() const void Player::DamageLife(int damage) { - if( this->playerState != PLAYER_STATE_DEAD) - { - this->life -= damage; - this->gameInstance->onDamageTakenFnc( this, this->life); - if(this->life <= 0) + this->life -= damage; + this->gameInstance->onDamageTakenFnc( this, this->life); + + if(this->life <= 0) + { + this->life = 0; + playerState = PLAYER_STATE_DEAD; + this->deathTimeLeft = this->deathTime; + this->gameInstance->onDeadFnc(this, this->deathTimeLeft); + } + +} + +void Player::AddAffectedObject(DynamicObject &AffectedObject) +{ + //check if object already exists in the list, if so then do not add + for(int i = 0; i < AffectedObjects.Size(); i++) + { + if(AffectedObjects[i]->GetID() == AffectedObject.GetID()) { - this->life = 0; - playerState = PLAYER_STATE_DEAD; - this->deathTimeLeft = this->deathTime; - this->gameInstance->onDeadFnc(this, this->deathTimeLeft); + //object already exists, exit function + return; } } + //else you add the object to the stack + AffectedObjects.Push(&AffectedObject); } diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index 001c9141..99af52c5 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -7,6 +7,7 @@ #include "GameLogicStates.h" #include "OysterMath.h" #include "DynamicObject.h" +#include "DynamicArray.h" namespace GameLogic @@ -49,6 +50,8 @@ namespace GameLogic void SetLookDir(const Oyster::Math3D::Float3& lookDir); void TurnLeft(Oyster::Math3D::Float deltaRadians); + + void AddAffectedObject(DynamicObject &AffectedObject); /******************************************************** * Collision function for player, this is to be sent to physics through the subscribe function with the rigidbody @@ -77,10 +80,14 @@ namespace GameLogic void EndFrame(); static Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); + + private: void Jump(); private: + Utility::DynamicMemory::DynamicArray AffectedObjects; + Oyster::Math::Float life; int teamID; Weapon *weapon; From 8a359bd1baca45e4e2528b0f7aee12dd92361ae5 Mon Sep 17 00:00:00 2001 From: Erik Persson Date: Tue, 25 Feb 2014 11:20:46 +0100 Subject: [PATCH 3/3] GL - only 1 player can manipulate a object at a time --- Code/Game/GameLogic/AttatchmentMassDriver.cpp | 2 +- Code/Game/GameLogic/CollisionManager.cpp | 14 +++++++++++-- Code/Game/GameLogic/DynamicObject.cpp | 20 +++++++++++++++++++ Code/Game/GameLogic/DynamicObject.h | 5 +++++ Code/Game/GameLogic/Player.cpp | 2 +- 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index c6b0df0a..1f86bf60 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -80,7 +80,7 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float { pushForce = Oyster::Math::Float4(this->owner->GetLookDir()) * (800); heldObject->ApplyImpulse((Oyster::Math::Float3)pushForce); - + ((DynamicObject*)(heldObject->GetCustomTag()))->RemoveManipulation(); hasObject = false; heldObject = NULL; return; diff --git a/Code/Game/GameLogic/CollisionManager.cpp b/Code/Game/GameLogic/CollisionManager.cpp index 8a360059..d60d16ce 100644 --- a/Code/Game/GameLogic/CollisionManager.cpp +++ b/Code/Game/GameLogic/CollisionManager.cpp @@ -309,6 +309,7 @@ using namespace GameLogic; obj->ApplyImpulse(((forcePushData*)(args))->pushForce); + DynamicObject *dynamicObj = dynamic_cast(realObj); @@ -333,12 +334,21 @@ using namespace GameLogic; Object* realObj = (Object*)(obj->GetCustomTag()); //check so that it is an object that you can pickup - switch(realObj->GetObjectType()) + DynamicObject *dynamicObj = dynamic_cast(realObj); + + if(!dynamicObj) return; + + if(dynamicObj->getManipulatingPlayer() != NULL) + { + return; + } + + switch(dynamicObj->GetObjectType()) { case ObjectSpecialType::ObjectSpecialType_StandardBox: weapon->heldObject = obj; //weapon now holds the object weapon->hasObject = true; - + dynamicObj->SetManipulatingPlayer(*weapon->owner); //TODO: add if this is to be a struggle of who has the most power in its weapon, the player that is already manipulating the object or you. if you then you take the object from the other player, if not then you do not take the object break; } diff --git a/Code/Game/GameLogic/DynamicObject.cpp b/Code/Game/GameLogic/DynamicObject.cpp index 961d29fc..844deaf2 100644 --- a/Code/Game/GameLogic/DynamicObject.cpp +++ b/Code/Game/GameLogic/DynamicObject.cpp @@ -12,6 +12,7 @@ DynamicObject::DynamicObject() this->isReleased = false; this->isActive = true; this->affectedBy = NULL; + this->manipulatedBy = NULL; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID) @@ -20,6 +21,7 @@ DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*Ev this->isReleased = false; this->isActive = true; this->affectedBy = NULL; + this->manipulatedBy = NULL; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID) :Object(rigidBody, EventOnCollision, type, objectID) @@ -27,6 +29,7 @@ DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::P this->isReleased = false; this->isActive = true; this->affectedBy = NULL; + this->manipulatedBy = NULL; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision) @@ -36,6 +39,7 @@ DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*Ev this->isReleased = false; this->isActive = true; this->affectedBy = NULL; + this->manipulatedBy = NULL; } DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, Oyster::Math::Float extraDamageOnCollision) @@ -45,6 +49,7 @@ DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::P this->isReleased = false; this->isActive = true; this->affectedBy = NULL; + this->manipulatedBy = NULL; } DynamicObject::~DynamicObject(void) { @@ -100,4 +105,19 @@ Player* DynamicObject::getAffectingPlayer() void DynamicObject::RemoveAffectedBy() { this->affectedBy = NULL; +} + +GameLogic::Player* DynamicObject::getManipulatingPlayer() +{ + return this->manipulatedBy; +} + +void DynamicObject::SetManipulatingPlayer(GameLogic::Player &player) +{ + this->manipulatedBy = &player; +} + +void DynamicObject::RemoveManipulation() +{ + this->manipulatedBy = NULL; } \ No newline at end of file diff --git a/Code/Game/GameLogic/DynamicObject.h b/Code/Game/GameLogic/DynamicObject.h index d1bb63bc..03a03ad6 100644 --- a/Code/Game/GameLogic/DynamicObject.h +++ b/Code/Game/GameLogic/DynamicObject.h @@ -30,8 +30,11 @@ namespace GameLogic void Activate(); void SetAffectedBy(GameLogic::Player &player); + void SetManipulatingPlayer(GameLogic::Player &player); void RemoveAffectedBy(); + void RemoveManipulation(); GameLogic::Player* getAffectingPlayer(); + GameLogic::Player* getManipulatingPlayer(); static void DynamicObject::DynamicDefaultOnCollision(Oyster::Physics::ICustomBody *rigidBodyObject, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); @@ -40,6 +43,8 @@ namespace GameLogic bool isReleased; protected: GameLogic::Player *affectedBy; + GameLogic::Player *manipulatedBy; + }; diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 4dcdacaa..d8ba38ba 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -221,7 +221,7 @@ void Player::EndFrame() //check if there are any objects that can be removed from the AffectedObjects list for(int i = 0; i < this->AffectedObjects.Size(); i++) { - if((this->AffectedObjects[i]->GetRigidBody()->GetState().previousVelocity).GetMagnitude() <= 0.1f) + if(this->AffectedObjects[i] && (this->AffectedObjects[i]->GetRigidBody()->GetState().previousVelocity).GetMagnitude() <= 0.1f) { this->AffectedObjects[i]->RemoveAffectedBy(); this->AffectedObjects.Remove(i);