Merge with affectedByTag. Sending killer ID

This commit is contained in:
Linda Andersson 2014-02-25 12:12:24 +01:00
commit f56323ee01
20 changed files with 328 additions and 58 deletions

View File

@ -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();
}
@ -591,6 +591,8 @@ const GameClientState::NetEvent & GameState::DataRecieved( const GameClientState
{
Protocol_ObjectDie decoded(data);
// if is this player. Remember to change camera
int killerID = decoded.killerID;
int victimID = decoded.objectID;
if( this->privData->myId == decoded.objectID )
{
this->currGameUI = this->respawnUI;

View File

@ -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;
@ -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);

View File

@ -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,11 +166,15 @@ 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
}
}
void PlayerVObject(Player &player, Object &obj, Oyster::Math::Float kineticEnergyLoss)
@ -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<DynamicObject*>((Object*)objA->GetCustomTag());
DynamicObject *realObjB = dynamic_cast<DynamicObject*>((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,17 @@ using namespace GameLogic;
if(realObj->GetObjectType() == ObjectSpecialType::ObjectSpecialType_Player || realObj->GetObjectType() == ObjectSpecialType::ObjectSpecialType_World)
return;
obj->ApplyImpulse(((forcePushData*)(args))->pushForce);
DynamicObject *dynamicObj = dynamic_cast<DynamicObject*>(realObj);
if(dynamicObj)
{
dynamicObj->SetAffectedBy(*((forcePushData*)(args))->p);
}
}
void AttatchmentMassDriver::AttemptPickUp(Oyster::Physics::ICustomBody *obj, void* args)
@ -268,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<DynamicObject*>(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;
}

View File

@ -1,5 +1,6 @@
#include "DynamicObject.h"
#include "CollisionManager.h"
#include "Player.h"
using namespace GameLogic;
using namespace Oyster::Math;
@ -10,6 +11,8 @@ 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)
@ -17,12 +20,16 @@ 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)
{
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)
@ -31,6 +38,8 @@ DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , void (*Ev
this->extraDamageOnCollision = extraDamageOnCollision;
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)
@ -39,6 +48,8 @@ DynamicObject::DynamicObject(Oyster::Physics::ICustomBody *rigidBody , Oyster::P
this->extraDamageOnCollision = extraDamageOnCollision;
this->isReleased = false;
this->isActive = true;
this->affectedBy = NULL;
this->manipulatedBy = NULL;
}
DynamicObject::~DynamicObject(void)
{
@ -75,3 +86,38 @@ 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;
}
GameLogic::Player* DynamicObject::getManipulatingPlayer()
{
return this->manipulatedBy;
}
void DynamicObject::SetManipulatingPlayer(GameLogic::Player &player)
{
this->manipulatedBy = &player;
}
void DynamicObject::RemoveManipulation()
{
this->manipulatedBy = NULL;
}

View File

@ -9,6 +9,7 @@
namespace GameLogic
{
class Player;
class DynamicObject : public Object
{
@ -28,9 +29,22 @@ namespace GameLogic
void Inactivate();
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);
private:
bool isActive;
bool isReleased;
protected:
GameLogic::Player *affectedBy;
GameLogic::Player *manipulatedBy;
};

View File

@ -29,7 +29,7 @@ namespace GameLogic
typedef void(*ObjectDisabledFunction)(IObjectData* object, float seconds); // Callback method that recieves and object
typedef void(*ObjectHpFunction)(IObjectData* object, float hp); // Callback method that sends obj HP
typedef void(*ObjectRespawnedFunction)(IObjectData* object, Oyster::Math::Float3 spawnPos ); // Callback method that sends spawnPos
typedef void(*ObjectDeadFunction)(IObjectData* object, float seconds); // Callback method that sends death timer
typedef void(*ObjectDeadFunction)(IObjectData* victim, IObjectData* killer, float seconds); // Callback method that sends killer and death timer
//etc...
};

View File

@ -2,8 +2,10 @@
#define GAMELOGICSTATES_H
#include "OysterMath.h"
namespace GameLogic
{
class Player;
enum PLAYER_MOVEMENT
{
PLAYER_MOVEMENT_FORWARD = 0,
@ -42,6 +44,7 @@ namespace GameLogic
struct forcePushData
{
Oyster::Math::Float3 pushForce;
Player *p;
};

View File

@ -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:
@ -433,7 +433,9 @@ void Level::Update(float deltaTime)
else if (this->playerObjects[i]->GetState() == PLAYER_STATE::PLAYER_STATE_DIED)
{
this->playerObjects[i]->setDeathTimer(DEATH_TIMER);
((Game*)&Game::Instance())->onDeadFnc(this->playerObjects[i], DEATH_TIMER); // add killer ID
// HACK to avoid crasch. affected by tag is NULL
((Game*)&Game::Instance())->onDeadFnc(this->playerObjects[i], this->playerObjects[i], DEATH_TIMER); // add killer ID
//((Game*)&Game::Instance())->onDeadFnc(this->playerObjects[i], this->playerObjects[i]->getAffectingPlayer(), DEATH_TIMER); // add killer ID
}
}
}

View File

@ -12,24 +12,26 @@ Player::Player()
:DynamicObject()
{
Player::initPlayerData();
AffectedObjects.Reserve(15);
this->weapon = NULL;
this->teamID = -1;
}
Player::Player(Oyster::Physics::ICustomBody *rigidBody, void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID)
:DynamicObject(rigidBody, EventOnCollision, type, objectID)
{
weapon = new Weapon(2,this);
this->weapon = new Weapon(2,this);
Player::initPlayerData();
AffectedObjects.Reserve(15);
this->teamID = teamID;
}
Player::Player(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID)
:DynamicObject(rigidBody, EventOnCollision, type, objectID)
{
weapon = new Weapon(2,this);
this->weapon = new Weapon(2,this);
Player::initPlayerData();
AffectedObjects.Reserve(15);
this->teamID = teamID;
}
@ -189,6 +191,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] && (this->AffectedObjects[i]->GetRigidBody()->GetState().previousVelocity).GetMagnitude() <= 0.1f)
{
this->AffectedObjects[i]->RemoveAffectedBy();
this->AffectedObjects.Remove(i);
}
}
}
void Player::Move(const PLAYER_MOVEMENT &movement)
@ -306,8 +318,6 @@ PLAYER_STATE Player::GetState() const
}
void Player::DamageLife(int damage)
{
if( this->playerState != PLAYER_STATE_DEAD)
{
this->playerStats.hp -= damage;
// send hp to client
@ -318,7 +328,22 @@ void Player::DamageLife(int damage)
this->playerStats.hp = 0;
this->playerState = PLAYER_STATE_DIED;
}
}
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())
{
//object already exists, exit function
return;
}
}
//else you add the object to the stack
AffectedObjects.Push(&AffectedObject);
}
bool Player::deathTimerTick(float dt)
{

View File

@ -7,6 +7,7 @@
#include "GameLogicStates.h"
#include "OysterMath.h"
#include "DynamicObject.h"
#include "DynamicArray.h"
const float MAX_HP = 100.0f;
const float BASIC_SPEED = 30.0f;
@ -67,6 +68,8 @@ namespace GameLogic
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
* Will be called when the physics detect a collision
@ -95,12 +98,14 @@ namespace GameLogic
void BeginFrame();
void EndFrame();
static Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
private:
void Jump();
void initPlayerData();
private:
Utility::DynamicMemory::DynamicArray<DynamicObject*> AffectedObjects;
int teamID;
Weapon *weapon;
PLAYER_STATE playerState;

View File

@ -868,6 +868,7 @@ namespace GameLogic
struct Protocol_ObjectDie :public Oyster::Network::CustomProtocolObject
{
int objectID;
int killerID;
float seconds;
Protocol_ObjectDie()
@ -875,28 +876,34 @@ namespace GameLogic
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[0].value.netShort = protocol_Gameplay_ObjectDie;
this->protocol[1].type = Oyster::Network::NetAttributeType_Int;
this->protocol[2].type = Oyster::Network::NetAttributeType_Float;
this->objectID = 0;
this->protocol[2].type = Oyster::Network::NetAttributeType_Int;
this->protocol[3].type = Oyster::Network::NetAttributeType_Float;
this->objectID = -1;
this->killerID = -1;
this->seconds = 0.0f;
}
Protocol_ObjectDie(int objectID, float seconds)
Protocol_ObjectDie(int objectID, int killerID, float seconds)
{
this->protocol[0].type = Oyster::Network::NetAttributeType_Short;
this->protocol[0].value.netShort = protocol_Gameplay_ObjectDie;
this->protocol[1].type = Oyster::Network::NetAttributeType_Int;
this->protocol[2].type = Oyster::Network::NetAttributeType_Float;
this->protocol[2].type = Oyster::Network::NetAttributeType_Int;
this->protocol[3].type = Oyster::Network::NetAttributeType_Float;
this->objectID = objectID;
this->killerID = killerID;
this->seconds = seconds;
}
Protocol_ObjectDie(Oyster::Network::CustomNetProtocol& p)
{
this->objectID = p[1].value.netInt;
this->seconds = p[2].value.netFloat;
this->killerID = p[2].value.netInt;
this->seconds = p[3].value.netFloat;
}
Oyster::Network::CustomNetProtocol GetProtocol() override
{
this->protocol[1].value = this->objectID;
this->protocol[2].value = this->seconds;
this->protocol[2].value = this->killerID;
this->protocol[3].value = this->seconds;
return protocol;
}

View File

@ -96,12 +96,12 @@ namespace DanBias
void General_Status ( GameLogic::Protocol_General_Status& p, DanBias::GameClient* c );
void General_Text ( GameLogic::Protocol_General_Text& p, DanBias::GameClient* c );
//Callback method recieving from gamelogic
//Callback method receiving from game logic
static void ObjectMove ( GameLogic::IObjectData* movedObject );
static void ObjectDisabled ( GameLogic::IObjectData* movedObject, float seconds );
static void ObjectDamaged ( GameLogic::IObjectData* movedObject, float hp );
static void ObjectRespawned ( GameLogic::IObjectData* movedObject, Oyster::Math::Float3 spawnPos );
static void ObjectDead ( GameLogic::IObjectData* movedObject, float seconds );
static void ObjectDead ( GameLogic::IObjectData* victim, GameLogic::IObjectData* killer, float seconds );
//Private member variables
private:

View File

@ -158,9 +158,9 @@ using namespace DanBias;
{
GameSession::gameSession->Send(Protocol_ObjectRespawn(movedObject->GetID(), spawnPos).GetProtocol());
}
void GameSession::ObjectDead( GameLogic::IObjectData* movedObject, float seconds )
void GameSession::ObjectDead( GameLogic::IObjectData* victim, GameLogic::IObjectData* killer, float seconds )
{
GameSession::gameSession->Send(Protocol_ObjectDie(movedObject->GetID(), seconds).GetProtocol());
GameSession::gameSession->Send(Protocol_ObjectDie(victim->GetID(), killer->GetID(), seconds).GetProtocol());
}
//*****************************************************//
//****************** Protocol methods *****************//

View File

@ -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)

View File

@ -26,6 +26,7 @@ namespace Oyster
Oyster::Math::Float3 Tint;
Oyster::Math::Float3 GlowTint;
bool Visible;
bool Instanced;
AnimationData Animation;
};
}

View File

@ -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]));
@ -262,12 +266,9 @@ namespace Oyster
Resources::Gather::InstancedData.Apply(1);
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);
}
}
Core::PipelineManager::SetRenderPass(Resources::Light::Pass);

View File

@ -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;

View File

@ -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);

View File

@ -28,3 +28,8 @@ DiffSpec LightCalc(PointLight pl, float3 pos, int2 texCoord)
output.Specular = output.Specular * SpecCo;
return output;
}
bool intersects(FrustrumPoints box, int Index)
{
return true;
}

View File

@ -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);
}