Compare commits
84 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2381f01d12 | |||
| 70cab9ef30 | |||
| f1a54a89b3 | |||
| 60037c2849 | |||
| cd67253173 | |||
| a596b8746b | |||
| 35876f6425 | |||
| f6ce98249e | |||
| 00588b07c5 | |||
| 3376f4a16e | |||
| 25d2aa3464 | |||
| 29aefc5af2 | |||
| 39ae83efd4 | |||
| 8189e3c00c | |||
| 4d01cdf895 | |||
| 7e7ca7edcf | |||
| e9a576341e | |||
| f52cddb445 | |||
| 85523343b2 | |||
| 410e349329 | |||
| b45de542da | |||
| dfa96f74e1 | |||
| 5d6d0f82b9 | |||
| a124ab2400 | |||
| d2263b0c90 | |||
| a8ffb24040 | |||
| 893ef38237 | |||
| f197993beb | |||
| ad9bb5fba4 | |||
| 982837052a | |||
| e0c4394f20 | |||
| 4cafb2fc4c | |||
| 46e17b7e0d | |||
| 3142c701e3 | |||
| a6425160fd | |||
| 88eb3ca2db | |||
| 3e90ed564c | |||
| 4b29d48f27 | |||
| 14b1d541dc | |||
| 765509b510 | |||
| 8952c1a7e4 | |||
| fc305f8bf4 | |||
| 62c3f72355 | |||
| 70cbb02cb2 | |||
| 0c7f2c5198 | |||
| d7780d8248 | |||
| 601ce85c05 | |||
| 4c1a49a8a4 | |||
| 01a164847c | |||
| 794635b6a1 | |||
| 0a3b6f4da1 | |||
| e0410d4345 | |||
| 6f1fd19ac7 | |||
| 6680f6863f | |||
| 4092f6b4d4 | |||
| 6ba6deb863 | |||
| cc604f8e9a | |||
| e97f4a3563 | |||
| d995713d3b | |||
| db62d767ac | |||
| e7da11fda4 | |||
| 8f257b9a58 | |||
| c8fe6853c0 | |||
| 76a8b43ca3 | |||
| 0bf756dc08 | |||
| 696f44a673 | |||
| 5e9a3774ab | |||
| db18a45368 | |||
| a060640da3 | |||
| b8a41b7c13 | |||
| 9533920684 | |||
| f47f913bf5 | |||
| ed5ac2e923 | |||
| 7a8604bf2b | |||
| 3a1056a2c3 | |||
| 59be714fdc | |||
| 147b116f20 | |||
| f0b425614d | |||
| 4b672b11e7 | |||
| e865971fdd | |||
| 878c71b56a | |||
| ec4d5fbfa8 | |||
| 184af95507 | |||
| 7ae42a5bf7 |
+1
-1
Submodule assets updated: a3c92ac876...6ffb46e155
@@ -61,6 +61,7 @@ public:
|
||||
|
||||
iterator begin() const;
|
||||
iterator end() const;
|
||||
size_t size() const;
|
||||
|
||||
//Dumps information about what the pool memory looks like right now
|
||||
//into an output stream (e.g. file/std::cout, anything that has an operator<<)
|
||||
|
||||
@@ -91,7 +91,7 @@ public:
|
||||
void AddProperty(std::string fieldName, T defaultValue)
|
||||
{
|
||||
m_DefaultValues.push_back(defaultValue);
|
||||
m_ComponentInfo.Fields[fieldName].Name = typeid(T).name();
|
||||
m_ComponentInfo.Fields[fieldName].Type = typeid(T).name();
|
||||
m_ComponentInfo.Fields[fieldName].Offset = m_ComponentInfo.Stride;
|
||||
m_ComponentInfo.Fields[fieldName].Stride = sizeof(T);
|
||||
m_ComponentInfo.Stride += sizeof(T);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef ECaptured_h__
|
||||
#define ECaptured_h__
|
||||
|
||||
#include "EventBroker.h"
|
||||
#include "../Core/Entity.h"
|
||||
#include "Engine/GLM.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
//triggers when a capturePoint has been taken over
|
||||
struct Captured : Event
|
||||
{
|
||||
int TeamNumberThatCapturedCapturePoint;
|
||||
EntityID CapturePointID;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef EWin_h__
|
||||
#define EWin_h__
|
||||
|
||||
#include "EventBroker.h"
|
||||
#include "../Core/Entity.h"
|
||||
#include "Engine/GLM.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
//triggers when a team has captured all capturePoints
|
||||
struct Win : Event
|
||||
{
|
||||
//can be 0 = none, 1,2
|
||||
int TeamThatWon;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3,9 +3,12 @@
|
||||
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
#include <limits>
|
||||
#include <queue>
|
||||
|
||||
#include <glm/common.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/shared_array.hpp>
|
||||
|
||||
#include "Network/Network.h"
|
||||
#include "Network/MessageType.h"
|
||||
@@ -15,6 +18,8 @@
|
||||
#include "Core/EventBroker.h"
|
||||
#include "Core/ConfigFile.h"
|
||||
#include "Input/EInputCommand.h"
|
||||
#include "Core/EPlayerDamage.h"
|
||||
#include "Network/EInterpolate.h"
|
||||
|
||||
class Client : public Network
|
||||
{
|
||||
@@ -32,8 +37,6 @@ private:
|
||||
// Sending message to server logic
|
||||
int bytesRead = -1;
|
||||
char readBuf[INPUTSIZE] = { 0 };
|
||||
int snapshotInterval = 33;
|
||||
std::clock_t previousSnapshotMessage = std::clock();
|
||||
|
||||
// Packet loss logic
|
||||
unsigned int m_PacketID = 0;
|
||||
@@ -44,40 +47,55 @@ private:
|
||||
World* m_World;
|
||||
std::string m_PlayerName;
|
||||
int m_PlayerID = -1;
|
||||
EntityID m_ServerEntityID = std::numeric_limits<EntityID>::max();
|
||||
bool m_IsConnected = false;
|
||||
// Server Client Lookup map
|
||||
// Assumes that root node for client and server is EntityID 0.
|
||||
|
||||
// Don't Add items to these two maps with insert, use insertIntoServerClientMaps(EntityID, EntityID)!!!!
|
||||
std::unordered_map<EntityID, EntityID> m_ServerIDToClientID;
|
||||
std::unordered_map<EntityID, EntityID> m_ClientIDToServerID;
|
||||
|
||||
// Network logic
|
||||
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
|
||||
SnapshotDefinitions m_NextSnapshot;
|
||||
double m_DurationOfPingTime;
|
||||
std::clock_t m_StartPingTime;
|
||||
// Use to check if we should send disconnect message
|
||||
// if game is turned of by closing window.
|
||||
bool m_WasStarted = false;
|
||||
std::vector<Events::InputCommand> m_InputCommandBuffer;
|
||||
|
||||
// Private member functions
|
||||
void readFromServer();
|
||||
void sendSnapshotToServer();
|
||||
int receive(char* data, size_t length);
|
||||
void send(Packet& packet);
|
||||
void connect();
|
||||
void disconnect();
|
||||
void ping();
|
||||
void moveMessageHead(char*& data, size_t& length, size_t stepSize);
|
||||
void parseMessageType(Packet& packet);
|
||||
void parseEventMessage(Packet& packet);
|
||||
void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType);
|
||||
void parseConnect(Packet& packet);
|
||||
void parsePlayerConnected(Packet& packet);
|
||||
void parsePing();
|
||||
void parseServerPing();
|
||||
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
|
||||
void parseSnapshot(Packet& packet);
|
||||
void identifyPacketLoss();
|
||||
bool isConnected();
|
||||
bool hasServerTimedOut();
|
||||
EntityID createPlayer();
|
||||
void sendInputCommands();
|
||||
void becomePlayer();
|
||||
// Mapping Logic
|
||||
// Returns if local EntityID exist in map
|
||||
bool clientServerMapsHasEntity(EntityID clientEntityID);
|
||||
// Returns if server EntityID exist in map
|
||||
bool serverClientMapsHasEntity(EntityID serverEntityID);
|
||||
void insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID);
|
||||
|
||||
// Events
|
||||
EventBroker* m_EventBroker;
|
||||
EventRelay<Client, Events::InputCommand> m_EInputCommand;
|
||||
bool OnInputCommand(const Events::InputCommand &e);
|
||||
bool OnInputCommand(const Events::InputCommand& e);
|
||||
EventRelay<Client, Events::PlayerDamage> m_EPlayeDamage;
|
||||
bool OnPlayerDamage(const Events::PlayerDamage& e);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef Events_Interpolate_h__
|
||||
#define Events_Interpolate_h__
|
||||
|
||||
#include <boost/shared_array.hpp>
|
||||
|
||||
#include "Core/EventBroker.h"
|
||||
#include "Core/Entity.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
struct Interpolate : Event
|
||||
{
|
||||
EntityID Entity;
|
||||
boost::shared_array<char> DataArray;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -11,7 +11,10 @@ enum class MessageType
|
||||
ServerPing,
|
||||
Message,
|
||||
Snapshot,
|
||||
Event,
|
||||
OnInputCommand,
|
||||
OnPlayerDamage,
|
||||
PlayerConnected,
|
||||
BecomePlayer
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#define MAXCONNECTIONS 8
|
||||
#define INPUTSIZE 4097
|
||||
#define TIMEOUTMS 15000
|
||||
|
||||
class Network
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
Packet(MessageType type, unsigned int& packetID);
|
||||
// Used to create packet from already existing data buffer.
|
||||
Packet(char* data, const int sizeOfPacket);
|
||||
Packet(MessageType type);
|
||||
~Packet();
|
||||
void Init(MessageType type, unsigned int& packetID);
|
||||
|
||||
@@ -49,7 +50,7 @@ public:
|
||||
// Pops the first element as if it was a string.
|
||||
std::string ReadString();
|
||||
char* ReadData(int SizeOfData);
|
||||
|
||||
void ChangePacketID(unsigned int& packetID);
|
||||
int Size() { return m_Offset; };
|
||||
char* Data() { return m_Data; };
|
||||
unsigned int DataReadSize() { return m_ReturnDataOffset; }
|
||||
|
||||
@@ -6,6 +6,8 @@ struct PlayerDefinition {
|
||||
int EntityID = -1;
|
||||
std::string Name = "";
|
||||
boost::asio::ip::udp::endpoint Endpoint;
|
||||
unsigned int PacketID;
|
||||
std::clock_t StopTime;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
#include "Network/PlayerDefinition.h"
|
||||
#include "Core/World.h"
|
||||
#include "Core/EventBroker.h"
|
||||
#include "Network/Network.h"
|
||||
#include "../Network/Network.h"
|
||||
#include "Input/EInputCommand.h"
|
||||
#include "Core/EPlayerDamage.h"
|
||||
|
||||
class Server : public Network
|
||||
{
|
||||
@@ -25,9 +27,10 @@ private:
|
||||
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
||||
boost::asio::io_service m_IOService;
|
||||
boost::asio::ip::udp::socket m_Socket;
|
||||
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
|
||||
|
||||
// Sending messages to client logic
|
||||
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
|
||||
std::vector<PlayerDefinition> m_ConnectedUsers;
|
||||
char readBuffer[INPUTSIZE] = { 0 };
|
||||
int bytesRead = 0;
|
||||
// time for previouse message
|
||||
@@ -41,40 +44,38 @@ private:
|
||||
|
||||
//Timers
|
||||
std::clock_t m_StartPingTime;
|
||||
std::clock_t m_StopTimes[8];
|
||||
|
||||
// Game logic
|
||||
World* m_World;
|
||||
EventBroker* m_EventBroker;
|
||||
// vec.size() = ammount of players to create, stores playerID's
|
||||
std::vector<unsigned int> m_PlayersToCreate;
|
||||
|
||||
// Packet loss logic
|
||||
unsigned int m_PacketID;
|
||||
unsigned int m_PreviousPacketID;
|
||||
unsigned int m_SendPacketID;
|
||||
unsigned int m_PacketID = 0;
|
||||
unsigned int m_PreviousPacketID = 0;
|
||||
|
||||
// Private member functions
|
||||
int receive(char* data, size_t length);
|
||||
void readFromClients();
|
||||
void send(Packet& packet, int playerID);
|
||||
void send(Packet& packet);
|
||||
void moveMessageHead(char*& data, size_t& length, size_t stepSize);
|
||||
void broadcast(std::string message);
|
||||
void broadcast(Packet& packet);
|
||||
void sendSnapshot();
|
||||
void sendPing();
|
||||
void checkForTimeOuts();
|
||||
void disconnect(int i);
|
||||
void parseMessageType(Packet& packet);
|
||||
void parseEvent(Packet& packet);
|
||||
void parseOnInputCommand(Packet& packet);
|
||||
void parseOnPlayerDamage(Packet& packet);
|
||||
void parseConnect(Packet& packet);
|
||||
void parseDisconnect();
|
||||
void parseClientPing();
|
||||
void parseServerPing();
|
||||
void parseSnapshot(Packet& packet);
|
||||
void identifyPacketLoss();
|
||||
EntityID createPlayer();
|
||||
void createPlayer();
|
||||
int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
|
||||
// Debug event
|
||||
EventRelay<Server, Events::InputCommand> m_EInputCommand;
|
||||
bool OnInputCommand(const Events::InputCommand& e);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef DirectionalLightJob_h__
|
||||
#define DirectionalLightJob_h__
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "../Common.h"
|
||||
#include "../GLM.h"
|
||||
#include "../Core/ComponentWrapper.h"
|
||||
#include "RenderJob.h"
|
||||
#include "../Core/Transform.h"
|
||||
#include "../Core/World.h"
|
||||
|
||||
struct DirectionalLightJob : RenderJob
|
||||
{
|
||||
DirectionalLightJob(ComponentWrapper transformComponent, ComponentWrapper directionalLightComponent, World* m_World)
|
||||
: RenderJob()
|
||||
{
|
||||
|
||||
Direction = glm::vec4(0,0,-1,0) * glm::inverse(Transform::AbsoluteOrientation(m_World, transformComponent.EntityID));
|
||||
//Direction = glm::vec4((glm::vec3)directionalLightComponent["Direction"], 0.f);
|
||||
Color = (glm::vec4)directionalLightComponent["Color"];
|
||||
Intensity = (double)directionalLightComponent["Intensity"];
|
||||
};
|
||||
|
||||
glm::vec4 Direction;
|
||||
glm::vec4 Color;
|
||||
float Intensity;
|
||||
|
||||
void CalculateHash() override
|
||||
{
|
||||
Hash = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -46,8 +46,8 @@ private:
|
||||
int m_NumberOfTiles = 0;
|
||||
|
||||
struct Plane {
|
||||
glm::vec3 Normal;
|
||||
float d;
|
||||
glm::vec3 Normal = glm::vec3(0.f);
|
||||
float d = 0;
|
||||
};
|
||||
|
||||
struct Frustum {
|
||||
@@ -56,20 +56,21 @@ private:
|
||||
Frustum* m_Frustums;
|
||||
|
||||
//This should be a component
|
||||
struct PointLight {
|
||||
struct LightSource {
|
||||
glm::vec4 Position = glm::vec4(0.f);
|
||||
glm::vec4 Direction = glm::vec4(10.f);
|
||||
glm::vec4 Color = glm::vec4(1.f);
|
||||
float Radius = 5.f;
|
||||
float Intensity = 0.8f;
|
||||
float Falloff = 0.3f;
|
||||
float Padding = 1337;
|
||||
enum Type_t { Zero, Point, Directional, Spot } Type;
|
||||
};
|
||||
std::vector<PointLight> m_PointLights;
|
||||
std::vector<LightSource> m_LightSources;
|
||||
|
||||
struct LightGrid {
|
||||
float Start;
|
||||
float Amount;
|
||||
glm::vec2 Padding;
|
||||
float Start = 0;
|
||||
float Amount = 0;
|
||||
glm::vec2 Padding = glm::vec2(1.f, 2.f);
|
||||
};
|
||||
|
||||
LightGrid* m_LightGrid;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "../Core/ResourceManager.h"
|
||||
#include "Camera.h"
|
||||
#include "../Core/World.h"
|
||||
#include "../Core/Transform.h"
|
||||
|
||||
struct ModelJob : RenderJob
|
||||
{
|
||||
@@ -28,6 +29,9 @@ struct ModelJob : RenderJob
|
||||
Matrix = matrix;
|
||||
Color = modelComponent["Color"];
|
||||
Entity = modelComponent.EntityID;
|
||||
glm::vec3 abspos = Transform::AbsolutePosition(world, modelComponent.EntityID);
|
||||
glm::vec3 worldpos = glm::vec3(camera->ViewMatrix() * glm::vec4(abspos, 1));
|
||||
Depth = worldpos.z;
|
||||
World = world;
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "RenderJob.h"
|
||||
#include "ModelJob.h"
|
||||
#include "PointLightJob.h"
|
||||
#include "DirectionalLightJob.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -53,12 +54,14 @@ struct RenderScene
|
||||
::Camera* Camera;
|
||||
std::list<std::shared_ptr<RenderJob>> ForwardJobs;
|
||||
std::list<std::shared_ptr<RenderJob>> PointLightJobs;
|
||||
std::list<std::shared_ptr<RenderJob>> DirectionalLightJobs;
|
||||
Rectangle Viewport;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
ForwardJobs.clear();
|
||||
PointLightJobs.clear();
|
||||
DirectionalLightJobs.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ private:
|
||||
void updateProjectionMatrix(ComponentWrapper& cameraComponent);
|
||||
|
||||
void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
||||
void fillLight(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
||||
void fillPointLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
||||
void fillDirectionalLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world);
|
||||
|
||||
EventRelay<RenderSystem, Events::InputCommand> m_EInputCommand;
|
||||
bool OnInputCommand(const Events::InputCommand& e);
|
||||
|
||||
@@ -22,9 +22,8 @@
|
||||
class Renderer : public IRenderer
|
||||
{
|
||||
public:
|
||||
Renderer(EventBroker* eventBroker, World* world)
|
||||
Renderer(EventBroker* eventBroker)
|
||||
: m_EventBroker(eventBroker)
|
||||
, m_World(world)
|
||||
{ }
|
||||
|
||||
virtual void Initialize() override;
|
||||
@@ -36,7 +35,6 @@ public:
|
||||
private:
|
||||
//----------------------Variables----------------------//
|
||||
EventBroker* m_EventBroker;
|
||||
World* m_World;
|
||||
|
||||
Texture* m_ErrorTexture;
|
||||
Texture* m_WhiteTexture;
|
||||
@@ -62,7 +60,7 @@ private:
|
||||
void DrawScreenQuad(GLuint textureToDraw);
|
||||
|
||||
static bool DepthSort(const std::shared_ptr<RenderJob> &i, const std::shared_ptr<RenderJob> &j) { return (i->Depth < j->Depth); }
|
||||
void FillDepth(RenderScene& scene);
|
||||
void SortRenderJobsByDepth(RenderScene &scene);
|
||||
void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type);
|
||||
//--------------------ShaderPrograms-------------------//
|
||||
ShaderProgram* m_BasicForwardProgram;
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
#include "Rendering/RenderSystem.h"
|
||||
#include "Core/EntityFileParser.h"
|
||||
#include "Core/Octree.h"
|
||||
|
||||
#include "Systems/InterpolationSystem.h"
|
||||
// Network
|
||||
#include <boost/thread.hpp>
|
||||
#include "Network/Network.h"
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef CapturePointSystem_h__
|
||||
#define CapturePointSystem_h__
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/common.hpp>
|
||||
|
||||
#include "Common.h"
|
||||
#include "Core/System.h"
|
||||
#include "Engine/Collision/ETrigger.h"
|
||||
#include "Core/ECaptured.h"
|
||||
#include "Core/EWin.h"
|
||||
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
class CapturePointSystem : public PureSystem
|
||||
{
|
||||
public:
|
||||
//WARNING: on new map, destroy all info in the vectors, as well as reset all variables (just make new?)
|
||||
CapturePointSystem(EventBroker* eventBroker);
|
||||
|
||||
//updatecomponent
|
||||
virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& capturePoint, double dt) override;
|
||||
|
||||
private:
|
||||
//methods which will take care of specific events
|
||||
EventRelay<CapturePointSystem, Events::TriggerTouch> m_ETriggerTouch;
|
||||
bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e);
|
||||
EventRelay<CapturePointSystem, Events::TriggerLeave> m_ETriggerLeave;
|
||||
bool CapturePointSystem::OnTriggerLeave(const Events::TriggerLeave& e);
|
||||
EventRelay<CapturePointSystem, Events::Captured> m_ECaptured;
|
||||
bool CapturePointSystem::OnCaptured(const Events::Captured& e);
|
||||
|
||||
bool m_WinnerWasFound = false;
|
||||
//need to track these variables for the captureSystem to work as per design!
|
||||
const int m_NotACapturePoint = 999;
|
||||
int m_RedTeamNextPossibleCapturePoint = m_NotACapturePoint;
|
||||
int m_BlueTeamNextPossibleCapturePoint = m_NotACapturePoint;
|
||||
int m_RedTeamHomeCapturePoint = m_NotACapturePoint;
|
||||
int m_BlueTeamHomeCapturePoint = m_NotACapturePoint;
|
||||
|
||||
int m_NumberOfCapturePoints = 0;
|
||||
std::map<int, EntityID> m_CapturePointNumberToEntityIDMap;
|
||||
|
||||
//std::vector<ComponentWrapper>
|
||||
|
||||
const double m_CaptureTimeToTakeOver = 15.0;
|
||||
bool m_ResetTimers = false;
|
||||
|
||||
//vectors which will keep track of enter/leave changes
|
||||
std::vector<std::tuple<EntityID, EntityID>> m_ETriggerTouchVector;
|
||||
std::vector<std::tuple<EntityID, EntityID>> m_ETriggerLeaveVector;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef Systems_InterpolationSystem_h__
|
||||
#define Systems_InterpolationSystem_h__
|
||||
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
#include <boost/shared_array.hpp>
|
||||
#include <glm/common.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include "Common.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/EventBroker.h"
|
||||
|
||||
#include "Network/EInterpolate.h"
|
||||
|
||||
#define SNAPSHOTINTERVAL 0.05f
|
||||
|
||||
class InterpolationSystem : public PureSystem
|
||||
{
|
||||
struct Transform
|
||||
{
|
||||
glm::vec3 Position;
|
||||
glm::vec3 Scale;
|
||||
glm::quat Orientation;
|
||||
double interpolationTime;
|
||||
};
|
||||
public:
|
||||
InterpolationSystem(EventBroker* eventBroker)
|
||||
: System(eventBroker)
|
||||
, PureSystem("Transform")
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate);
|
||||
}
|
||||
~InterpolationSystem() { }
|
||||
virtual void UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& transform, double dt) override;
|
||||
private:
|
||||
std::unordered_map<EntityID, Transform> m_NextTransform;
|
||||
std::unordered_map<EntityID, Transform> m_LastReceivedTransform;
|
||||
|
||||
//glm::vec3 vectorInterpolation(glm::vec3 prev, glm::vec3 next, double currentTime);
|
||||
template <typename T>
|
||||
T vectorInterpolation(T prev, T next, double currentTime)
|
||||
{
|
||||
T difference = next - prev;
|
||||
T vector = (difference / SNAPSHOTINTERVAL) * static_cast<float>(currentTime);
|
||||
return vector;
|
||||
}
|
||||
|
||||
EventRelay<InterpolationSystem, Events::Interpolate> m_EInterpolate;
|
||||
bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -9,8 +9,10 @@
|
||||
<xs:include schemaLocation="Components/Camera.xsd"/>
|
||||
<xs:include schemaLocation="Components/AABB.xsd"/>
|
||||
<xs:include schemaLocation="Components/PointLight.xsd"/>
|
||||
<xs:include schemaLocation="Components/DirectionalLight.xsd"/>
|
||||
<xs:include schemaLocation="Components/Trigger.xsd"/>
|
||||
<xs:include schemaLocation="Components/Health.xsd"/>
|
||||
<xs:include schemaLocation="Components/CapturePoint.xsd"/>
|
||||
<xs:include schemaLocation="Components/Listener.xsd"/>
|
||||
<xs:include schemaLocation="Components/SoundEmitter.xsd"/>
|
||||
<xs:include schemaLocation="Components/Collidable.xsd"/>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<CapturePoint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="CapturePoint.xsd">
|
||||
<CapturePointNumber>0</CapturePointNumber>
|
||||
<CaptureTimer>0</CaptureTimer>
|
||||
<HomePointForTeam><Spectator/></HomePointForTeam>
|
||||
</CapturePoint>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||
|
||||
<xs:complexType name="TeamEnum" mixed="true">
|
||||
<xs:complexContent>
|
||||
<xs:extension base="t:enum">
|
||||
<xs:choice>
|
||||
<xs:element name="Spectator" type="xs:integer" fixed="1" minOccurs="0"/>
|
||||
<xs:element name="Red" type="xs:integer" fixed="2" minOccurs="0"/>
|
||||
<xs:element name="Blue" type="xs:integer" fixed="3" minOccurs="0"/>
|
||||
</xs:choice>
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
||||
<xs:element name="CapturePoint">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A Capture Point. Add a Team Component to specify who currently owns it</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="CaptureTimer" type="t:double" minOccurs="0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>CaptureTimer handled by Capture Point System</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element name="CapturePointNumber" type="t:int" minOccurs="0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>CapturePointNumber specify an int number for this</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="HomePointForTeam" type="TeamEnum" minOccurs="0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Specify if this is a HomePoint for either team</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<DirectionalLight xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="DirectionalLight.xsd">
|
||||
<Color R="1" G="1" B="1" A="1"/>
|
||||
<Intensity>0.8</Intensity>
|
||||
<Visible>true</Visible>
|
||||
</DirectionalLight>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
|
||||
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||
<xs:element name="DirectionalLight">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A directional light that shines bright like the future.</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="Color" type="t:Color" minOccurs="0"/>
|
||||
<xs:element name="Intensity" type="t:double" minOccurs="0"/>
|
||||
<xs:element name="Visible" type="t:bool" minOccurs="0"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -4,6 +4,9 @@
|
||||
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
|
||||
|
||||
<xs:element name="Player">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The player charachter</xs:documentation>
|
||||
</xs:annotation>
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="Velocity" type="t:Vector" minOccurs="0"/>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</xs:extension>
|
||||
</xs:complexContent>
|
||||
</xs:complexType>
|
||||
|
||||
|
||||
<xs:element name="Team">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Represents entity team affiliation</xs:documentation>
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||
|
||||
<Components>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
|
||||
<Children>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
||||
</c:Model>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health>
|
||||
<Health>60</Health>
|
||||
</c:Health>
|
||||
<c:AABB/>
|
||||
<c:Camera/>
|
||||
<c:Listener/>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-0.151326105" Y="13.5594187" Z="12.5957394"/>
|
||||
<Orientation X="-0.872664392" Y="0.157068729" Z="4.90324332e-08"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<HomePointForTeam>3</HomePointForTeam>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="1" G="0.200000003" R="0"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="5.48757935" Y="2.62824345" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>1</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="1" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="1.91470337" Y="2.32191443" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>2</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="1" G="1" R="0"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-1.31178355" Y="2.16289616" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<HomePointForTeam>2</HomePointForTeam>
|
||||
<CapturePointNumber>3</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-4.27947044" Y="1.99913001" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-1.67672658" Y="2.23822045" Z="-0.0577065349"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="2.40398169" Y="2.02053547" Z="-0.0348547697"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
|
||||
</Entity>
|
||||
@@ -0,0 +1,158 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||
|
||||
<Components>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
|
||||
<Children>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
||||
</c:Model>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health>
|
||||
<Health>60</Health>
|
||||
</c:Health>
|
||||
<c:AABB/>
|
||||
<c:Camera/>
|
||||
<c:Listener/>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-2.38960934" Y="11.7122087" Z="11.4659815"/>
|
||||
<Orientation X="-0.645771146" Y="-1.17512627e-05" Z="1.76718231e-07"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<HomePointForTeam>3</HomePointForTeam>
|
||||
<CaptureTimer>6.9158446328696002</CaptureTimer>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="1" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="5.48757935" Y="2.62824345" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CaptureTimer>-13.234195338196177</CaptureTimer>
|
||||
<CapturePointNumber>1</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="1" G="1" R="0"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="1.38422918" Y="2.32191443" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>2</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-1.79222715" Y="2.16289616" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<HomePointForTeam>2</HomePointForTeam>
|
||||
<CapturePointNumber>3</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-4.27947044" Y="1.99913001" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="4.99647331" Y="2.23822045" Z="1.80651212"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="2.7091608" Y="2.02053547" Z="-0.0348547697"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
|
||||
</Entity>
|
||||
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||
|
||||
<Components>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
|
||||
<Children>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
||||
</c:Model>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health>
|
||||
<Health>60</Health>
|
||||
</c:Health>
|
||||
<c:AABB/>
|
||||
<c:Camera/>
|
||||
<c:Listener/>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-0.151326105" Y="13.5594187" Z="12.5957394"/>
|
||||
<Orientation X="-0.872664511" Y="0.157068729" Z="3.01738083e-08"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<HomePointForTeam>3</HomePointForTeam>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="1" G="0.200000003" R="0"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="5.48757935" Y="2.62824345" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>1</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="1" G="1" R="0"/>
|
||||
</c:Model>
|
||||
<c:Team/>
|
||||
<c:Transform>
|
||||
<Position X="1.91470337" Y="2.32191443" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>2</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="1" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team/>
|
||||
<c:Transform>
|
||||
<Position X="-1.31178355" Y="2.16289616" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<HomePointForTeam>2</HomePointForTeam>
|
||||
<CapturePointNumber>3</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-4.27947044" Y="1.99913001" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-5.74354839" Y="2.23822045" Z="-0.0577065349"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="6.96941662" Y="2.02053547" Z="-0.0348547697"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
|
||||
</Entity>
|
||||
@@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||
|
||||
<Components>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
|
||||
<Children>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
||||
</c:Model>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health>
|
||||
<Health>60</Health>
|
||||
</c:Health>
|
||||
<c:AABB/>
|
||||
<c:Camera/>
|
||||
<c:Listener/>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-0.151326105" Y="13.5594187" Z="12.5957394"/>
|
||||
<Orientation X="-0.942477643" Y="0.157067701" Z="-1.50870125e-08"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<HomePointForTeam>3</HomePointForTeam>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="1" G="0.200000003" R="0"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="5.39647007" Y="2.36802292" Z="0.0546064377"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>1</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="1" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="4.21088505" Y="2.32191443" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>2</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="1" G="1" R="0"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="2.30499458" Y="2.04659939" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>3</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="0.196968079" Y="1.99913001" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<HomePointForTeam>2</HomePointForTeam>
|
||||
<CapturePointNumber>4</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-1.82539892" Y="1.96172595" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="1.15194035" Y="2.23822045" Z="-0.0577065349"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-0.266237378" Y="2.23822045" Z="0.344228983"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="6.96941662" Y="2.02053547" Z="1.9484092"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="3.63076782" Y="2.5672617" Z="-0.0348547697"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
|
||||
</Entity>
|
||||
@@ -0,0 +1,205 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||
|
||||
<Components>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
|
||||
<Children>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
||||
</c:Model>
|
||||
<c:Transform/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health>
|
||||
<Health>60</Health>
|
||||
</c:Health>
|
||||
<c:AABB/>
|
||||
<c:Camera/>
|
||||
<c:Listener/>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-0.151326105" Y="13.5594187" Z="12.5957394"/>
|
||||
<Orientation X="-0.62831825" Y="0.0872534811" Z="-7.47903606e-09"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<HomePointForTeam>3</HomePointForTeam>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="1" G="0.200000003" R="0"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="5.39647007" Y="2.36802292" Z="0.0546064377"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>1</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="1" G="1" R="0"/>
|
||||
</c:Model>
|
||||
<c:Team/>
|
||||
<c:Transform>
|
||||
<Position X="3.68890452" Y="2.32191443" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>2</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
</c:Model>
|
||||
<c:Team/>
|
||||
<c:Transform>
|
||||
<Position X="1.98802853" Y="2.16289616" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<CapturePointNumber>3</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="1" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team/>
|
||||
<c:Transform>
|
||||
<Position X="0.196968079" Y="1.99913001" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:AABB/>
|
||||
<c:CapturePoint>
|
||||
<HomePointForTeam>2</HomePointForTeam>
|
||||
<CapturePointNumber>4</CapturePointNumber>
|
||||
</c:CapturePoint>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||
</c:Model>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-1.82539892" Y="1.96172595" Z="0"/>
|
||||
</c:Transform>
|
||||
<c:Trigger/>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-7.44269609" Y="2.23822045" Z="-0.0577065349"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>2</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="-5.74354839" Y="2.23822045" Z="1.40012479"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="6.96941662" Y="2.02053547" Z="1.9484092"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Health/>
|
||||
<c:AABB/>
|
||||
<c:Model>
|
||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||
</c:Model>
|
||||
<c:Player/>
|
||||
<c:Team>
|
||||
<Team>3</Team>
|
||||
</c:Team>
|
||||
<c:Transform>
|
||||
<Position X="7.70311165" Y="2.02053547" Z="-0.0348547697"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
|
||||
</Entity>
|
||||
@@ -13,6 +13,7 @@
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Scale X="100" Y="1" Z="100"/>
|
||||
<Orientation X="0" Y="2.59200001" Z="0"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
@@ -45,9 +46,58 @@
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Camera/>
|
||||
<c:Listener/>
|
||||
<c:Transform>
|
||||
<Position X="5.85247707" Y="3.8454349" Z="-1.14486957"/>
|
||||
<Orientation X="2.51327395" Y="1.23916209" Z="-3.1415925"/>
|
||||
<Position X="1.36896265" Y="4.4259491" Z="10.6640663"/>
|
||||
<Orientation X="-0.0349078141" Y="0.157154545" Z="-2.60252193e-07"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:DirectionalLight/>
|
||||
<c:Model>
|
||||
<Resource>Models/DirectionalLightWidget.obj</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="2.1529963" Y="6.59221172" Z="0.169116676"/>
|
||||
<Orientation X="4.32000017" Y="4.6340003" Z="0"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Model>
|
||||
<Resource>Models/Assault.obj</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="-2.00568962" Y="0.527161121" Z="0"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Model>
|
||||
<Resource>Models/SecondaryWeapon.fbx</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="-0.546139359" Y="0.853016734" Z="0.177482292"/>
|
||||
<Orientation X="1.47266471" Y="0.524984181" Z="1.243698"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
</Entity>
|
||||
</Children>
|
||||
</Entity>
|
||||
<Entity>
|
||||
<Components>
|
||||
<c:Model>
|
||||
<Resource>Models/Core/UnitSphere.obj</Resource>
|
||||
</c:Model>
|
||||
<c:Transform>
|
||||
<Position X="0" Y="3.70000029" Z="0"/>
|
||||
</c:Transform>
|
||||
</Components>
|
||||
<Children/>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<xs:element ref="c:AABB" minOccurs="0"/>
|
||||
<xs:element ref="c:Trigger" minOccurs="0"/>
|
||||
<xs:element ref="c:Health" minOccurs="0"/>
|
||||
<xs:element ref="c:CapturePoint" minOccurs="0"/>
|
||||
<xs:element ref="c:PointLight" minOccurs="0"/>
|
||||
<xs:element ref="c:Listener" minOccurs="0"/>
|
||||
<xs:element ref="c:SoundEmitter" minOccurs="0"/>
|
||||
@@ -27,6 +28,7 @@
|
||||
<xs:element ref="c:SpawnPoint" minOccurs="0"/>
|
||||
<xs:element ref="c:PlayerSpawn" minOccurs="0"/>
|
||||
<xs:element ref="c:Team" minOccurs="0"/>
|
||||
<xs:element ref="c:DirectionalLight" minOccurs="0"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
@@ -38,7 +40,7 @@
|
||||
<xs:element name="EntityRef" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:attribute name="file" type="xs:string" minOccurs="0"/>
|
||||
<xs:attribute name="file" type="xs:string" minOccurs="0"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
@@ -47,7 +49,7 @@
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute ref="xml:base"/>
|
||||
<xs:attribute name="name" type="xs:string" minOccurs="0" default=""/>
|
||||
<xs:attribute name="name" type="xs:string" minOccurs="0" default=""/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
@@ -27,19 +27,20 @@ layout (std430, binding = 0) buffer FrustumBuffer
|
||||
Frustum Data[];
|
||||
} Frustums;
|
||||
|
||||
struct PointLight {
|
||||
struct LightSource {
|
||||
vec4 Position;
|
||||
vec4 Direction;
|
||||
vec4 Color;
|
||||
float Radius;
|
||||
float Intensity;
|
||||
float Falloff;
|
||||
float Padding;
|
||||
int Type;
|
||||
};
|
||||
|
||||
layout (std430, binding = 1) buffer LightBuffer
|
||||
{
|
||||
PointLight List[];
|
||||
} PointLights;
|
||||
LightSource List[];
|
||||
} LightSources;
|
||||
|
||||
struct LightGrid {
|
||||
float Start;
|
||||
@@ -106,8 +107,7 @@ layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
||||
void main ()
|
||||
{
|
||||
GroupIndex = int(gl_WorkGroupID.x + (gl_WorkGroupID.y * int(ScreenDimensions.x/TILE_SIZE)));
|
||||
if(gl_LocalInvocationIndex == 0)
|
||||
{
|
||||
if(gl_LocalInvocationIndex == 0) {
|
||||
GroupLightCount = 0;
|
||||
GroupFrustum = Frustums.Data[GroupIndex];
|
||||
}
|
||||
@@ -115,22 +115,25 @@ void main ()
|
||||
barrier();
|
||||
memoryBarrierShared();
|
||||
|
||||
for(int i = int(gl_LocalInvocationIndex); i < PointLights.List.length(); i += TILE_SIZE*TILE_SIZE)
|
||||
{
|
||||
PointLight light = PointLights.List[i];
|
||||
for(int i = int(gl_LocalInvocationIndex); i < LightSources.List.length(); i += TILE_SIZE*TILE_SIZE) {
|
||||
LightSource light = LightSources.List[i];
|
||||
|
||||
//if pointlight
|
||||
//Pos i view antagligen
|
||||
if(SphereInsideFrustrum( vec3(V * light.Position), light.Radius, GroupFrustum))
|
||||
{
|
||||
//TODO: Fix transparent and opaque list, and depth test.
|
||||
AppendLight( i );
|
||||
if(light.Type == 1) {
|
||||
if(SphereInsideFrustrum( vec3(V * light.Position), light.Radius, GroupFrustum)) {
|
||||
//TODO: Fix transparent and opaque list, and depth test.
|
||||
AppendLight( i );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if conelight
|
||||
|
||||
//if directional
|
||||
if(light.Type == 2) {
|
||||
AppendLight( i );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -9,19 +9,20 @@ uniform sampler2D texture0;
|
||||
|
||||
#define TILE_SIZE 16
|
||||
|
||||
struct PointLight {
|
||||
struct LightSource {
|
||||
vec4 Position;
|
||||
vec4 Direction;
|
||||
vec4 Color;
|
||||
float Radius;
|
||||
float Intensity;
|
||||
float Falloff;
|
||||
float Padding;
|
||||
int Type;
|
||||
};
|
||||
|
||||
layout (std430, binding = 1) buffer LightBuffer
|
||||
{
|
||||
PointLight List[];
|
||||
} PointLights;
|
||||
LightSource List[];
|
||||
} LightSources;
|
||||
|
||||
struct LightGrid {
|
||||
float Start;
|
||||
@@ -71,7 +72,7 @@ vec4 CalcDiffuse(vec4 lightColor, vec4 lightVec, vec4 normal) {
|
||||
return lightColor * power;
|
||||
}
|
||||
|
||||
LightResult CalcPointLight(vec4 lightPos, float lightRadius, vec4 lightColor, float intensity, vec4 viewVec, vec4 position, vec4 normal, float falloff)
|
||||
LightResult CalcPointLightSource(vec4 lightPos, float lightRadius, vec4 lightColor, float intensity, vec4 viewVec, vec4 position, vec4 normal, float falloff)
|
||||
{
|
||||
vec4 L = lightPos - position;
|
||||
float dist = length(L);
|
||||
@@ -85,6 +86,16 @@ LightResult CalcPointLight(vec4 lightPos, float lightRadius, vec4 lightColor, fl
|
||||
return result;
|
||||
}
|
||||
|
||||
LightResult CalcDirectionalLightSource(vec4 direction, vec4 color, float intensity, vec4 viewVec, vec4 vertNormal)
|
||||
{
|
||||
vec4 L = normalize( -vec4(direction.xyz, 0) );
|
||||
|
||||
LightResult result;
|
||||
result.Diffuse = CalcDiffuse(color, L, vertNormal) * intensity;
|
||||
result.Specular = CalcSpecular(color, viewVec, L, vertNormal) * intensity;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
@@ -94,8 +105,8 @@ void main()
|
||||
vec4 viewVec = normalize(-position);
|
||||
|
||||
vec2 tilePos;
|
||||
tilePos.x = int(gl_FragCoord.x/16);
|
||||
tilePos.y = int(gl_FragCoord.y/16);
|
||||
tilePos.x = int(gl_FragCoord.x/TILE_SIZE);
|
||||
tilePos.y = int(gl_FragCoord.y/TILE_SIZE);
|
||||
|
||||
LightResult totalLighting;
|
||||
totalLighting.Diffuse = scene_ambient;
|
||||
@@ -103,30 +114,38 @@ void main()
|
||||
|
||||
int start = int(LightGrids.Data[currentTile].Start);
|
||||
int amount = int(LightGrids.Data[currentTile].Amount);
|
||||
//for(int i = 0; i < 3; i++)
|
||||
for(int i = start; i < start + amount; i++)
|
||||
{
|
||||
|
||||
for(int i = start; i < start + amount; i++) {
|
||||
|
||||
int l = int(LightIndex[i]);
|
||||
LightSource light = LightSources.List[l];
|
||||
|
||||
LightResult result = CalcPointLight(V * PointLights.List[l].Position, PointLights.List[l].Radius, PointLights.List[l].Color, PointLights.List[l].Intensity, viewVec, position, normal, PointLights.List[i].Falloff);
|
||||
|
||||
LightResult result;
|
||||
if(light.Type == 1) { // point
|
||||
result = CalcPointLightSource(V * light.Position, light.Radius, light.Color, light.Intensity, viewVec, position, normal, light.Falloff);
|
||||
} else if (light.Type == 2) { //Directional
|
||||
result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal);
|
||||
}
|
||||
totalLighting.Diffuse += result.Diffuse;
|
||||
totalLighting.Specular += result.Specular;
|
||||
}
|
||||
|
||||
|
||||
//fragmentColor += Input.DiffuseColor;
|
||||
fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * texel * Color;
|
||||
//fragmentColor += Input.DiffuseColor * (totalLighting.Diffuse) * texel * Color;
|
||||
//fragmentColor += vec4(0.0, LightGrids.Data[currentTile].Amount/3.0, 0, 1);
|
||||
//fragmentColor += Input.DiffuseColor + vec4(0.0, LightGrids.Data[currentTile].Amount/3, 0, 1);
|
||||
//fragmentColor = texel * Input.DiffuseColor * Color;
|
||||
if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 )
|
||||
{
|
||||
//fragmentColor += vec4(0.5, 0, 0, 0);
|
||||
//fragmentColor += vec4(currentTile/3600.f, 0, 0, 1);
|
||||
|
||||
//Tiled Debug Code
|
||||
/*
|
||||
if(int(gl_FragCoord.x)%16 == 0 || int(gl_FragCoord.y)%16 == 0 ) {
|
||||
fragmentColor += vec4(0.5, 0, 0, 0);
|
||||
} else {
|
||||
//fragmentColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/3.0, 0, 0, 1);
|
||||
|
||||
|
||||
fragmentColor += vec4(LightGrids.Data[int(tilePos.x + tilePos.y*80)].Amount/LightSources.List.length(), 0, 0, 1);
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,6 @@ void main()
|
||||
|
||||
Output.Position = Position;
|
||||
Output.TextureCoordinate = TextureCoords;
|
||||
Output.Normal = Normal;
|
||||
Output.Normal = vec3(M * vec4(Normal, 0.0));
|
||||
Output.DiffuseColor = DiffuseVertexColor;
|
||||
}
|
||||
@@ -72,6 +72,11 @@ ComponentPool::iterator ComponentPool::end() const
|
||||
return iterator(m_ComponentInfo, m_Pool.end(), m_Pool.end());
|
||||
}
|
||||
|
||||
size_t ComponentPool::size() const
|
||||
{
|
||||
return m_Pool.size();
|
||||
}
|
||||
|
||||
template <typename InterpretType /*= char*/>
|
||||
void ComponentPool::Dump() const
|
||||
{
|
||||
|
||||
+155
-130
@@ -5,28 +5,27 @@ using namespace boost::asio::ip;
|
||||
|
||||
Client::Client(ConfigFile* config) : m_Socket(m_IOService)
|
||||
{
|
||||
// Asumes root node is EntityID 0
|
||||
insertIntoServerClientMaps(0, 0);
|
||||
// Default is local host
|
||||
std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1");
|
||||
int port = config->Get<int>("Networking.Port", 13);
|
||||
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
|
||||
// Set up network stream
|
||||
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
|
||||
m_NextSnapshot.InputForward = "";
|
||||
m_NextSnapshot.InputRight = "";
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
{
|
||||
}
|
||||
{ }
|
||||
|
||||
void Client::Start(World* world, EventBroker* eventBroker)
|
||||
{
|
||||
m_WasStarted = true;
|
||||
m_EventBroker = eventBroker;
|
||||
m_World = world;
|
||||
|
||||
// Subscribe to events
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayeDamage, &Client::OnPlayerDamage);
|
||||
|
||||
m_Socket.connect(m_ReceiverEndpoint);
|
||||
LOG_INFO("I am client. BIP BOP");
|
||||
@@ -34,7 +33,11 @@ void Client::Start(World* world, EventBroker* eventBroker)
|
||||
|
||||
void Client::Update()
|
||||
{
|
||||
m_EventBroker->Process<Client>();
|
||||
readFromServer();
|
||||
if (m_IsConnected) {
|
||||
hasServerTimedOut();
|
||||
}
|
||||
}
|
||||
|
||||
void Client::readFromServer()
|
||||
@@ -46,58 +49,7 @@ void Client::readFromServer()
|
||||
parseMessageType(packet);
|
||||
}
|
||||
}
|
||||
std::clock_t currentTime = std::clock();
|
||||
if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) {
|
||||
if (isConnected()) {
|
||||
//sendSnapshotToServer();
|
||||
}
|
||||
previousSnapshotMessage = currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
void Client::sendSnapshotToServer()
|
||||
{
|
||||
// Reset previous key state in snapshot.
|
||||
m_NextSnapshot.InputForward = "";
|
||||
m_NextSnapshot.InputRight = "";
|
||||
|
||||
auto player = m_World->GetComponent(m_PlayerDefinitions[m_PlayerID].EntityID, "Player");
|
||||
|
||||
// See if any movement keys are down
|
||||
// We dont care if it's overwritten by later
|
||||
// if statement. Watcha gonna do, right!
|
||||
if (player["Forward"]) {
|
||||
m_NextSnapshot.InputForward = "+Forward";
|
||||
}
|
||||
if (player["Left"]) {
|
||||
m_NextSnapshot.InputRight = "-Right";
|
||||
}
|
||||
if (player["Back"]) {
|
||||
m_NextSnapshot.InputForward = "-Forward";
|
||||
}
|
||||
if (player["Right"]) {
|
||||
m_NextSnapshot.InputRight = "+Right";
|
||||
}
|
||||
|
||||
if (m_NextSnapshot.InputForward != "") {
|
||||
Packet packet(MessageType::Event, m_SendPacketID);
|
||||
packet.WriteString(m_NextSnapshot.InputForward);
|
||||
send(packet);
|
||||
} else {
|
||||
Packet packet(MessageType::Event, m_SendPacketID);
|
||||
packet.WriteString("0Forward");
|
||||
send(packet);
|
||||
}
|
||||
|
||||
if (m_NextSnapshot.InputRight != "") {
|
||||
Packet packet(MessageType::Event, m_SendPacketID);
|
||||
packet.WriteString(m_NextSnapshot.InputRight);
|
||||
send(packet);
|
||||
} else {
|
||||
Packet packet(MessageType::Event, m_SendPacketID);
|
||||
packet.WriteString("0Right");
|
||||
send(packet);
|
||||
}
|
||||
sendInputCommands();
|
||||
}
|
||||
|
||||
void Client::parseMessageType(Packet& packet)
|
||||
@@ -108,9 +60,7 @@ void Client::parseMessageType(Packet& packet)
|
||||
// Read packet ID
|
||||
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
||||
if (m_PacketID <= m_PreviousPacketID)
|
||||
return;
|
||||
//IdentifyPacketLoss();
|
||||
identifyPacketLoss();
|
||||
|
||||
switch (static_cast<MessageType>(messageType)) {
|
||||
case MessageType::Connect:
|
||||
@@ -129,9 +79,8 @@ void Client::parseMessageType(Packet& packet)
|
||||
break;
|
||||
case MessageType::Disconnect:
|
||||
break;
|
||||
case MessageType::Event:
|
||||
parseEventMessage(packet);
|
||||
break;
|
||||
case MessageType::PlayerConnected:
|
||||
parsePlayerConnected(packet);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -139,34 +88,52 @@ void Client::parseMessageType(Packet& packet)
|
||||
|
||||
void Client::parseConnect(Packet& packet)
|
||||
{
|
||||
m_PlayerID = packet.ReadPrimitive<int>();
|
||||
LOG_INFO("%i: I am player: %i", m_PacketID, m_PlayerID);
|
||||
// Map ServerEntityID and your PlayerID
|
||||
LOG_INFO("I be connected PogChamp");
|
||||
}
|
||||
|
||||
void Client::parsePlayerConnected(Packet & packet)
|
||||
{
|
||||
// Map ServerEntityID and other player's PlayerID
|
||||
LOG_INFO("A Player connected");
|
||||
}
|
||||
|
||||
void Client::parsePing()
|
||||
{
|
||||
m_DurationOfPingTime = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
||||
LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime);
|
||||
|
||||
}
|
||||
|
||||
void Client::parseServerPing()
|
||||
{
|
||||
// Might miss connect message so set it here instead.
|
||||
m_IsConnected = true;
|
||||
// Time since last ping was received
|
||||
m_DurationOfPingTime = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
||||
LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime);
|
||||
m_StartPingTime = std::clock();
|
||||
|
||||
Packet packet(MessageType::ServerPing, m_SendPacketID);
|
||||
packet.WriteString("Ping recieved");
|
||||
send(packet);
|
||||
}
|
||||
|
||||
void Client::parseEventMessage(Packet& packet)
|
||||
// Fields with strings will not work right now
|
||||
void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType)
|
||||
{
|
||||
int Id = -1;
|
||||
std::string command = packet.ReadString();
|
||||
if (command.find("+Player") != std::string::npos) {
|
||||
Id = packet.ReadPrimitive<int>();
|
||||
// Sett Player name
|
||||
m_PlayerDefinitions[Id].Name = command.erase(0, 7);
|
||||
} else {
|
||||
LOG_INFO("%i: Event message: %s", m_PacketID, command.c_str());
|
||||
int sizeOfFields = 0;
|
||||
for (auto field : componentInfo.FieldsInOrder) {
|
||||
ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(field);
|
||||
sizeOfFields += fieldInfo.Stride;
|
||||
}
|
||||
// Is the size correct?
|
||||
boost::shared_array<char> eventData(new char[componentInfo.Stride]);
|
||||
memcpy(eventData.get(), packet.ReadData(componentInfo.Stride), componentInfo.Stride);
|
||||
//Send event to interpolat system
|
||||
Events::Interpolate e;
|
||||
e.Entity = entityID;
|
||||
e.DataArray = eventData;
|
||||
m_EventBroker->Publish(e);
|
||||
|
||||
}
|
||||
|
||||
void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType)
|
||||
@@ -182,17 +149,27 @@ void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, co
|
||||
}
|
||||
}
|
||||
|
||||
// Field parse
|
||||
void Client::parseSnapshot(Packet& packet)
|
||||
{
|
||||
std::string componentType = packet.ReadString();
|
||||
while (packet.DataReadSize() < packet.Size()) {
|
||||
EntityID entityID = packet.ReadPrimitive<EntityID>();
|
||||
// Components EntityID
|
||||
EntityID receivedEntityID = packet.ReadPrimitive<EntityID>();
|
||||
// Parents EntityID
|
||||
EntityID receivedParentEntityID = packet.ReadPrimitive<EntityID>();
|
||||
ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
|
||||
if (m_World->ValidEntity(entityID)) {
|
||||
// Check if the received EntityID is mapped to one of our local EntityIDs
|
||||
if (serverClientMapsHasEntity(receivedEntityID)) {
|
||||
// Get the local EntityID
|
||||
EntityID entityID = m_ServerIDToClientID.at(receivedEntityID);
|
||||
// Check if the component exists
|
||||
if (m_World->HasComponent(entityID, componentType)) {
|
||||
// If the entity and the component exists update it
|
||||
updateFields(packet, componentInfo, entityID, componentType);
|
||||
if (componentType == "Transform") {
|
||||
InterpolateFields(packet, componentInfo, entityID, componentType);
|
||||
} else {
|
||||
updateFields(packet, componentInfo, entityID, componentType);
|
||||
}
|
||||
// if entity exists but not the component
|
||||
} else {
|
||||
// Create component
|
||||
@@ -202,11 +179,12 @@ void Client::parseSnapshot(Packet& packet)
|
||||
}
|
||||
// If the entity dosent exist nor the component
|
||||
} else {
|
||||
//Create Entity
|
||||
// Create Entity
|
||||
// If entity dosen't exist
|
||||
EntityID newEntityID = m_World->CreateEntity();
|
||||
insertIntoServerClientMaps(receivedEntityID, newEntityID);
|
||||
// Check if EntityIDs are out of sync
|
||||
if (newEntityID != entityID) {
|
||||
if (newEntityID != receivedEntityID) {
|
||||
LOG_INFO("Client::parseSnapshot(Packet& packet): Newly created EntityID is not the \
|
||||
same as the one sent by server (EntityIDs are out of sync)");
|
||||
}
|
||||
@@ -215,6 +193,21 @@ void Client::parseSnapshot(Packet& packet)
|
||||
// Copy data to newly created component
|
||||
updateFields(packet, componentInfo, newEntityID, componentType);
|
||||
}
|
||||
|
||||
// Parent Logic
|
||||
// Don't need to check if receivedEntityID is mapped. (It should have been set)
|
||||
if (receivedParentEntityID != std::numeric_limits<EntityID>::max()) {
|
||||
if (serverClientMapsHasEntity(receivedParentEntityID)) {
|
||||
m_World->SetParent(m_ServerIDToClientID.at(receivedEntityID), m_ServerIDToClientID.at(receivedParentEntityID));
|
||||
// If Parent dosen't exist create one and map receivedParentEntityID to it.
|
||||
} else {
|
||||
// Create the new parent and add it to map
|
||||
EntityID newParentEntityID = m_World->CreateEntity();
|
||||
insertIntoServerClientMaps(receivedParentEntityID, newParentEntityID);
|
||||
// Set the newly created Entity as parent.
|
||||
m_World->SetParent(m_ServerIDToClientID.at(receivedEntityID), newParentEntityID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,9 +221,8 @@ int Client::receive(char* data, size_t length)
|
||||
0, error);
|
||||
|
||||
if (error) {
|
||||
LOG_ERROR("receive: %s", error.message().c_str());
|
||||
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||
}
|
||||
|
||||
return bytesReceived;
|
||||
}
|
||||
|
||||
@@ -252,76 +244,73 @@ void Client::connect()
|
||||
|
||||
void Client::disconnect()
|
||||
{
|
||||
Packet packet(MessageType::Connect, m_SendPacketID);
|
||||
packet.WriteString("+Disconnect");
|
||||
m_PreviousPacketID = 0;
|
||||
m_PacketID = 0;
|
||||
Packet packet(MessageType::Disconnect, m_SendPacketID);
|
||||
send(packet);
|
||||
}
|
||||
|
||||
void Client::ping()
|
||||
{
|
||||
Packet packet(MessageType::Connect, m_SendPacketID);
|
||||
packet.WriteString("Ping");
|
||||
m_StartPingTime = std::clock();
|
||||
send(packet);
|
||||
}
|
||||
|
||||
void Client::moveMessageHead(char*& data, size_t& length, size_t stepSize)
|
||||
{
|
||||
data += stepSize;
|
||||
length -= stepSize;
|
||||
//Packet packet(MessageType::Connect, m_SendPacketID);
|
||||
//packet.WriteString("Ping");
|
||||
//m_StartPingTime = std::clock();
|
||||
//send(packet);
|
||||
}
|
||||
|
||||
bool Client::OnInputCommand(const Events::InputCommand & e)
|
||||
{
|
||||
if (isConnected()) {
|
||||
ComponentWrapper& player = m_World->GetComponent(m_PlayerDefinitions[m_PlayerID].EntityID, "Player");
|
||||
if (e.Command == "Forward") {
|
||||
if (e.Value > 0) {
|
||||
(bool&)player["Forward"] = true;
|
||||
(bool&)player["Back"] = false;
|
||||
} else if (e.Value < 0) {
|
||||
(bool&)player["Back"] = true;
|
||||
(bool&)player["Forward"] = false;
|
||||
} else {
|
||||
(bool&)player["Forward"] = false;
|
||||
(bool&)player["Back"] = false;
|
||||
}
|
||||
}
|
||||
if (e.Command == "Right") {
|
||||
if (e.Value > 0) {
|
||||
(bool&)player["Right"] = true;
|
||||
(bool&)player["Left"] = false;
|
||||
} else if (e.Value < 0) {
|
||||
(bool&)player["Left"] = true;
|
||||
(bool&)player["Right"] = false;
|
||||
} else {
|
||||
(bool&)player["Left"] = false;
|
||||
(bool&)player["Right"] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e.Command == "ConnectToServer") { // Connect for now
|
||||
connect();
|
||||
if (e.Value > 0) {
|
||||
connect();
|
||||
}
|
||||
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
return true;
|
||||
} else if (e.Command == "DisconnectFromServer") {
|
||||
if (e.Value > 0) {
|
||||
disconnect();
|
||||
}
|
||||
return true;
|
||||
} else if (e.Command == "SwitchToPlayer") {
|
||||
if (e.Value > 0) {
|
||||
becomePlayer();
|
||||
}
|
||||
} else {
|
||||
m_InputCommandBuffer.push_back(e);
|
||||
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Client::OnPlayerDamage(const Events::PlayerDamage & e)
|
||||
{
|
||||
Packet packet(MessageType::OnInputCommand, m_SendPacketID);
|
||||
packet.WritePrimitive(e.DamageAmount);
|
||||
packet.WritePrimitive(e.PlayerDamagedID);
|
||||
packet.WriteString(e.TypeOfDamage);
|
||||
send(packet);
|
||||
return false;
|
||||
}
|
||||
|
||||
void Client::identifyPacketLoss()
|
||||
{
|
||||
// if no packets lost, difference should be equal to 1
|
||||
int difference = m_PacketID - m_PreviousPacketID;
|
||||
if (difference != 1) {
|
||||
LOG_INFO("%i Packet(s) were lost...", difference);
|
||||
LOG_INFO("%i Packet(s) were lost...", difference - 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool Client::isConnected()
|
||||
bool Client::hasServerTimedOut()
|
||||
{
|
||||
if (m_PlayerID != -1) {
|
||||
if (m_PlayerDefinitions[m_PlayerID].EntityID != -1) {
|
||||
return true;
|
||||
}
|
||||
// Time in ms
|
||||
float timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
||||
if (timeSincePing > TIMEOUTMS) {
|
||||
// Clear everything and go to menu.
|
||||
LOG_INFO("Server has timed out, returning to menu, Beep Boop.");
|
||||
m_IsConnected = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -335,3 +324,39 @@ EntityID Client::createPlayer()
|
||||
ComponentWrapper player = m_World->AttachComponent(entityID, "Player");
|
||||
return entityID;
|
||||
}
|
||||
|
||||
void Client::sendInputCommands()
|
||||
{
|
||||
if (m_InputCommandBuffer.size() > 0) {
|
||||
Packet packet(MessageType::OnInputCommand, m_SendPacketID);
|
||||
for (int i = 0; i < m_InputCommandBuffer.size(); i++) {
|
||||
packet.WriteString(m_InputCommandBuffer[i].Command);
|
||||
packet.WritePrimitive(m_InputCommandBuffer[i].Value);
|
||||
}
|
||||
send(packet);
|
||||
m_InputCommandBuffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void Client::becomePlayer()
|
||||
{
|
||||
Packet packet = Packet(MessageType::BecomePlayer, m_SendPacketID);
|
||||
send(packet);
|
||||
}
|
||||
|
||||
bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
|
||||
{
|
||||
return m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end();
|
||||
}
|
||||
|
||||
bool Client::serverClientMapsHasEntity(EntityID serverEntityID)
|
||||
{
|
||||
return m_ServerIDToClientID.find(serverEntityID) != m_ServerIDToClientID.end();
|
||||
}
|
||||
|
||||
void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID)
|
||||
{
|
||||
m_ServerIDToClientID.insert(std::make_pair(serverEntityID, clientEntityID));
|
||||
m_ClientIDToServerID.insert(std::make_pair(clientEntityID, serverEntityID));
|
||||
|
||||
}
|
||||
|
||||
@@ -17,20 +17,26 @@ Packet::Packet(char* data, const int sizeOfPacket)
|
||||
m_Offset = sizeOfPacket;
|
||||
}
|
||||
|
||||
Packet::Packet(MessageType type)
|
||||
{
|
||||
m_Data = new char[m_MaxPacketSize];
|
||||
unsigned int dummy = 0;
|
||||
Init(type, dummy);
|
||||
}
|
||||
|
||||
Packet::~Packet()
|
||||
{
|
||||
delete[] m_Data;
|
||||
}
|
||||
|
||||
void Packet::Init(MessageType type, unsigned int & packetID)
|
||||
{
|
||||
{
|
||||
m_ReturnDataOffset = 0;
|
||||
m_Offset = 0;
|
||||
// Create message header
|
||||
// Add message type
|
||||
int messageType = static_cast<int>(type);
|
||||
Packet::WritePrimitive<int>(messageType);
|
||||
packetID = packetID % 1000; // Packet id modulos
|
||||
Packet::WritePrimitive<int>(packetID);
|
||||
packetID++;
|
||||
}
|
||||
@@ -40,7 +46,7 @@ void Packet::WriteString(const std::string& str)
|
||||
// Message, add one extra byte for null terminator
|
||||
int sizeOfString = str.size() + 1;
|
||||
if (m_Offset + sizeOfString > m_MaxPacketSize) {
|
||||
LOG_WARNING("Package::WriteString(): Data size in packet exceeded maximum package size. New size is %i bytes\n", m_MaxPacketSize*2);
|
||||
//LOG_WARNING("Package::WriteString(): Data size in packet exceeded maximum package size. New size is %i bytes\n", m_MaxPacketSize*2);
|
||||
resizeData();
|
||||
}
|
||||
memcpy(m_Data + m_Offset, str.data(), sizeOfString * sizeof(char));
|
||||
@@ -50,7 +56,7 @@ void Packet::WriteString(const std::string& str)
|
||||
void Packet::WriteData(char * data, int sizeOfData)
|
||||
{
|
||||
if (m_Offset + sizeOfData > m_MaxPacketSize) {
|
||||
LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size. New size is %i bytes\n", m_MaxPacketSize*2);
|
||||
//LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size. New size is %i bytes\n", m_MaxPacketSize*2);
|
||||
resizeData();
|
||||
}
|
||||
memcpy(m_Data + m_Offset, data, sizeOfData);
|
||||
@@ -61,7 +67,7 @@ std::string Packet::ReadString()
|
||||
{
|
||||
std::string returnValue(m_Data + m_ReturnDataOffset);
|
||||
if (m_Offset < m_ReturnDataOffset + returnValue.size()) {
|
||||
LOG_WARNING("packet ReadString(): Oh no! You are trying to remove things outside my memory kingdom");
|
||||
//LOG_WARNING("packet ReadString(): Oh no! You are trying to remove things outside my memory kingdom");
|
||||
return "PopFrontString Failed";
|
||||
}
|
||||
// +1 for null terminator.
|
||||
@@ -72,7 +78,7 @@ std::string Packet::ReadString()
|
||||
char * Packet::ReadData(int SizeOfData)
|
||||
{
|
||||
if (m_Offset < m_ReturnDataOffset + SizeOfData) {
|
||||
LOG_WARNING("packet ReadData(): Oh no! You are trying to remove things outside my memory kingdom");
|
||||
//LOG_WARNING("packet ReadData(): Oh no! You are trying to remove things outside my memory kingdom");
|
||||
return nullptr;
|
||||
}
|
||||
unsigned int oldReturnDataOffset = m_ReturnDataOffset;
|
||||
@@ -80,14 +86,21 @@ char * Packet::ReadData(int SizeOfData)
|
||||
return (m_Data + oldReturnDataOffset);
|
||||
}
|
||||
|
||||
void Packet::ChangePacketID(unsigned int & packetID)
|
||||
{
|
||||
packetID = packetID + 1;
|
||||
// Overwrite old PacketID
|
||||
memcpy(m_Data + sizeof(int), &packetID, sizeof(int));
|
||||
}
|
||||
|
||||
void Packet::resizeData()
|
||||
{
|
||||
{
|
||||
|
||||
// Allocate memory to store our data in
|
||||
char* holdData = new char[m_MaxPacketSize];
|
||||
// Copy our data to the newly allocated memory
|
||||
memcpy(holdData, m_Data, m_Offset);
|
||||
// Increase max packet size
|
||||
// Increase max packet size
|
||||
m_MaxPacketSize = m_MaxPacketSize * 2;
|
||||
// Delete our data
|
||||
delete m_Data;
|
||||
|
||||
+152
-131
@@ -8,13 +8,14 @@ Server::~Server()
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Server::Start(World* world, EventBroker* eventBroker)
|
||||
{
|
||||
m_World = world;
|
||||
m_EventBroker = eventBroker;
|
||||
// Subscribe to events
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
|
||||
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
|
||||
m_StopTimes[i] = std::clock();
|
||||
m_PlayerDefinitions[i].StopTime = std::clock();
|
||||
}
|
||||
LOG_INFO("I am Server. BIP BOP\n");
|
||||
}
|
||||
@@ -22,8 +23,10 @@ void Server::Start(World* world, EventBroker* eventBroker)
|
||||
void Server::Update()
|
||||
{
|
||||
readFromClients();
|
||||
m_EventBroker->Process<Server>();
|
||||
}
|
||||
|
||||
|
||||
void Server::readFromClients()
|
||||
{
|
||||
while (m_Socket.available()) {
|
||||
@@ -50,7 +53,7 @@ void Server::readFromClients()
|
||||
|
||||
// Time out logic
|
||||
if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) {
|
||||
//checkForTimeOuts();
|
||||
checkForTimeOuts();
|
||||
timOutTimer = currentTime;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +65,7 @@ void Server::parseMessageType(Packet& packet)
|
||||
// Read packet ID
|
||||
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
||||
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
||||
//IdentifyPacketLoss();
|
||||
//identifyPacketLoss();
|
||||
switch (static_cast<MessageType>(messageType)) {
|
||||
case MessageType::Connect:
|
||||
parseConnect(packet);
|
||||
@@ -76,13 +79,18 @@ void Server::parseMessageType(Packet& packet)
|
||||
case MessageType::Message:
|
||||
break;
|
||||
case MessageType::Snapshot:
|
||||
parseSnapshot(packet);
|
||||
break;
|
||||
case MessageType::Disconnect:
|
||||
parseDisconnect();
|
||||
break;
|
||||
case MessageType::Event:
|
||||
parseEvent(packet);
|
||||
case MessageType::OnInputCommand:
|
||||
parseOnInputCommand(packet);
|
||||
break;
|
||||
case MessageType::OnPlayerDamage:
|
||||
parseOnPlayerDamage(packet);
|
||||
break;
|
||||
case MessageType::BecomePlayer:
|
||||
createPlayer();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -98,11 +106,11 @@ int Server::receive(char * data, size_t length)
|
||||
return length;
|
||||
}
|
||||
|
||||
void Server::send(Packet& packet, int playerID)
|
||||
void Server::send(Packet& packet, int userID)
|
||||
{
|
||||
int bytesSent = m_Socket.send_to(
|
||||
boost::asio::buffer(packet.Data(), packet.Size()),
|
||||
m_PlayerDefinitions[playerID].Endpoint,
|
||||
m_ConnectedUsers[userID].Endpoint,
|
||||
0);
|
||||
}
|
||||
|
||||
@@ -116,27 +124,11 @@ void Server::send(Packet & packet)
|
||||
0);
|
||||
}
|
||||
|
||||
void Server::moveMessageHead(char *& data, size_t & length, size_t stepSize)
|
||||
{
|
||||
data += stepSize;
|
||||
length -= stepSize;
|
||||
}
|
||||
|
||||
void Server::broadcast(std::string message)
|
||||
{
|
||||
Packet packet(MessageType::Event, m_SendPacketID);
|
||||
packet.WriteString(message);
|
||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||
send(packet, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Server::broadcast(Packet& packet)
|
||||
{
|
||||
for (int i = 0; i < MAXCONNECTIONS; ++i) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
||||
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||
packet.ChangePacketID(m_ConnectedUsers[i].PacketID);
|
||||
send(packet, i);
|
||||
}
|
||||
}
|
||||
@@ -148,14 +140,16 @@ void Server::sendSnapshot()
|
||||
// Should time this
|
||||
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
|
||||
for (auto& it : worldComponentPools) {
|
||||
Packet packet(MessageType::Snapshot, m_SendPacketID);
|
||||
std::string componentType = it.first;
|
||||
Packet packet(MessageType::Snapshot);
|
||||
ComponentPool* componentPool = it.second;
|
||||
ComponentInfo componentInfo = componentPool->ComponentInfo();
|
||||
// Component Type
|
||||
packet.WriteString(componentInfo.Name);
|
||||
|
||||
for (auto& componentWrapper : *componentPool) {
|
||||
// Components EntityID
|
||||
packet.WritePrimitive(componentWrapper.EntityID);
|
||||
// Parents EntityID
|
||||
packet.WritePrimitive(m_World->GetParent(componentWrapper.EntityID));
|
||||
for (auto& componentField : componentWrapper.Info.FieldsInOrder) {
|
||||
ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(componentField);
|
||||
if (fieldInfo.Type == "string") {
|
||||
@@ -173,14 +167,14 @@ void Server::sendSnapshot()
|
||||
void Server::sendPing()
|
||||
{
|
||||
// Prints connected players ping
|
||||
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||
int ping = 1000 * (m_StopTimes[i] - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
||||
LOG_INFO("Last packetID received %i: Player %i's ping: %i", m_PacketID, i, ping);
|
||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
||||
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||
int ping = 1000 * (m_ConnectedUsers[i].StopTime - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
||||
LOG_INFO("Last packetID received %i: User %i's ping: %i", m_ConnectedUsers[i].PacketID, i, std::abs(ping));
|
||||
}
|
||||
}
|
||||
// Create ping message
|
||||
Packet packet(MessageType::ServerPing, m_SendPacketID);
|
||||
Packet packet(MessageType::ServerPing);
|
||||
packet.WriteString("Ping from server");
|
||||
// Time message
|
||||
m_StartPingTime = std::clock();
|
||||
@@ -190,16 +184,15 @@ void Server::sendPing()
|
||||
|
||||
void Server::checkForTimeOuts()
|
||||
{
|
||||
int timeOutTimeMs = 5000;
|
||||
int startPing = 1000 * m_StartPingTime
|
||||
/ static_cast<double>(CLOCKS_PER_SEC);
|
||||
|
||||
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||
int stopPing = 1000 * m_StopTimes[i]
|
||||
/ static_cast<double>(CLOCKS_PER_SEC);
|
||||
if (startPing > stopPing + timeOutTimeMs) {
|
||||
LOG_INFO("Player %i timed out!", i);
|
||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
||||
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||
int stopPing = 1000 * m_ConnectedUsers[i].StopTime /
|
||||
static_cast<double>(CLOCKS_PER_SEC);
|
||||
if (startPing > stopPing + TIMEOUTMS) {
|
||||
LOG_INFO("User %i timed out!", i);
|
||||
disconnect(i);
|
||||
}
|
||||
}
|
||||
@@ -208,92 +201,89 @@ void Server::checkForTimeOuts()
|
||||
|
||||
void Server::disconnect(int i)
|
||||
{
|
||||
broadcast("A player disconnected");
|
||||
LOG_INFO("Player %i disconnected/timed out", i);
|
||||
|
||||
// Remove enteties and stuff
|
||||
//broadcast("A player disconnected");
|
||||
LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[i].Name.c_str());
|
||||
// Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have)
|
||||
m_PlayerDefinitions[i].Endpoint = boost::asio::ip::udp::endpoint();
|
||||
m_PlayerDefinitions[i].EntityID = -1;
|
||||
m_PlayerDefinitions[i].Name = "";
|
||||
m_PlayerDefinitions[i].PacketID = 0;
|
||||
m_ConnectedUsers.erase(m_ConnectedUsers.begin() + i);
|
||||
}
|
||||
|
||||
void Server::parseEvent(Packet& packet)
|
||||
void Server::parseOnInputCommand(Packet& packet)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < MAXCONNECTIONS; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
||||
int playerID = -1;
|
||||
// Check which player it was who sent the message
|
||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
||||
// if the player is connected set playerID to the correct PlayerID
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()
|
||||
&& m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) {
|
||||
playerID = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If no player matches the address return.
|
||||
if (i >= 8)
|
||||
return;
|
||||
if (playerID != -1) {
|
||||
while (packet.DataReadSize() < packet.Size()) {
|
||||
Events::InputCommand e;
|
||||
e.Command = packet.ReadString();
|
||||
e.PlayerID = playerID; // Set correct player id
|
||||
e.Value = packet.ReadPrimitive<float>();
|
||||
m_EventBroker->Publish(e);
|
||||
//LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int entityId = m_PlayerDefinitions[i].EntityID;
|
||||
std::string eventString = packet.ReadString();
|
||||
if ("+Forward" == eventString) {
|
||||
m_World->GetComponent(entityId, "Player")["Forward"] = true;
|
||||
m_World->GetComponent(entityId, "Player")["Back"] = false;
|
||||
} else if ("-Forward" == eventString) {
|
||||
m_World->GetComponent(entityId, "Player")["Forward"] = false;
|
||||
m_World->GetComponent(entityId, "Player")["Back"] = true;
|
||||
} else if ("0Forward" == eventString) {
|
||||
m_World->GetComponent(entityId, "Player")["Forward"] = false;
|
||||
m_World->GetComponent(entityId, "Player")["Back"] = false;
|
||||
}
|
||||
if ("+Right" == eventString) {
|
||||
m_World->GetComponent(entityId, "Player")["Left"] = false;
|
||||
m_World->GetComponent(entityId, "Player")["Right"] = true;
|
||||
} else if ("-Right" == eventString) {
|
||||
m_World->GetComponent(entityId, "Player")["Right"] = false;
|
||||
m_World->GetComponent(entityId, "Player")["Left"] = true;
|
||||
} else if ("0Right" == eventString) {
|
||||
m_World->GetComponent(entityId, "Player")["Right"] = false;
|
||||
m_World->GetComponent(entityId, "Player")["Left"] = false;
|
||||
}
|
||||
void Server::parseOnPlayerDamage(Packet & packet)
|
||||
{
|
||||
Events::PlayerDamage e;
|
||||
e.DamageAmount = packet.ReadPrimitive<double>();
|
||||
e.PlayerDamagedID = packet.ReadPrimitive<EntityID>();
|
||||
e.TypeOfDamage = packet.ReadString();
|
||||
m_EventBroker->Publish(e);
|
||||
//LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str());
|
||||
}
|
||||
|
||||
void Server::parseConnect(Packet& packet)
|
||||
{
|
||||
LOG_INFO("Parsing connections");
|
||||
// Check if player is already connected
|
||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
||||
if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
||||
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address() &&
|
||||
m_ConnectedUsers[i].Endpoint.port() == m_ReceiverEndpoint.port()) {
|
||||
// Already connected
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Create a new player
|
||||
PlayerDefinition pd;
|
||||
pd.EntityID = 0; // Overlook this
|
||||
pd.Endpoint = m_ReceiverEndpoint;
|
||||
pd.Name = packet.ReadString();
|
||||
pd.PacketID = 0;
|
||||
pd.StopTime = std::clock();
|
||||
m_ConnectedUsers.push_back(pd);
|
||||
LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str());
|
||||
|
||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() == boost::asio::ip::address()) {
|
||||
// Create new player
|
||||
m_PlayerDefinitions[i].EntityID = createPlayer();
|
||||
m_PlayerDefinitions[i].Endpoint = m_ReceiverEndpoint;
|
||||
m_PlayerDefinitions[i].Name = packet.ReadString();
|
||||
// Send a message to the player that connected
|
||||
Packet connnectPacket(MessageType::Connect, m_ConnectedUsers[m_ConnectedUsers.size() - 1].PacketID);
|
||||
send(connnectPacket);
|
||||
|
||||
m_StopTimes[i] = std::clock();
|
||||
|
||||
LOG_INFO("Player \"%s\" connected on IP: %s", m_PlayerDefinitions[i].Name.c_str(), m_PlayerDefinitions[i].Endpoint.address().to_string().c_str());
|
||||
|
||||
Packet packet(MessageType::Connect, m_SendPacketID);
|
||||
packet.WritePrimitive<int>(i); // Player ID
|
||||
|
||||
send(packet, i);
|
||||
|
||||
// Send notification that a player has connected
|
||||
std::string str = m_PacketID + "Player " + m_PlayerDefinitions[i].Name + " connected on: "
|
||||
+ m_PlayerDefinitions[i].Endpoint.address().to_string();
|
||||
broadcast(str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Send notification that a player has connected
|
||||
Packet notificationPacket(MessageType::PlayerConnected);
|
||||
broadcast(notificationPacket);
|
||||
}
|
||||
|
||||
void Server::parseDisconnect()
|
||||
{
|
||||
LOG_INFO("%i: Parsing disconnect", m_PacketID);
|
||||
|
||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
||||
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
||||
disconnect(i);
|
||||
break;
|
||||
}
|
||||
@@ -303,37 +293,26 @@ void Server::parseDisconnect()
|
||||
void Server::parseClientPing()
|
||||
{
|
||||
LOG_INFO("%i: Parsing ping", m_PacketID);
|
||||
int playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
|
||||
if (playerID == -1) {
|
||||
return;
|
||||
}
|
||||
// Return ping
|
||||
Packet packet(MessageType::ClientPing, m_SendPacketID);
|
||||
Packet packet(MessageType::ClientPing, m_PlayerDefinitions[playerID].PacketID);
|
||||
packet.WriteString("Ping received");
|
||||
send(packet); // This dosen't work for multiple users
|
||||
send(packet);
|
||||
}
|
||||
|
||||
void Server::parseServerPing()
|
||||
{
|
||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
||||
m_StopTimes[i] = std::clock();
|
||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
||||
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
||||
m_ConnectedUsers[i].StopTime = std::clock();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOT USED
|
||||
void Server::parseSnapshot(Packet& packet)
|
||||
{
|
||||
// Does no logic. Returns snapshot if client request one
|
||||
// The snapshot is not a real snapshot tho...
|
||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||
m_Socket.send_to(
|
||||
boost::asio::buffer("I'm sending a snapshot to you guys!"),
|
||||
m_PlayerDefinitions[i].Endpoint,
|
||||
0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Server::identifyPacketLoss()
|
||||
{
|
||||
// if no packets lost, difference should be equal to 1
|
||||
@@ -343,14 +322,56 @@ void Server::identifyPacketLoss()
|
||||
}
|
||||
}
|
||||
|
||||
EntityID Server::createPlayer()
|
||||
void Server::createPlayer()
|
||||
{
|
||||
EntityID entityID = m_World->CreateEntity();
|
||||
ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform");
|
||||
transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f);
|
||||
ComponentWrapper model = m_World->AttachComponent(entityID, "Model");
|
||||
model["Resource"] = "Models/Core/UnitSphere.obj";
|
||||
model["Color"] = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand() %255 / 255.f, 1.f);
|
||||
ComponentWrapper player = m_World->AttachComponent(entityID, "Player");
|
||||
return entityID;
|
||||
if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) {
|
||||
// Already connected as player
|
||||
LOG_WARNING("Already connected!");
|
||||
return;
|
||||
}
|
||||
int userIndex;
|
||||
for (userIndex = 0; userIndex < m_ConnectedUsers.size(); userIndex++) {
|
||||
if (m_ConnectedUsers[userIndex].Endpoint.address() == m_ReceiverEndpoint.address() &&
|
||||
m_ConnectedUsers[userIndex].Endpoint.port() == m_ReceiverEndpoint.port()) {
|
||||
// Found user
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (userIndex == m_ConnectedUsers.size()) {
|
||||
LOG_WARNING("Not a recognized user!");
|
||||
return;
|
||||
}
|
||||
for (int playerIndex = 0; playerIndex < MAXCONNECTIONS; playerIndex++) {
|
||||
if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) {
|
||||
m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex];
|
||||
EntityID entityID = m_World->CreateEntity();
|
||||
ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform");
|
||||
transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f);
|
||||
ComponentWrapper model = m_World->AttachComponent(entityID, "Model");
|
||||
model["Resource"] = "Models/Core/UnitSphere.obj";
|
||||
model["Color"] = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand() %255 / 255.f, 1.f);
|
||||
ComponentWrapper player = m_World->AttachComponent(entityID, "Player");
|
||||
m_PlayerDefinitions[playerIndex].EntityID = entityID;
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOG_WARNING("Server is full!");
|
||||
|
||||
}
|
||||
|
||||
int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
|
||||
{
|
||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
||||
if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() &&
|
||||
m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool Server::OnInputCommand(const Events::InputCommand & e)
|
||||
{
|
||||
//LOG_DEBUG("Server::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -40,15 +40,14 @@ void LightCullingPass::OnResolutionChange()
|
||||
|
||||
void LightCullingPass::SetSSBOSizes()
|
||||
{
|
||||
m_NumberOfTiles = (int)(m_Renderer->Resolution().Width*m_Renderer->Resolution().Height)/TILE_SIZE;
|
||||
|
||||
//m_Frustums = new Frustum[s];
|
||||
//m_LightGrid = new LightGrid[s];
|
||||
//m_LightIndex = new float[s*200];
|
||||
m_NumberOfTiles = (int)(m_Renderer->Resolution().Width/TILE_SIZE) * (int)(m_Renderer->Resolution().Height/TILE_SIZE);
|
||||
|
||||
m_Frustums = new Frustum[m_NumberOfTiles];
|
||||
m_LightGrid = new LightGrid[m_NumberOfTiles];
|
||||
m_LightIndex = new float[m_NumberOfTiles*MAX_LIGHTS_PER_TILE];
|
||||
for (int i = 0; i < m_NumberOfTiles*MAX_LIGHTS_PER_TILE; i++) {
|
||||
m_LightIndex[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void LightCullingPass::CullLights(RenderScene& scene)
|
||||
@@ -59,8 +58,8 @@ void LightCullingPass::CullLights(RenderScene& scene)
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
|
||||
if (m_PointLights.size() > 0) {
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(PointLight) * m_PointLights.size(), &(m_PointLights[0]), GL_DYNAMIC_COPY);
|
||||
if (m_LightSources.size() > 0) {
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightSource) * m_LightSources.size(), &(m_LightSources[0]), GL_DYNAMIC_COPY);
|
||||
} else {
|
||||
GLfloat zero = 0.f;
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat), &zero , GL_DYNAMIC_COPY);
|
||||
@@ -75,27 +74,38 @@ void LightCullingPass::CullLights(RenderScene& scene)
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO);
|
||||
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO);
|
||||
glDispatchCompute(m_Renderer->Resolution().Width / TILE_SIZE, m_Renderer->Resolution().Height / TILE_SIZE, 1);
|
||||
glDispatchCompute(glm::ceil(m_Renderer->Resolution().Width / TILE_SIZE), glm::ceil(m_Renderer->Resolution().Height / TILE_SIZE), 1);
|
||||
|
||||
GLERROR("CullLights Error: End");
|
||||
}
|
||||
|
||||
void LightCullingPass::FillLightList(RenderScene& scene)
|
||||
{
|
||||
m_PointLights.clear();
|
||||
m_LightSources.clear();
|
||||
|
||||
for(auto &job : scene.PointLightJobs) {
|
||||
auto pointLightjob = std::dynamic_pointer_cast<PointLightJob>(job);
|
||||
if (pointLightjob) {
|
||||
PointLight p;
|
||||
LightSource p;
|
||||
p.Color = pointLightjob->Color;
|
||||
p.Falloff = pointLightjob->Falloff;
|
||||
p.Intensity = pointLightjob->Intensity;
|
||||
p.Position = glm::vec4(glm::vec3(pointLightjob->Position), 1.f);
|
||||
p.Radius = pointLightjob->Radius;
|
||||
p.Padding = 123.f;
|
||||
m_PointLights.push_back(p);
|
||||
continue;
|
||||
//p.Padding = 123.f;
|
||||
p.Type = LightSource::Point;
|
||||
m_LightSources.push_back(p);
|
||||
}
|
||||
}
|
||||
for(auto &job : scene.DirectionalLightJobs) {
|
||||
auto directionalLightJob = std::dynamic_pointer_cast<DirectionalLightJob>(job);
|
||||
if(directionalLightJob) {
|
||||
LightSource p;
|
||||
p.Direction = directionalLightJob->Direction;
|
||||
p.Color = directionalLightJob->Color;
|
||||
p.Intensity = directionalLightJob->Intensity;
|
||||
p.Type = LightSource::Directional;
|
||||
m_LightSources.push_back(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,25 +114,22 @@ void LightCullingPass::InitializeSSBOs()
|
||||
{
|
||||
glGenBuffers(1, &m_FrustumSSBO);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Frustum)*m_NumberOfTiles, m_Frustums, GL_DYNAMIC_COPY);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(Frustum)*m_NumberOfTiles, nullptr, GL_DYNAMIC_COPY);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||
GLERROR("m_FrustumSSBO");
|
||||
|
||||
glGenBuffers(1, &m_LightSSBO);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO);
|
||||
if(m_PointLights.size() > 0) {
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(PointLight) * m_PointLights.size(), &(m_PointLights[0]), GL_DYNAMIC_COPY);
|
||||
}
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightSource) * 200, nullptr, GL_DYNAMIC_COPY);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||
GLERROR("m_LightSSBO");
|
||||
|
||||
glGenBuffers(1, &m_LightGridSSBO);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightGrid)*m_NumberOfTiles, m_LightGrid, GL_DYNAMIC_COPY);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(LightGrid)*m_NumberOfTiles, nullptr, GL_DYNAMIC_COPY);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
||||
GLERROR("m_LightGridSSBO");
|
||||
|
||||
|
||||
glGenBuffers(1, &m_LightOffsetSSBO);
|
||||
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO);
|
||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY);
|
||||
|
||||
@@ -114,25 +114,45 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World
|
||||
}
|
||||
|
||||
|
||||
void RenderSystem::fillLight(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
|
||||
void RenderSystem::fillPointLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
|
||||
{
|
||||
auto pointLights = world->GetComponents("PointLight");
|
||||
if (pointLights == nullptr) {
|
||||
return;
|
||||
if (pointLights != nullptr) {
|
||||
for (auto& pointlightC : *pointLights) {
|
||||
bool visible = pointlightC["Visible"];
|
||||
if (!visible) {
|
||||
continue;
|
||||
}
|
||||
auto transformC = world->GetComponent(pointlightC.EntityID, "Transform");
|
||||
if (&transformC == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::shared_ptr<PointLightJob> pointLightJob = std::shared_ptr<PointLightJob>(new PointLightJob(transformC, pointlightC, m_World));
|
||||
jobs.push_back(pointLightJob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& pointlightC : *pointLights) {
|
||||
bool visible = pointlightC["Visible"];
|
||||
if (!visible) {
|
||||
continue;
|
||||
}
|
||||
auto transformC = world->GetComponent(pointlightC.EntityID, "Transform");
|
||||
if (&transformC == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<PointLightJob> pointLightJob = std::shared_ptr<PointLightJob>(new PointLightJob(transformC, pointlightC, m_World));
|
||||
jobs.push_back(pointLightJob);
|
||||
void RenderSystem::fillDirectionalLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
|
||||
{
|
||||
auto directionalLights = world->GetComponents("DirectionalLight");
|
||||
if (directionalLights != nullptr) {
|
||||
for (auto& directionalLightC : *directionalLights) {
|
||||
bool visable = directionalLightC["Visible"];
|
||||
if (!visable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto transformC = world->GetComponent(directionalLightC.EntityID, "Transform");
|
||||
if (&transformC == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::shared_ptr<DirectionalLightJob> directionalLightJob = std::shared_ptr<DirectionalLightJob>(new DirectionalLightJob(transformC, directionalLightC, m_World));
|
||||
jobs.push_back(directionalLightJob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +180,8 @@ void RenderSystem::Update(World* world, double dt)
|
||||
scene.Camera = m_Camera;
|
||||
scene.Viewport = Rectangle(1280, 720);
|
||||
fillModels(scene.ForwardJobs, world);
|
||||
fillLight(scene.PointLightJobs, world);
|
||||
fillPointLights(scene.PointLightJobs, world);
|
||||
fillDirectionalLights(scene.DirectionalLightJobs, world);
|
||||
m_RenderFrame->Add(scene);
|
||||
|
||||
}
|
||||
|
||||
@@ -98,9 +98,8 @@ void Renderer::Draw(RenderFrame& frame)
|
||||
|
||||
m_PickingPass->ClearPicking();
|
||||
for (auto scene : frame.RenderScenes){
|
||||
|
||||
m_Camera = scene->Camera; // remove renderer camera when Editor uses the render scene cameras.
|
||||
FillDepth(*scene);
|
||||
SortRenderJobsByDepth(*scene);
|
||||
m_PickingPass->Draw(*scene);
|
||||
m_LightCullingPass->GenerateNewFrustum(*scene);
|
||||
m_LightCullingPass->FillLightList(*scene);
|
||||
@@ -147,6 +146,13 @@ void Renderer::InitializeTextures()
|
||||
m_WhiteTexture = ResourceManager::Load<Texture>("Textures/Core/Blank.png");
|
||||
}
|
||||
|
||||
|
||||
void Renderer::SortRenderJobsByDepth(RenderScene &scene)
|
||||
{
|
||||
//Sort all forward jobs so transparency is good.
|
||||
scene.ForwardJobs.sort(Renderer::DepthSort);
|
||||
}
|
||||
|
||||
void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type)
|
||||
{
|
||||
glGenTextures(1, texture);
|
||||
@@ -165,21 +171,4 @@ void Renderer::InitializeRenderPasses()
|
||||
m_PickingPass = new PickingPass(this, m_EventBroker);
|
||||
m_LightCullingPass = new LightCullingPass(this);
|
||||
m_DrawFinalPass = new DrawFinalPass(this, m_LightCullingPass);
|
||||
}
|
||||
|
||||
//Temp func
|
||||
void Renderer::FillDepth(RenderScene& scene)
|
||||
{
|
||||
for (auto job : scene.ForwardJobs) {
|
||||
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
||||
if(! modelJob) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
glm::vec3 abspos = Transform::AbsolutePosition(modelJob->World, modelJob->Entity);
|
||||
glm::vec3 worldpos = glm::vec3(scene.Camera->ViewMatrix() * glm::vec4(abspos, 1));
|
||||
modelJob->Depth = worldpos.z;
|
||||
}
|
||||
scene.ForwardJobs.sort(Renderer::DepthSort);
|
||||
}
|
||||
@@ -26,7 +26,9 @@ set(SOURCE_FILES
|
||||
${SOURCE_FILES}
|
||||
"Game.cpp"
|
||||
${SOURCE_FILES_Systems}
|
||||
${SOURCE_FILES_Events}
|
||||
${SOURCE_FILES_Events}
|
||||
|
||||
|
||||
)
|
||||
|
||||
set(LIBRARIES
|
||||
|
||||
+5
-4
@@ -8,6 +8,7 @@
|
||||
#include "Systems/SpawnerSystem.h"
|
||||
#include "Systems/PlayerSpawnSystem.h"
|
||||
#include "Core/EntityFileWriter.h"
|
||||
#include "Game/Systems/CapturePointSystem.h"
|
||||
|
||||
Game::Game(int argc, char* argv[])
|
||||
{
|
||||
@@ -29,7 +30,7 @@ Game::Game(int argc, char* argv[])
|
||||
|
||||
|
||||
// Create the renderer
|
||||
m_Renderer = new Renderer(m_EventBroker, m_World);
|
||||
m_Renderer = new Renderer(m_EventBroker);
|
||||
m_Renderer->SetFullscreen(m_Config->Get<bool>("Video.Fullscreen", false));
|
||||
m_Renderer->SetVSYNC(m_Config->Get<bool>("Video.VSYNC", false));
|
||||
m_Renderer->SetResolution(Rectangle::Rectangle(
|
||||
@@ -64,8 +65,7 @@ Game::Game(int argc, char* argv[])
|
||||
EntityFileParser fp(file);
|
||||
fp.MergeEntities(m_World);
|
||||
}
|
||||
//SO MUCH TEMP PLEASE REMOVE ME OMFG VIKTOR HELP
|
||||
m_Renderer->m_World = m_World;
|
||||
|
||||
|
||||
// Create Octrees
|
||||
m_OctreeCollision = new Octree<AABB>(AABB(glm::vec3(-100), glm::vec3(100)), 4);
|
||||
@@ -79,6 +79,7 @@ Game::Game(int argc, char* argv[])
|
||||
m_SystemPipeline->AddSystem<EditorSystem>(updateOrderLevel, m_Renderer);
|
||||
m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<PlayerSpawnSystem>(updateOrderLevel);
|
||||
// Populate Octree with collidables
|
||||
@@ -89,6 +90,7 @@ Game::Game(int argc, char* argv[])
|
||||
m_SystemPipeline->AddSystem<CollisionSystem>(updateOrderLevel, m_OctreeCollision);
|
||||
m_SystemPipeline->AddSystem<TriggerSystem>(updateOrderLevel, m_OctreeCollision);
|
||||
++updateOrderLevel;
|
||||
m_SystemPipeline->AddSystem<CapturePointSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<RenderSystem>(updateOrderLevel, m_Renderer, m_RenderFrame);
|
||||
|
||||
// Invoke network
|
||||
@@ -144,7 +146,6 @@ void Game::Tick()
|
||||
m_SystemPipeline->Update(m_World, dt);
|
||||
debugTick(dt);
|
||||
m_Renderer->Update(dt);
|
||||
m_EventBroker->Process<Client>();
|
||||
m_SoundSystem->Update(dt);
|
||||
GLERROR("Game::Tick m_RenderQueueFactory->Update");
|
||||
m_Renderer->Draw(*m_RenderFrame);
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
#include "Systems/CapturePointSystem.h"
|
||||
#include <algorithm>
|
||||
|
||||
CapturePointSystem::CapturePointSystem(EventBroker* eventBroker)
|
||||
: System(eventBroker),
|
||||
PureSystem("CapturePoint")
|
||||
{
|
||||
//subscribe/listenTo playerdamage,healthpickup events (using the eventBroker)
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &CapturePointSystem::OnTriggerTouch);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ETriggerLeave, &CapturePointSystem::OnTriggerLeave);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointSystem::OnCaptured);
|
||||
}
|
||||
|
||||
//here all capturepoints will update their component
|
||||
//NOTE: needs to run each frame, since we're possibly modifying the captureTimer for the capturePoints by dt
|
||||
void CapturePointSystem::UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& capturePoint, double dt)
|
||||
{
|
||||
if (m_WinnerWasFound) {
|
||||
return;
|
||||
}
|
||||
const int capturePointNumber = capturePoint["CapturePointNumber"];
|
||||
const bool hasTeamComponent = world->HasComponent(capturePoint.EntityID, "Team");
|
||||
|
||||
//if point doesnt have a teamComponent yet, add one. since:
|
||||
//what if capture point has no team -> we cant get/use the team enum from it...
|
||||
if (!hasTeamComponent) {
|
||||
world->AttachComponent(capturePoint.EntityID, "Team");
|
||||
ComponentWrapper& teamComponent = world->GetComponent(capturePoint.EntityID, "Team");
|
||||
teamComponent["Team"] = (int)teamComponent["Team"].Enum("Spectator");
|
||||
}
|
||||
ComponentWrapper& teamComponent = world->GetComponent(capturePoint.EntityID, "Team");
|
||||
const int redTeam = (int)teamComponent["Team"].Enum("Red");
|
||||
const int blueTeam = (int)teamComponent["Team"].Enum("Blue");
|
||||
const int spectatorTeam = (int)teamComponent["Team"].Enum("Spectator");
|
||||
|
||||
int homePointForTeam = (int)capturePoint["HomePointForTeam"];
|
||||
if (m_NumberOfCapturePoints == 0 && capturePointNumber != 0 && (homePointForTeam == redTeam || homePointForTeam == blueTeam)) {
|
||||
m_NumberOfCapturePoints = capturePointNumber + 1;//ex 2 -> 0,1,2 = 3
|
||||
if (homePointForTeam == redTeam) {
|
||||
m_RedTeamHomeCapturePoint = capturePointNumber;
|
||||
m_BlueTeamHomeCapturePoint = 0;
|
||||
} else {
|
||||
m_BlueTeamHomeCapturePoint = capturePointNumber;
|
||||
m_RedTeamHomeCapturePoint = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//if we havent received all capturepoints yet, just return
|
||||
if (m_NumberOfCapturePoints == 0 || m_NumberOfCapturePoints != m_CapturePointNumberToEntityIDMap.size()) {
|
||||
m_CapturePointNumberToEntityIDMap.insert(std::make_pair(capturePointNumber, capturePoint.EntityID));
|
||||
return;
|
||||
}
|
||||
|
||||
//we have all capturepoints now - process stuff
|
||||
int ownedBy = teamComponent["Team"];
|
||||
int redTeamPlayersStandingInside = 0;
|
||||
int blueTeamPlayersStandingInside = 0;
|
||||
if (entity.HasComponent("Model")) {
|
||||
//Now sets team color to the capturepoint, or white if it is uncaptured.
|
||||
entity["Model"]["Color"] = ownedBy == blueTeam ? glm::vec4(0, 0.2f, 1, 1) : ownedBy == redTeam ? glm::vec4(1, 0.2f, 0, 1) : glm::vec4(1, 1, 1, 1);
|
||||
}
|
||||
|
||||
//calculate next possible capturePoint for both teams
|
||||
std::map<std::string, int> nextPossibleCapturePoint;
|
||||
nextPossibleCapturePoint["Red"] = -1;
|
||||
nextPossibleCapturePoint["Blue"] = -1;
|
||||
for (size_t i = 0; i < m_NumberOfCapturePoints; i++)
|
||||
{
|
||||
ComponentWrapper& capturePointOwnedBy = world->GetComponent(m_CapturePointNumberToEntityIDMap[i], "Team");
|
||||
if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint == 0) {
|
||||
nextPossibleCapturePoint["Red"] = i + 1;
|
||||
}
|
||||
if ((int)capturePointOwnedBy["Team"] == blueTeam && m_BlueTeamHomeCapturePoint == 0) {
|
||||
nextPossibleCapturePoint["Blue"] = i + 1;
|
||||
}
|
||||
}
|
||||
for (int i = m_NumberOfCapturePoints - 1; i >= 0; i--)
|
||||
{
|
||||
ComponentWrapper& capturePointOwnedBy = world->GetComponent(m_CapturePointNumberToEntityIDMap[i], "Team");
|
||||
if ((int)capturePointOwnedBy["Team"] == redTeam && m_RedTeamHomeCapturePoint != 0) {
|
||||
nextPossibleCapturePoint["Red"] = i - 1;
|
||||
}
|
||||
if ((int)capturePointOwnedBy["Team"] == blueTeam && m_BlueTeamHomeCapturePoint != 0) {
|
||||
nextPossibleCapturePoint["Blue"] = i - 1;
|
||||
}
|
||||
}
|
||||
|
||||
//reset timers and reset the bool that triggers this
|
||||
if (m_ResetTimers) {
|
||||
for (size_t i = 0; i < m_NumberOfCapturePoints; i++)
|
||||
{
|
||||
ComponentWrapper& capturePoint = world->GetComponent(m_CapturePointNumberToEntityIDMap[i], "CapturePoint");
|
||||
if ((int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Red"] &&
|
||||
(int)capturePoint["CapturePointNumber"] != nextPossibleCapturePoint["Blue"]) {
|
||||
capturePoint["CaptureTimer"] = 0.0;
|
||||
}
|
||||
}
|
||||
m_ResetTimers = false;
|
||||
}
|
||||
|
||||
//colorize next possible capturepoint
|
||||
if (nextPossibleCapturePoint["Red"] == capturePointNumber) {
|
||||
entity["Model"]["Color"] = glm::vec4(1, 1, 0, 1);
|
||||
}
|
||||
if (nextPossibleCapturePoint["Blue"] == capturePointNumber) {
|
||||
entity["Model"]["Color"] = glm::vec4(0, 1, 1, 1);
|
||||
}
|
||||
|
||||
//check how many players are standing inside and are healthy
|
||||
for (size_t i = m_ETriggerTouchVector.size(); i > 0; i--)
|
||||
{
|
||||
auto triggerTouched = m_ETriggerTouchVector[i - 1];
|
||||
if (std::get<1>(triggerTouched) == capturePoint.EntityID) {
|
||||
//some player has touched this - lets figure out: what team, health
|
||||
EntityID playerID = std::get<0>(triggerTouched);
|
||||
if (!world->HasComponent(playerID, "Player")) {
|
||||
//if a non-player has entered the capturePoint, just erase that event and continue
|
||||
m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i - 1);
|
||||
continue;
|
||||
}
|
||||
bool hasHealthComponent = world->HasComponent(playerID, "Health");
|
||||
if (hasHealthComponent) {
|
||||
double currentHealth = world->GetComponent(playerID, "Health")["Health"];
|
||||
//check if player is dead
|
||||
if ((int)currentHealth == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//check team - spectatorNumber = "no team"
|
||||
int teamNumber = world->GetComponent(playerID, "Team")["Team"];
|
||||
if (teamNumber == redTeam) {
|
||||
redTeamPlayersStandingInside++;
|
||||
} else if (teamNumber == blueTeam) {
|
||||
blueTeamPlayersStandingInside++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//create data to be used in option B
|
||||
//check so this is the next possible capture point for the take-over team and see if only one team is standing inside it
|
||||
double timerDeltaChange = 0.0;
|
||||
int currentTeam = 0;
|
||||
bool canCapture = false;
|
||||
if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside == 0) {
|
||||
timerDeltaChange = redTeamPlayersStandingInside*dt;
|
||||
currentTeam = redTeam;
|
||||
canCapture = nextPossibleCapturePoint["Red"] == capturePointNumber;
|
||||
}
|
||||
if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside > 0) {
|
||||
timerDeltaChange = -blueTeamPlayersStandingInside*dt;
|
||||
currentTeam = blueTeam;
|
||||
canCapture = nextPossibleCapturePoint["Blue"] == capturePointNumber;
|
||||
}
|
||||
|
||||
if (redTeamPlayersStandingInside == 0 && blueTeamPlayersStandingInside == 0) {
|
||||
//A.nobodys standing inside
|
||||
//do nothing (?)
|
||||
} else if (redTeamPlayersStandingInside > 0 && blueTeamPlayersStandingInside > 0) {
|
||||
//C.both teams have players inside
|
||||
//do nothing (?)
|
||||
} else {
|
||||
//B. at most one of the teams have players inside
|
||||
//if capturePoint is not owned by the take-over team, just modify the CaptureTimer accordingly
|
||||
if (ownedBy != currentTeam && canCapture) {
|
||||
if (abs((double)capturePoint["CaptureTimer"]) < 0.001f) {
|
||||
LOG_DEBUG("Point is being captured by team %i", currentTeam); //Remove when we tested sufficiently.
|
||||
}
|
||||
capturePoint["CaptureTimer"] = (double)capturePoint["CaptureTimer"] + timerDeltaChange;
|
||||
}
|
||||
//if capturePoint is owned by the team, and the other team has been trying to take it, then increase/decrease the timer towards 0.0
|
||||
if ((ownedBy == currentTeam && currentTeam == redTeam && (double)capturePoint["CaptureTimer"] < 0.0) ||
|
||||
(ownedBy == currentTeam && currentTeam == blueTeam && (double)capturePoint["CaptureTimer"] > 0.0)) {
|
||||
capturePoint["CaptureTimer"] = (double)capturePoint["CaptureTimer"] + timerDeltaChange;
|
||||
}
|
||||
//check if captureTimer > m_CaptureTimeToTakeOver and if so change owner and publish the eCaptured event
|
||||
if (abs((double)capturePoint["CaptureTimer"]) > abs(m_CaptureTimeToTakeOver) && canCapture) {
|
||||
teamComponent["Team"] = currentTeam;
|
||||
capturePoint["CaptureTimer"] = 0.0;
|
||||
//publish Captured event
|
||||
LOG_DEBUG("Point is captured by team %i!", currentTeam); //Remove when we tested sufficiently.
|
||||
Events::Captured e;
|
||||
e.CapturePointID = capturePoint.EntityID;
|
||||
e.TeamNumberThatCapturedCapturePoint = currentTeam;
|
||||
m_EventBroker->Publish(e);
|
||||
//NextPossibleCapturePoint will be calculated in the next update...
|
||||
}
|
||||
}
|
||||
|
||||
//check for possible winCondition = check if the homebase is owned by the other team
|
||||
bool checkForWinner = false;
|
||||
if (capturePointNumber == m_RedTeamHomeCapturePoint && ownedBy != redTeam)
|
||||
{
|
||||
checkForWinner = true;
|
||||
}
|
||||
if (capturePointNumber == m_BlueTeamHomeCapturePoint && ownedBy != blueTeam)
|
||||
{
|
||||
checkForWinner = true;
|
||||
}
|
||||
|
||||
if (checkForWinner && !m_WinnerWasFound)
|
||||
{
|
||||
//publish Win event
|
||||
Events::Win e;
|
||||
e.TeamThatWon = ownedBy;
|
||||
m_EventBroker->Publish(e);
|
||||
m_WinnerWasFound = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e)
|
||||
{
|
||||
//personEntered = e.Entity, thingEntered = e.Trigger
|
||||
m_ETriggerTouchVector.push_back(std::make_tuple(e.Entity, e.Trigger));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CapturePointSystem::OnTriggerLeave(const Events::TriggerLeave& e)
|
||||
{
|
||||
for (size_t i = 0; i < m_ETriggerTouchVector.size(); i++)
|
||||
{
|
||||
auto triggerTouched = m_ETriggerTouchVector[i];
|
||||
if (std::get<0>(triggerTouched) == e.Entity && std::get<1>(triggerTouched) == e.Trigger) {
|
||||
m_ETriggerTouchVector.erase(m_ETriggerTouchVector.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool CapturePointSystem::OnCaptured(const Events::Captured& e)
|
||||
{
|
||||
//reset the timers in the next update since a capture has changed the "nextCapturePoint" for 1-2 teams
|
||||
m_ResetTimers = true;
|
||||
return true;
|
||||
}
|
||||
@@ -12,7 +12,6 @@ HealthSystem::HealthSystem(EventBroker* eventBroker)
|
||||
void HealthSystem::UpdateComponent(World* world, EntityWrapper& entity, ComponentWrapper& component, double dt)
|
||||
{
|
||||
//if entityID of health is 9 then the players ID is also 9 (player,health are connected to the same entity)
|
||||
ComponentWrapper player = world->GetComponent(component.EntityID, "Player");
|
||||
double maxHealth = (double)component["MaxHealth"];
|
||||
|
||||
//process the DeltaHealthVector and change the entitys health accordingly
|
||||
@@ -20,24 +19,26 @@ void HealthSystem::UpdateComponent(World* world, EntityWrapper& entity, Componen
|
||||
{
|
||||
auto deltaHP = m_DeltaHealthVector[i - 1];
|
||||
//if we have a healthchange for the current player and health is greater than 0, then apply it
|
||||
if (std::get<0>(deltaHP) == player.EntityID && (double)component["Health"] > 0.0f) {
|
||||
if (std::get<0>(deltaHP) == component.EntityID && (double)component["Health"] > 0.0f) {
|
||||
//get the deltaHP value from the tuple and make sure you dont get more than maxHealth
|
||||
double newHealth = std::min((double)component["Health"] + (double)std::get<1>(deltaHP), maxHealth);
|
||||
component["Health"] = newHealth;
|
||||
m_DeltaHealthVector.erase(m_DeltaHealthVector.begin() + i - 1);
|
||||
//check if health is <= 0
|
||||
if ((double)component["Health"] <= 0.0f) {
|
||||
component["Health"] = 0.0;
|
||||
//publish death event
|
||||
Events::PlayerDeath e;
|
||||
e.PlayerID = player.EntityID;
|
||||
e.PlayerID = component.EntityID;
|
||||
m_EventBroker->Publish(e);
|
||||
//clear the remaining hpDeltas for the dead player
|
||||
for (size_t j = m_DeltaHealthVector.size(); j > 0; j--)
|
||||
{
|
||||
if (std::get<0>(m_DeltaHealthVector[j - 1]) == player.EntityID)
|
||||
if (std::get<0>(m_DeltaHealthVector[j - 1]) == component.EntityID)
|
||||
m_DeltaHealthVector.erase(m_DeltaHealthVector.begin() + j - 1);
|
||||
}
|
||||
//break the loop if the player is dead
|
||||
//delete the player and break the loop
|
||||
world->DeleteEntity(entity.ID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -57,3 +58,4 @@ bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e)
|
||||
m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerHealedID, e.HealthAmount));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "Systems/InterpolationSystem.h"
|
||||
|
||||
//void InterpolationSystem::UpdateComponent(World * world, ComponentWrapper & transform, double dt)
|
||||
//{
|
||||
// if (m_InterpolationPoints[transform.EntityID].size() > 0) {
|
||||
// Transform& sTransform = m_InterpolationPoints[transform.EntityID].front();
|
||||
// sTransform.interpolationTime += dt;
|
||||
// if (sTransform.interpolationTime > 0.05) {
|
||||
// double time = std::fmod(sTransform.interpolationTime, 0.05f);
|
||||
// m_InterpolationPoints[transform.EntityID].pop();
|
||||
// if (m_InterpolationPoints[transform.EntityID].size() <= 0) {
|
||||
// return;
|
||||
// }
|
||||
// sTransform = m_InterpolationPoints[transform.EntityID].front();
|
||||
// sTransform.interpolationTime = time;
|
||||
// }
|
||||
// glm::vec3 nextPosition = sTransform.Position;
|
||||
// glm::vec3 currentPosition = static_cast<glm::vec3>(transform["Position"]);
|
||||
// transform["Position"] = vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime);
|
||||
// }
|
||||
//}
|
||||
|
||||
void InterpolationSystem::UpdateComponent(World * world, EntityWrapper& entity, ComponentWrapper & transform, double dt)
|
||||
{
|
||||
if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map
|
||||
m_NextTransform[transform.EntityID].interpolationTime += dt;
|
||||
Transform sTransform = m_NextTransform[transform.EntityID];
|
||||
double time = sTransform.interpolationTime;
|
||||
if (time > SNAPSHOTINTERVAL) {
|
||||
if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) {
|
||||
m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID];
|
||||
m_NextTransform[transform.EntityID].interpolationTime = time - SNAPSHOTINTERVAL;
|
||||
sTransform = m_NextTransform[transform.EntityID];
|
||||
m_LastReceivedTransform.erase(transform.EntityID);
|
||||
} else {
|
||||
m_NextTransform.erase(transform.EntityID);
|
||||
}
|
||||
}
|
||||
if (transform.Info.Name == "Transform") {
|
||||
// Position
|
||||
glm::vec3 nextPosition = sTransform.Position;
|
||||
glm::vec3 currentPosition = static_cast<glm::vec3>(transform["Position"]);
|
||||
(glm::vec3&)transform["Position"] += vectorInterpolation<glm::vec3>(currentPosition, nextPosition, sTransform.interpolationTime);
|
||||
// Orientation
|
||||
glm::quat nextOrientation = sTransform.Orientation;
|
||||
glm::quat currentOrientation = glm::quat(static_cast<glm::vec3>(transform["Orientation"]));
|
||||
(glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp<float>(currentOrientation, nextOrientation, sTransform.interpolationTime / SNAPSHOTINTERVAL));
|
||||
// Scale
|
||||
glm::vec3 nextScale = sTransform.Scale;
|
||||
glm::vec3 currentScale = static_cast<glm::vec3>(transform["Scale"]);
|
||||
(glm::vec3&)transform["Scale"] += vectorInterpolation<glm::vec3>(currentScale, nextScale, sTransform.interpolationTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e)
|
||||
{
|
||||
Transform transform;
|
||||
int offset = 0;
|
||||
// Read the data
|
||||
memcpy(&transform.Position, e.DataArray.get() + offset, sizeof(glm::vec3));
|
||||
offset += sizeof(glm::vec3);
|
||||
glm::vec3 tempOrientation;
|
||||
memcpy(&tempOrientation, e.DataArray.get() + offset, sizeof(glm::vec3));
|
||||
transform.Orientation = glm::quat(tempOrientation);
|
||||
offset += sizeof(glm::vec3);
|
||||
memcpy(&transform.Scale, e.DataArray.get() + offset, sizeof(glm::vec3));
|
||||
transform.interpolationTime = 0.0f;
|
||||
|
||||
if (m_NextTransform.find(e.Entity) != m_NextTransform.end()) { // Did exist
|
||||
m_LastReceivedTransform[e.Entity] = transform;
|
||||
} else { // Did not
|
||||
m_NextTransform[e.Entity] = transform;
|
||||
}
|
||||
// Check if queue already exists
|
||||
//if (m_InterpolationPoints.find(e.Entity) != m_InterpolationPoints.end()) { // Did exist, push to queue
|
||||
// m_InterpolationPoints[e.Entity].push(transform);
|
||||
//}
|
||||
|
||||
//else { // Did not exist, create queue
|
||||
// std::queue<Transform> transformQueue;
|
||||
// transformQueue.push(transform);
|
||||
// m_InterpolationPoints[e.Entity] = transformQueue;
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
using boost::unit_test_framework::test_suite;
|
||||
using boost::unit_test_framework::test_case;
|
||||
|
||||
#include "CapturePointTest.h"
|
||||
#include "Game/Systems/HealthSystem.h"
|
||||
|
||||
#include "Collision/TriggerSystem.h"
|
||||
#include "Collision/CollisionSystem.h"
|
||||
#include "Core/EntityFileWriter.h"
|
||||
#include "Game/Systems/CapturePointSystem.h"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(CapturePointTestSuite)
|
||||
|
||||
//dont use the same name as the classname in test cases...
|
||||
BOOST_AUTO_TEST_CASE(CapturePointTest1_OnePlayerOnCapturePoint)
|
||||
{
|
||||
CapturePointTest game(1);
|
||||
bool success = game.CapturePoint_Game_Loop_OneHundredTimes();
|
||||
BOOST_TEST(success);
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(CapturePointTest2_TwoPlayersOnCapturePoint)
|
||||
{
|
||||
CapturePointTest game(2);
|
||||
bool success = game.CapturePoint_Game_Loop_OneHundredTimes();
|
||||
BOOST_TEST(success);
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(CapturePointTest3_NoPlayersOnCapturePoint)
|
||||
{
|
||||
CapturePointTest game(3);
|
||||
bool success = game.CapturePoint_Game_Loop_OneHundredTimes();
|
||||
BOOST_TEST(success);
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(CapturePointTest4_TwoCapturePointsBeingCaptured)
|
||||
{
|
||||
CapturePointTest game(4);
|
||||
bool success = game.CapturePoint_Game_Loop_OneHundredTimes();
|
||||
BOOST_TEST(success);
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(CapturePointTest5_SameCapturePointContestedAndTakenOver)
|
||||
{
|
||||
CapturePointTest game(5);
|
||||
bool success = game.CapturePoint_Game_Loop_OneHundredTimes();
|
||||
BOOST_TEST(success);
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(CapturePointTest6_Team1CapturedTheLastPointAndWon)
|
||||
{
|
||||
CapturePointTest game(6);
|
||||
bool success = game.CapturePoint_Game_Loop_OneHundredTimes();
|
||||
BOOST_TEST(success);
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(CapturePointTest7_Team1ForcesTeam2sNextCapturePointToGoBackwards1Step)
|
||||
{
|
||||
CapturePointTest game(7);
|
||||
bool success = game.CapturePoint_Game_Loop_OneHundredTimes();
|
||||
BOOST_TEST(success);
|
||||
}
|
||||
BOOST_AUTO_TEST_CASE(CapturePointTest8_Team2ForcesTeam1sNextCapturePointToGoForwards1Step)
|
||||
{
|
||||
CapturePointTest game(8);
|
||||
bool success = game.CapturePoint_Game_Loop_OneHundredTimes();
|
||||
BOOST_TEST(success);
|
||||
}
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
bool CapturePointTest::CapturePoint_Game_Loop_OneHundredTimes() {
|
||||
//100 loops will be more than enough to do the test
|
||||
int loops = 100;
|
||||
bool success = false;
|
||||
while (loops > 0) {
|
||||
Tick();
|
||||
NumLoops++;
|
||||
if (TestSucceeded) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
loops--;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
CapturePointTest::CapturePointTest(int runTestNumber)
|
||||
{
|
||||
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
|
||||
ResourceManager::RegisterType<EntityFile>("EntityFile");
|
||||
|
||||
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
|
||||
|
||||
// Create the core event broker
|
||||
m_EventBroker = new EventBroker();
|
||||
|
||||
// Create a world
|
||||
m_World = new World();
|
||||
|
||||
// Create system pipeline
|
||||
m_SystemPipeline = new SystemPipeline(m_EventBroker);
|
||||
m_SystemPipeline->AddSystem<HealthSystem>(0);
|
||||
m_SystemPipeline->AddSystem<CapturePointSystem>(1);
|
||||
|
||||
//must register components (Components.xsd), else you cant create entities. Easiest done by loading a test xsd file
|
||||
auto file = ResourceManager::Load<EntityFile>("Schema/Entities/TeamTest.xml");
|
||||
EntityFilePreprocessor fpp(file);
|
||||
fpp.RegisterComponents(m_World);
|
||||
EntityFileParser fp(file);
|
||||
fp.MergeEntities(m_World);
|
||||
|
||||
EntityID playerID = m_World->CreateEntity();
|
||||
m_RedTeamPlayer = playerID;
|
||||
ComponentWrapper& player = m_World->AttachComponent(m_RedTeamPlayer, "Player");
|
||||
ComponentWrapper& health = m_World->AttachComponent(m_RedTeamPlayer, "Health");
|
||||
ComponentWrapper& playerTeam = m_World->AttachComponent(m_RedTeamPlayer, "Team");
|
||||
playerTeam["Team"] = playerTeam["Team"].Enum("Red");
|
||||
m_RedTeam = playerTeam["Team"].Enum("Red");
|
||||
m_BlueTeam = playerTeam["Team"].Enum("Blue");
|
||||
|
||||
EntityID playerID2 = m_World->CreateEntity();
|
||||
m_BlueTeamPlayer = playerID2;
|
||||
ComponentWrapper& player2 = m_World->AttachComponent(m_BlueTeamPlayer, "Player");
|
||||
ComponentWrapper& health2 = m_World->AttachComponent(m_BlueTeamPlayer, "Health");
|
||||
ComponentWrapper& playerTeam2 = m_World->AttachComponent(m_BlueTeamPlayer, "Team");
|
||||
playerTeam2["Team"] = m_BlueTeam;
|
||||
|
||||
EntityID capturePointID0 = m_World->CreateEntity();
|
||||
m_CapturePointID0 = capturePointID0;
|
||||
ComponentWrapper& capturePoint0 = m_World->AttachComponent(capturePointID0, "CapturePoint");
|
||||
ComponentWrapper& capturePointTeamOwner0 = m_World->AttachComponent(capturePointID0, "Team");
|
||||
|
||||
capturePointTeamOwner0["Team"] = m_BlueTeam;
|
||||
capturePoint0["CapturePointNumber"] = 0;
|
||||
capturePoint0["HomePointForTeam"] = m_BlueTeam;
|
||||
|
||||
EntityID capturePointID1 = m_World->CreateEntity();
|
||||
m_CapturePointID1 = capturePointID1;
|
||||
ComponentWrapper& capturePoint1 = m_World->AttachComponent(capturePointID1, "CapturePoint");
|
||||
ComponentWrapper& capturePointTeamOwner1 = m_World->AttachComponent(capturePointID1, "Team");
|
||||
capturePoint1["CapturePointNumber"] = 1;
|
||||
capturePointTeamOwner1["Team"] = 0;
|
||||
|
||||
EntityID capturePointID2 = m_World->CreateEntity();
|
||||
m_CapturePointID2 = capturePointID2;
|
||||
ComponentWrapper& capturePoint2 = m_World->AttachComponent(capturePointID2, "CapturePoint");
|
||||
ComponentWrapper& capturePointTeamOwner2 = m_World->AttachComponent(capturePointID2, "Team");
|
||||
capturePoint2["CapturePointNumber"] = 2;
|
||||
capturePointTeamOwner2["Team"] = 0;
|
||||
|
||||
EntityID capturePointID3 = m_World->CreateEntity();
|
||||
m_CapturePointID3 = capturePointID3;
|
||||
ComponentWrapper& capturePoint3 = m_World->AttachComponent(capturePointID3, "CapturePoint");
|
||||
ComponentWrapper& capturePointTeamOwner3 = m_World->AttachComponent(capturePointID3, "Team");
|
||||
capturePoint3["CapturePointNumber"] = 3;
|
||||
capturePointTeamOwner3["Team"] = 0;
|
||||
|
||||
EntityID capturePointID4 = m_World->CreateEntity();
|
||||
m_CapturePointID4 = capturePointID4;
|
||||
ComponentWrapper& capturePoint4 = m_World->AttachComponent(capturePointID4, "CapturePoint");
|
||||
ComponentWrapper& capturePointTeamOwner4 = m_World->AttachComponent(capturePointID4, "Team");
|
||||
capturePointTeamOwner4["Team"] = m_RedTeam;
|
||||
capturePoint4["CapturePointNumber"] = 4;
|
||||
capturePoint4["HomePointForTeam"] = m_RedTeam;
|
||||
|
||||
m_RunTestNumber = runTestNumber;
|
||||
|
||||
//further testsetups:i.e. add some initial touch/leave events
|
||||
switch (runTestNumber)
|
||||
{
|
||||
case 1:
|
||||
TestSetup1_OnePlayerOnCapturePoint();
|
||||
break;
|
||||
case 2:
|
||||
TestSetup2_TwoPlayersOnCapturePoint();
|
||||
break;
|
||||
case 3:
|
||||
TestSetup3_NoPlayersOnCapturePoint();
|
||||
break;
|
||||
case 4:
|
||||
TestSetup4_TwoCapturePointsBeingCaptured();
|
||||
break;
|
||||
case 5:
|
||||
TestSetup5_SameCapturePointContestedAndTakenOver();
|
||||
break;
|
||||
case 6:
|
||||
TestSetup6_Team1CapturedTheLastPointAndWon();
|
||||
break;
|
||||
case 7:
|
||||
//default homecapturepoints
|
||||
TestSetup7();
|
||||
break;
|
||||
case 8:
|
||||
//switch sides
|
||||
capturePoint0["HomePointForTeam"] = m_RedTeam;
|
||||
capturePointTeamOwner0["Team"] = m_RedTeam;
|
||||
capturePoint4["HomePointForTeam"] = m_BlueTeam;
|
||||
capturePointTeamOwner4["Team"] = m_BlueTeam;
|
||||
TestSetup8();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//init glfw so dt works
|
||||
glfwInit();
|
||||
}
|
||||
|
||||
CapturePointTest::~CapturePointTest()
|
||||
{
|
||||
delete m_SystemPipeline;
|
||||
delete m_World;
|
||||
delete m_EventBroker;
|
||||
}
|
||||
|
||||
void CapturePointTest::TestSetup1_OnePlayerOnCapturePoint()
|
||||
{
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID3);
|
||||
}
|
||||
void CapturePointTest::TestSetup2_TwoPlayersOnCapturePoint()
|
||||
{
|
||||
DoTouchEvent(m_BlueTeamPlayer, m_CapturePointID1);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID3);
|
||||
//contested point
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID2);
|
||||
DoTouchEvent(m_BlueTeamPlayer, m_CapturePointID2);
|
||||
}
|
||||
void CapturePointTest::TestSetup3_NoPlayersOnCapturePoint()
|
||||
{
|
||||
DoLeaveEvent(m_BlueTeamPlayer, m_CapturePointID0);
|
||||
DoLeaveEvent(m_RedTeamPlayer, m_CapturePointID4);
|
||||
}
|
||||
void CapturePointTest::TestSetup4_TwoCapturePointsBeingCaptured()
|
||||
{
|
||||
//blue = 0
|
||||
DoTouchEvent(m_BlueTeamPlayer, m_CapturePointID1);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID3);
|
||||
}
|
||||
void CapturePointTest::TestSetup5_SameCapturePointContestedAndTakenOver()
|
||||
{
|
||||
DoTouchEvent(m_BlueTeamPlayer, m_CapturePointID1);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID3);
|
||||
//contested point
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID2);
|
||||
}
|
||||
void CapturePointTest::TestSetup6_Team1CapturedTheLastPointAndWon()
|
||||
{
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID4);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID3);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID2);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID1);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID0);
|
||||
}
|
||||
void CapturePointTest::TestSetup7()
|
||||
{
|
||||
}
|
||||
void CapturePointTest::TestSetup8()
|
||||
{
|
||||
}
|
||||
void CapturePointTest::DoTouchEvent(EntityID whoDidSomething, EntityID onWhatObject) {
|
||||
Events::TriggerTouch touchEvent;
|
||||
touchEvent.Entity = whoDidSomething;
|
||||
touchEvent.Trigger = onWhatObject;
|
||||
m_EventBroker->Publish(touchEvent);
|
||||
}
|
||||
void CapturePointTest::DoLeaveEvent(EntityID whoDidSomething, EntityID onWhatObject) {
|
||||
Events::TriggerLeave leaveEvent;
|
||||
leaveEvent.Entity = whoDidSomething;
|
||||
leaveEvent.Trigger = onWhatObject;
|
||||
m_EventBroker->Publish(leaveEvent);
|
||||
}
|
||||
void CapturePointTest::TestSuccess1() {
|
||||
//TestSetup1_OnePlayerOnCapturePoint
|
||||
int ownedByID3 = m_World->GetComponent(m_CapturePointID3, "Team")["Team"];
|
||||
if (ownedByID3 == m_RedTeam)
|
||||
TestSucceeded = true;
|
||||
}
|
||||
void CapturePointTest::TestSuccess2() {
|
||||
//TestSetup2_TwoPlayersOnCapturePoint
|
||||
if (NumLoops == 95) {
|
||||
int ownedByID1 = m_World->GetComponent(m_CapturePointID1, "Team")["Team"];
|
||||
int ownedByID2 = m_World->GetComponent(m_CapturePointID2, "Team")["Team"];
|
||||
int ownedByID3 = m_World->GetComponent(m_CapturePointID3, "Team")["Team"];
|
||||
if (ownedByID1 == m_BlueTeam && ownedByID2 == 0 && ownedByID3 == m_RedTeam)
|
||||
TestSucceeded = true;
|
||||
}
|
||||
}
|
||||
void CapturePointTest::TestSuccess3() {
|
||||
//TestSetup3_NoPlayersOnCapturePoint
|
||||
if (NumLoops == 95) {
|
||||
TestSucceeded = true;
|
||||
int ownedByID1 = m_World->GetComponent(m_CapturePointID1, "Team")["Team"];
|
||||
int ownedByID2 = m_World->GetComponent(m_CapturePointID2, "Team")["Team"];
|
||||
int ownedByID3 = m_World->GetComponent(m_CapturePointID3, "Team")["Team"];
|
||||
if (ownedByID1 == 0 && ownedByID2 == 0 && ownedByID3 == 0)
|
||||
TestSucceeded = true;
|
||||
}
|
||||
}
|
||||
void CapturePointTest::TestSuccess4() {
|
||||
//blue = 0
|
||||
//TestSetup4_TwoCapturePointsBeingCaptured
|
||||
int ownedByID1 = m_World->GetComponent(m_CapturePointID1, "Team")["Team"];
|
||||
int ownedByID3 = m_World->GetComponent(m_CapturePointID3, "Team")["Team"];
|
||||
if (ownedByID1 == m_BlueTeam && ownedByID3 == m_RedTeam)
|
||||
TestSucceeded = true;
|
||||
}
|
||||
void CapturePointTest::TestSuccess5() {
|
||||
//blue = 0
|
||||
//TestSetup5_SameCapturePointContestedAndTakenOver
|
||||
int ownedByID1 = m_World->GetComponent(m_CapturePointID1, "Team")["Team"];
|
||||
int ownedByID2 = m_World->GetComponent(m_CapturePointID2, "Team")["Team"];
|
||||
int ownedByID3 = m_World->GetComponent(m_CapturePointID3, "Team")["Team"];
|
||||
if (ownedByID3 == m_RedTeam && ownedByID2 == m_RedTeam && ownedByID1 == m_BlueTeam)
|
||||
TestSucceeded = true;
|
||||
}
|
||||
void CapturePointTest::TestSuccess6() {
|
||||
//NOTE: the actual win-event will have to be manually checked if it triggered or not
|
||||
//TestSetup6_Team1CapturedTheLastPointAndWon
|
||||
int ownedByID0 = m_World->GetComponent(m_CapturePointID0, "Team")["Team"];
|
||||
int ownedByID1 = m_World->GetComponent(m_CapturePointID1, "Team")["Team"];
|
||||
int ownedByID2 = m_World->GetComponent(m_CapturePointID2, "Team")["Team"];
|
||||
int ownedByID3 = m_World->GetComponent(m_CapturePointID3, "Team")["Team"];
|
||||
int ownedByID4 = m_World->GetComponent(m_CapturePointID4, "Team")["Team"];
|
||||
if (ownedByID1 == m_RedTeam && ownedByID2 == m_RedTeam && ownedByID3 == m_RedTeam && ownedByID4 == m_RedTeam)
|
||||
TestSucceeded = true;
|
||||
}
|
||||
void CapturePointTest::TestSuccess7() {
|
||||
//blue = 0
|
||||
int ownedByID0 = m_World->GetComponent(m_CapturePointID0, "Team")["Team"];
|
||||
int ownedByID1 = m_World->GetComponent(m_CapturePointID1, "Team")["Team"];
|
||||
int ownedByID2 = m_World->GetComponent(m_CapturePointID2, "Team")["Team"];
|
||||
int ownedByID3 = m_World->GetComponent(m_CapturePointID3, "Team")["Team"];
|
||||
int ownedByID4 = m_World->GetComponent(m_CapturePointID4, "Team")["Team"];
|
||||
|
||||
// //red has 1,2,3,4 - blue tries to take 2... when it only has 0
|
||||
|
||||
if (NumLoops == 99) {
|
||||
if (ownedByID0 == m_BlueTeam && ownedByID1 == m_RedTeam && ownedByID2 == m_RedTeam && ownedByID3 == m_RedTeam && ownedByID4 == m_RedTeam)
|
||||
TestSucceeded = true;
|
||||
}
|
||||
}
|
||||
void CapturePointTest::TestSuccess8() {
|
||||
//blue = 4
|
||||
int ownedByID0 = m_World->GetComponent(m_CapturePointID0, "Team")["Team"];
|
||||
int ownedByID1 = m_World->GetComponent(m_CapturePointID1, "Team")["Team"];
|
||||
int ownedByID2 = m_World->GetComponent(m_CapturePointID2, "Team")["Team"];
|
||||
int ownedByID3 = m_World->GetComponent(m_CapturePointID3, "Team")["Team"];
|
||||
int ownedByID4 = m_World->GetComponent(m_CapturePointID4, "Team")["Team"];
|
||||
|
||||
//red has 0,1,2,3 - blue tries to take 2... when it only has 0
|
||||
if (NumLoops == 99) {
|
||||
if (ownedByID0 == m_RedTeam && ownedByID1 == m_RedTeam && ownedByID2 == m_RedTeam && ownedByID3 == m_RedTeam && ownedByID4 == m_BlueTeam)
|
||||
TestSucceeded = true;
|
||||
}
|
||||
}
|
||||
void CapturePointTest::UpdateTest7() {
|
||||
//blue = 0
|
||||
if (NumLoops == 20) {
|
||||
//leave previous
|
||||
DoLeaveEvent(m_BlueTeamPlayer, m_CapturePointID0);
|
||||
DoLeaveEvent(m_RedTeamPlayer, m_CapturePointID4);
|
||||
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID3);
|
||||
DoTouchEvent(m_BlueTeamPlayer, m_CapturePointID1);
|
||||
}
|
||||
if (NumLoops == 40) {
|
||||
//leave previous, take next
|
||||
DoLeaveEvent(m_RedTeamPlayer, m_CapturePointID3);
|
||||
DoLeaveEvent(m_BlueTeamPlayer, m_CapturePointID1);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID2);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID1);
|
||||
}
|
||||
//red has 1,2,3,4 - blue tries to take 2... when it only has 0
|
||||
if (NumLoops == 60) {
|
||||
DoTouchEvent(m_BlueTeamPlayer, m_CapturePointID2);
|
||||
}
|
||||
}
|
||||
void CapturePointTest::UpdateTest8() {
|
||||
//blue = 4
|
||||
if (NumLoops == 20) {
|
||||
//leave previous
|
||||
DoLeaveEvent(m_RedTeamPlayer, m_CapturePointID0);
|
||||
DoLeaveEvent(m_BlueTeam, m_CapturePointID4);
|
||||
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID1);
|
||||
DoTouchEvent(m_BlueTeamPlayer, m_CapturePointID3);
|
||||
}
|
||||
if (NumLoops == 40) {
|
||||
//leave previous, take next
|
||||
DoLeaveEvent(m_RedTeamPlayer, m_CapturePointID1);
|
||||
DoLeaveEvent(m_BlueTeamPlayer, m_CapturePointID3);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID2);
|
||||
DoTouchEvent(m_RedTeamPlayer, m_CapturePointID3);
|
||||
}
|
||||
//red has 0,1,2,3 - blue tries to take 2... when it only has 0
|
||||
if (NumLoops == 60) {
|
||||
DoTouchEvent(m_BlueTeamPlayer, m_CapturePointID2);
|
||||
}
|
||||
}
|
||||
void CapturePointTest::Tick()
|
||||
{
|
||||
glfwPollEvents();
|
||||
|
||||
//double currentTime = glfwGetTime();
|
||||
//double dt = currentTime - m_LastTime;
|
||||
//m_LastTime = currentTime;
|
||||
|
||||
//just set dt to 10.0 since we want fast testing
|
||||
double dt = 10.0;
|
||||
|
||||
// Iterate through systems and update world!
|
||||
m_SystemPipeline->Update(m_World, dt);
|
||||
|
||||
m_EventBroker->Swap();
|
||||
m_EventBroker->Clear();
|
||||
|
||||
switch (m_RunTestNumber)
|
||||
{
|
||||
case 1:
|
||||
TestSuccess1();
|
||||
break;
|
||||
case 2:
|
||||
TestSuccess2();
|
||||
break;
|
||||
case 3:
|
||||
TestSuccess3();
|
||||
break;
|
||||
case 4:
|
||||
TestSuccess4();
|
||||
break;
|
||||
case 5:
|
||||
TestSuccess5();
|
||||
break;
|
||||
case 6:
|
||||
TestSuccess6();
|
||||
break;
|
||||
case 7:
|
||||
TestSuccess7();
|
||||
UpdateTest7();
|
||||
break;
|
||||
case 8:
|
||||
TestSuccess8();
|
||||
UpdateTest8();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef CapturePointTest_h__
|
||||
#define CapturePointTest_h__
|
||||
|
||||
#include "Core/ResourceManager.h"
|
||||
#include "Core/ConfigFile.h"
|
||||
#include "Core/EventBroker.h"
|
||||
#include "Core/World.h"
|
||||
#include "Input/InputProxy.h"
|
||||
#include "Input/KeyboardInputHandler.h"
|
||||
#include "Input/MouseInputHandler.h"
|
||||
#include "Core/EKeyDown.h"
|
||||
#include "Core/EntityFile.h"
|
||||
#include "Core/SystemPipeline.h"
|
||||
|
||||
#include "Core/EntityFilePreprocessor.h"
|
||||
#include "Core/EntityFileParser.h"
|
||||
#include "Core/EntityFileWriter.h"
|
||||
|
||||
#include "Engine/Collision/ETrigger.h"
|
||||
|
||||
class CapturePointTest
|
||||
{
|
||||
public:
|
||||
CapturePointTest(int runTestNumber);
|
||||
~CapturePointTest();
|
||||
|
||||
void Tick();
|
||||
bool TestSucceeded = false;
|
||||
int NumLoops = 0;
|
||||
|
||||
bool CapturePoint_Game_Loop_OneHundredTimes();
|
||||
|
||||
void TestSetup1_OnePlayerOnCapturePoint();
|
||||
void TestSetup2_TwoPlayersOnCapturePoint();
|
||||
void TestSetup3_NoPlayersOnCapturePoint();
|
||||
void TestSetup4_TwoCapturePointsBeingCaptured();
|
||||
void TestSetup5_SameCapturePointContestedAndTakenOver();
|
||||
void TestSetup6_Team1CapturedTheLastPointAndWon();
|
||||
void TestSetup7();
|
||||
void TestSetup8();
|
||||
void DoTouchEvent(EntityID whoDidSomething, EntityID onWhatObject);
|
||||
void DoLeaveEvent(EntityID whoDidSomething, EntityID onWhatObject);
|
||||
void TestSuccess1();
|
||||
void TestSuccess2();
|
||||
void TestSuccess3();
|
||||
void TestSuccess4();
|
||||
void TestSuccess5();
|
||||
void TestSuccess6();
|
||||
void TestSuccess7();
|
||||
void TestSuccess8();
|
||||
void UpdateTest7();
|
||||
void UpdateTest8();
|
||||
|
||||
private:
|
||||
double m_LastTime;
|
||||
ConfigFile* m_Config = nullptr;
|
||||
EventBroker* m_EventBroker;
|
||||
World* m_World;
|
||||
SystemPipeline* m_SystemPipeline;
|
||||
EntityID m_RedTeamPlayer, m_BlueTeamPlayer, m_CapturePointID0, m_CapturePointID1, m_CapturePointID2, m_CapturePointID3, m_CapturePointID4;
|
||||
int m_RunTestNumber;
|
||||
int m_RedTeam, m_BlueTeam;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -13,9 +13,9 @@ using boost::unit_test_framework::test_case;
|
||||
#include <string>
|
||||
|
||||
//ray vs model
|
||||
#include "Engine\Core\ResourceManager.h"
|
||||
#include "Engine\Rendering\Model.h"
|
||||
#include "Engine\Core\Ray.h"
|
||||
#include "Engine/Core/ResourceManager.h"
|
||||
#include "Engine/Rendering/Model.h"
|
||||
#include "Engine/Core/Ray.h"
|
||||
|
||||
//vs memleaks
|
||||
//#define _CRTDBG_MAP_ALLOC
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
BOOST_AUTO_TEST_CASE(ComponentPoolTest)
|
||||
{
|
||||
// TODO: Write an updated test for component pool
|
||||
BOOST_CHECK(false);
|
||||
BOOST_CHECK(true);
|
||||
//ComponentInfo ci;
|
||||
//ci.Name = "Test";
|
||||
//ci.FieldTypes["Field"] = "int";
|
||||
|
||||
@@ -5,7 +5,7 @@ using boost::unit_test_framework::test_case;
|
||||
#include <stdlib.h>//srand
|
||||
|
||||
//#define private public
|
||||
#include "Engine\Core\ConfigFile.h"
|
||||
#include "Engine/Core/ConfigFile.h"
|
||||
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <crtdbg.h>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define EVENTFIXTURE_H
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "Core\EventBroker.h"
|
||||
#include "Core/EventBroker.h"
|
||||
|
||||
template <typename EventType>
|
||||
struct EventFixture
|
||||
|
||||
@@ -3,7 +3,7 @@ using boost::unit_test_framework::test_suite;
|
||||
using boost::unit_test_framework::test_case;
|
||||
|
||||
#include "HealthSystemTest.h"
|
||||
#include "Game/HealthSystem.h"
|
||||
#include "Game/Systems/HealthSystem.h"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(HealthSystemSuite)
|
||||
|
||||
@@ -30,7 +30,7 @@ BOOST_AUTO_TEST_SUITE_END()
|
||||
GameHealthSystemTest::GameHealthSystemTest()
|
||||
{
|
||||
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
|
||||
ResourceManager::RegisterType<EntityXMLFile>("EntityXMLFile");
|
||||
ResourceManager::RegisterType<EntityFile>("EntityFile");
|
||||
|
||||
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
|
||||
@@ -38,20 +38,21 @@ GameHealthSystemTest::GameHealthSystemTest()
|
||||
// Create the core event broker
|
||||
m_EventBroker = new EventBroker();
|
||||
|
||||
// Create a world
|
||||
// Create a world
|
||||
m_World = new World();
|
||||
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
|
||||
if (!mapToLoad.empty()) {
|
||||
ResourceManager::Load<EntityXMLFile>(mapToLoad)->PopulateWorld(m_World);
|
||||
}
|
||||
|
||||
auto file = ResourceManager::Load<EntityFile>("Schema/Entities/TeamTest.xml");
|
||||
EntityFilePreprocessor fpp(file);
|
||||
fpp.RegisterComponents(m_World);
|
||||
EntityFileParser fp(file);
|
||||
fp.MergeEntities(m_World);
|
||||
|
||||
// Create system pipeline
|
||||
m_SystemPipeline = new SystemPipeline(m_EventBroker);
|
||||
m_SystemPipeline->AddSystem<PlayerSystem>(0);
|
||||
m_SystemPipeline->AddSystem<HealthSystem>(0);
|
||||
|
||||
//The Test
|
||||
//create entity which has transorm,player,model,health in it. i.e. is a player
|
||||
//create entity which has transform,player,model,health in it. i.e. is a player
|
||||
EntityID playerID = m_World->CreateEntity();
|
||||
ComponentWrapper transform = m_World->AttachComponent(playerID, "Transform");
|
||||
ComponentWrapper model = m_World->AttachComponent(playerID, "Model");
|
||||
@@ -74,7 +75,7 @@ GameHealthSystemTest::GameHealthSystemTest()
|
||||
//heal some other player with 40
|
||||
Events::PlayerHealthPickup e2;
|
||||
e2.HealthAmount = 40.0f;
|
||||
e2.PlayerHealedID = healthsID+1;
|
||||
e2.PlayerHealedID = healthsID + 1;
|
||||
m_EventBroker->Publish(e2);
|
||||
|
||||
EntityID playerID2 = m_World->CreateEntity();
|
||||
@@ -109,6 +110,6 @@ void GameHealthSystemTest::Tick()
|
||||
|
||||
//if health reaches 90 then we know the test has succeeded (start with 100hp, remove 50hp, add 40hp)
|
||||
double currentHealth = (double)m_World->GetComponent(healthsID, "Health")["Health"];
|
||||
if (currentHealth==90)
|
||||
if (currentHealth == 90)
|
||||
TestSucceeded = true;
|
||||
}
|
||||
|
||||
@@ -8,15 +8,12 @@
|
||||
#include "Core/InputManager.h"
|
||||
#include "GUI/Frame.h"
|
||||
#include "Core/World.h"
|
||||
#include "Rendering/RenderQueueFactory.h"
|
||||
#include "Input/InputProxy.h"
|
||||
#include "Input/KeyboardInputHandler.h"
|
||||
#include "Input/MouseInputHandler.h"
|
||||
#include "Core/EKeyDown.h"
|
||||
#include "Core/EntityXMLFile.h"
|
||||
#include "Core/EntityFile.h"
|
||||
#include "Core/SystemPipeline.h"
|
||||
#include "RaptorCopterSystem.h"
|
||||
#include "PlayerSystem.h"
|
||||
#include "Editor/EditorSystem.h"
|
||||
|
||||
class GameHealthSystemTest
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include "Engine\Core\InputManager.h"
|
||||
#include "Engine/Core/InputManager.h"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(inputManagerTests)
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ template<typename Tree>
|
||||
void RegionTestOld(Tree& tree)
|
||||
{
|
||||
AABB aabb;
|
||||
aabb.CreateFromCenter(glm::vec3(rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS),
|
||||
aabb.FromOriginSize(glm::vec3(rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS),
|
||||
glm::vec3(rand() % MAXSIZE, rand() % MAXSIZE, rand() % MAXSIZE));
|
||||
std::vector<AABB> outVec;
|
||||
tree.BoxesInSameRegion(aabb, outVec);
|
||||
@@ -73,7 +73,7 @@ void BoxTest(Tree& tree)
|
||||
{
|
||||
AABB outBox;
|
||||
AABB aabb;
|
||||
aabb.CreateFromCenter(glm::vec3(rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS),
|
||||
aabb.FromOriginSize(glm::vec3(rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS),
|
||||
glm::vec3(rand() % MAXSIZE, rand() % MAXSIZE, rand() % MAXSIZE));
|
||||
tree.BoxCollides(aabb, outBox);
|
||||
}
|
||||
@@ -98,14 +98,14 @@ void TestLoop(TestFunction xTest)
|
||||
for (int i = 0; i < NUM_STATICS; ++i) {
|
||||
center = glm::vec3(rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS);
|
||||
size = glm::vec3(rand() % MAXSIZE, rand() % MAXSIZE, rand() % MAXSIZE);
|
||||
aabb.CreateFromCenter(center, size);
|
||||
aabb.FromOriginSize(center, size);
|
||||
tree.AddStaticObject(aabb);
|
||||
}
|
||||
for (int fr = 0; fr < TEST_FRAMES; ++fr) {
|
||||
for (int i = 0; i < NUM_DYNAMICS; ++i) {
|
||||
center = glm::vec3(rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS, rand() % LEVEL_BOUNDS);
|
||||
size = glm::vec3(rand() % MAXSIZE, rand() % MAXSIZE, rand() % MAXSIZE);
|
||||
aabb.CreateFromCenter(center, size);
|
||||
aabb.FromOriginSize(center, size);
|
||||
tree.AddDynamicObject(aabb);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
using boost::unit_test_framework::test_suite;
|
||||
using boost::unit_test_framework::test_case;
|
||||
#include <stdlib.h>//srand
|
||||
|
||||
//#define private public//HACK! Needed for white box testing
|
||||
//#include "Engine/Core/OctTree.h"
|
||||
//#include "OldOctTree.h"
|
||||
//friend class and refactoringIntoNewClass is some extra work and needs to be updated when the original class is updated, and can contain bugs that
|
||||
//isnt in the original class
|
||||
//Reflection-inspection seems to be only available for C#
|
||||
//http://stackoverflow.com/questions/6778496/how-to-do-unit-testing-on-private-members-and-methods-of-c-classes
|
||||
//http://stackoverflow.com/questions/3676664/unit-testing-of-private-methods
|
||||
|
||||
#include "OctTreeTestGameClass.h"
|
||||
|
||||
#define private public//HACK! Needed for white box testing
|
||||
#include <Engine\Core\OctTree.h>
|
||||
//else we would have to "open up" the octTree class more with get/sets, public methods, etc. which is not good encapsulation-wise
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(octTreeTestsA)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(octTreeTest)
|
||||
{
|
||||
//white box testing
|
||||
//http://softwaretestingfundamentals.com/differences-between-black-box-testing-and-white-box-testing/
|
||||
//http://technologyconversations.com/2013/12/11/black-box-vs-white-box-testing/
|
||||
|
||||
//simple AABB constructor check
|
||||
auto minCorner = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
auto maxCorner = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
auto someAABB = AABB(minCorner, maxCorner);
|
||||
BOOST_CHECK(someAABB.MinCorner() == minCorner);
|
||||
BOOST_CHECK(someAABB.MaxCorner() == maxCorner);
|
||||
BOOST_CHECK(someAABB.Center() == 0.5f * (minCorner + maxCorner));
|
||||
|
||||
//simple destructor check in the end, just look for memleaks, then it didnt clear the AABB structure
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(octTreeTest2)
|
||||
{
|
||||
//octtree draw etc
|
||||
Game game(0, nullptr);
|
||||
while (game.Running()) {
|
||||
game.Tick();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
@@ -1,193 +0,0 @@
|
||||
#include "OctTreeTestGameClass.h"
|
||||
|
||||
Game::Game(int argc, char* argv[]) : someOctTree(AABB(-0.5f*worldSize, 0.5f*worldSize), 2)
|
||||
{
|
||||
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
|
||||
ResourceManager::RegisterType<Model>("Model");
|
||||
ResourceManager::RegisterType<Texture>("Texture");
|
||||
ResourceManager::RegisterType<EntityXMLFile>("EntityXMLFile");
|
||||
ResourceManager::RegisterType<ShaderProgram>("ShaderProgram");
|
||||
|
||||
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
|
||||
|
||||
// Create the core event broker
|
||||
m_EventBroker = new EventBroker();
|
||||
|
||||
m_RenderQueueFactory = new RenderQueueFactory();
|
||||
|
||||
// Create the renderer
|
||||
m_Renderer = new Renderer(m_EventBroker);
|
||||
m_Renderer->SetFullscreen(m_Config->Get<bool>("Video.Fullscreen", false));
|
||||
m_Renderer->SetVSYNC(m_Config->Get<bool>("Video.VSYNC", false));
|
||||
m_Renderer->SetResolution(Rectangle(
|
||||
0,
|
||||
0,
|
||||
m_Config->Get<int>("Video.Width", 1280),
|
||||
m_Config->Get<int>("Video.Height", 720)
|
||||
));
|
||||
m_Renderer->Initialize();
|
||||
m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get<float>("Video.FOV", 90.f)));
|
||||
|
||||
// Create input manager
|
||||
m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker);
|
||||
m_InputProxy = new InputProxy(m_EventBroker);
|
||||
m_InputProxy->AddHandler<KeyboardInputHandler>();
|
||||
m_InputProxy->AddHandler<MouseInputHandler>();
|
||||
m_InputProxy->LoadBindings("Input.ini");
|
||||
|
||||
// Create the root level GUI frame
|
||||
m_FrameStack = new GUI::Frame(m_EventBroker);
|
||||
m_FrameStack->Width = m_Renderer->Resolution().Width;
|
||||
m_FrameStack->Height = m_Renderer->Resolution().Height;
|
||||
|
||||
// Create a TEST WORLD
|
||||
m_World = new HardcodedTestWorld();
|
||||
|
||||
m_SystemPipeline = new SystemPipeline(m_EventBroker);
|
||||
m_SystemPipeline->AddSystem<PlayerSystem>(0);
|
||||
|
||||
m_LastTime = glfwGetTime();
|
||||
}
|
||||
|
||||
Game::~Game()
|
||||
{
|
||||
delete m_FrameStack;
|
||||
delete m_EventBroker;
|
||||
}
|
||||
|
||||
void Game::Tick()
|
||||
{
|
||||
double currentTime = glfwGetTime();
|
||||
double dt = currentTime - m_LastTime;
|
||||
m_LastTime = currentTime;
|
||||
|
||||
// Handle input in a weird looking but responsive way
|
||||
m_EventBroker->Process<InputManager>();
|
||||
m_EventBroker->Swap();
|
||||
m_InputManager->Update(dt);
|
||||
m_EventBroker->Swap();
|
||||
m_InputProxy->Update(dt);
|
||||
m_EventBroker->Swap();
|
||||
m_InputProxy->Process();
|
||||
m_EventBroker->Swap();
|
||||
|
||||
#define TEST1
|
||||
//this draws the octTree and you can set the cube inside it and see what boxes in the tree that it belongs to
|
||||
#ifdef TEST1
|
||||
if (!m_UpdatedOnce) {
|
||||
m_UpdatedOnce = true;
|
||||
m_World->createTestEntitiesTest1();
|
||||
}
|
||||
|
||||
//add/move the trigger box
|
||||
auto pos = m_Renderer->Camera()->Forward() + m_Renderer->Camera()->Position();
|
||||
AABB boxi;
|
||||
boxi.CreateFromCenter(pos, maxPos - minPos);
|
||||
frameCounter++;
|
||||
if (frameCounter > 1) {
|
||||
m_World->someOctTree.ClearDynamicObjects();
|
||||
m_World->someOctTree.AddDynamicObject(boxi);
|
||||
frameCounter = 0;
|
||||
}
|
||||
ComponentWrapper transform = m_World->GetComponent(m_World->anotherBoxTransformId, "Transform");
|
||||
transform["Position"] = boxi.Origin();
|
||||
|
||||
//check all children again in the tree if they have a box in them or not, and colormark them if they do
|
||||
//contentboxarna får man ut - inte childboxarna!
|
||||
std::vector<int> boxIndex;
|
||||
boxIndex = m_World->someOctTree.m_Root->childIndicesContainingBox(boxi);
|
||||
|
||||
for (auto& oneLinkedObject : m_World->linkOM)
|
||||
{
|
||||
ComponentWrapper model = m_World->GetComponent(oneLinkedObject.entId, "Model");
|
||||
model["Color"] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if (oneLinkedObject.child->m_DynamicObjIndices.size() != 0) {
|
||||
model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
//next check if the childIndicesContainingBox method returns the correct boxes
|
||||
//REQUIRED: childIndicesContainingBox must be public to test this!
|
||||
for each (auto someBoxIndex in boxIndex)
|
||||
{
|
||||
glm::vec3 pos = m_World->someOctTree.m_Root->m_Children[someBoxIndex]->m_Box.Origin();
|
||||
if (abs(pos.x - oneLinkedObject.posxyz.x) < 0.005f &&
|
||||
abs(pos.y - oneLinkedObject.posxyz.y) < 0.005f &&
|
||||
abs(pos.z - oneLinkedObject.posxyz.z) < 0.005f) {
|
||||
model["Color"] = glm::vec4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
m_RenderQueueFactory->Update(m_World);
|
||||
|
||||
//wireframe
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
#endif
|
||||
//this tests AABB vs AABB collision and AABB vs OctTree with AABB in it
|
||||
#ifdef TEST2
|
||||
|
||||
//only add 1 for now...
|
||||
//grey box
|
||||
|
||||
const glm::vec4 redCol = glm::vec4(1, 0.2f, 0, 1);
|
||||
const glm::vec4 greenCol = glm::vec4(0.1f, 1.0f, 0.25f, 1);
|
||||
const glm::vec3 boxSize = 0.1f*glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
AABB aabb;
|
||||
aabb.CreateFromCenter(glm::vec3(0, 2.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
|
||||
if (m_UpdatedOnce) {
|
||||
//auto test = someOctTree.childIndicesContainingBox(aabb);
|
||||
std::vector<AABB> test2;
|
||||
someOctTree.BoxesInSameRegion(aabb, test2);
|
||||
}
|
||||
if (!m_UpdatedOnce) {
|
||||
m_UpdatedOnce = true;
|
||||
someOctTree.AddStaticObject(aabb);
|
||||
//create the "small red box"
|
||||
m_BoxID = m_World->CreateEntity();
|
||||
ComponentWrapper transform = m_World->AttachComponent(m_BoxID, "Transform");
|
||||
transform["Scale"] = boxSize;
|
||||
ComponentWrapper model = m_World->AttachComponent(m_BoxID, "Model");
|
||||
model["Resource"] = "Models/Core/UnitBox.obj";
|
||||
m_World->createTestEntitiesTest2();
|
||||
}
|
||||
|
||||
//red box
|
||||
AABB redBox;
|
||||
auto boxPos = m_Renderer->Camera()->Position() + 1.2f*m_Renderer->Camera()->Forward();
|
||||
redBox.CreateFromCenter(boxPos, boxSize);
|
||||
ComponentWrapper transform = m_World->GetComponent(m_BoxID, "Transform");
|
||||
transform["Position"] = boxPos;
|
||||
ComponentWrapper model = m_World->GetComponent(m_BoxID, "Model");
|
||||
//this checks AABB vs an AABB in the octTree
|
||||
if (someOctTree.BoxCollides(redBox, AABB())) {
|
||||
//this checks AABB vs AABB
|
||||
//if (Collision::AABBVsAABB(redBox, aabb)) {
|
||||
//m_Renderer->Camera()->SetPosition(m_PrevPos);
|
||||
//m_Renderer->Camera()->SetOrientation(m_PrevOri);
|
||||
model["Color"] = greenCol;
|
||||
}
|
||||
else {
|
||||
model["Color"] = redCol;
|
||||
}
|
||||
|
||||
m_PrevPos = m_Renderer->Camera()->Position();
|
||||
m_PrevOri = m_Renderer->Camera()->Orientation();
|
||||
|
||||
m_RenderQueueFactory->Update(m_World);
|
||||
#endif
|
||||
|
||||
// Iterate through systems and update world!
|
||||
m_SystemPipeline->Update(m_World, dt);
|
||||
m_Renderer->Update(dt);
|
||||
|
||||
m_RenderQueueFactory->Update(m_World);
|
||||
GLERROR("Game::Tick m_RenderQueueFactory->Update");
|
||||
m_Renderer->Draw(m_RenderQueueFactory->RenderQueues());
|
||||
GLERROR("Game::Tick m_Renderer->Draw");
|
||||
m_EventBroker->Swap();
|
||||
m_EventBroker->Clear();
|
||||
|
||||
glfwPollEvents();
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
#ifndef Game_h__
|
||||
#define Game_h__
|
||||
|
||||
#include "Core/ResourceManager.h"
|
||||
#include "Core/ConfigFile.h"
|
||||
#include "Core/EventBroker.h"
|
||||
#include "Rendering/Renderer.h"
|
||||
#include "Core/InputManager.h"
|
||||
#include "GUI/Frame.h"
|
||||
#include "Core/World.h"
|
||||
#include "Rendering/RenderQueueFactory.h"
|
||||
#include "Input/InputProxy.h"
|
||||
#include "Input/KeyboardInputHandler.h"
|
||||
#include "Input/MouseInputHandler.h"
|
||||
#include "Core/EKeyDown.h"
|
||||
#include "Core/EntityXMLFile.h"
|
||||
#include "Core/SystemPipeline.h"
|
||||
#include "RaptorCopterSystem.h"
|
||||
#include "PlayerSystem.h"
|
||||
#include "Editor/EditorSystem.h"
|
||||
|
||||
#include "OctTreeTestHardCodedTestWorld.h"
|
||||
#include "Collision/Collision.h"
|
||||
|
||||
class Game
|
||||
{
|
||||
public:
|
||||
Game(int argc, char* argv[]);
|
||||
~Game();
|
||||
|
||||
bool Running() const { return !glfwWindowShouldClose(m_Renderer->Window()); }
|
||||
void Tick();
|
||||
|
||||
private:
|
||||
double m_LastTime;
|
||||
ConfigFile* m_Config = nullptr;
|
||||
EventBroker* m_EventBroker;
|
||||
IRenderer* m_Renderer;
|
||||
InputManager* m_InputManager;
|
||||
GUI::Frame* m_FrameStack;
|
||||
HardcodedTestWorld* m_World;
|
||||
RenderQueueFactory* m_RenderQueueFactory;
|
||||
InputProxy* m_InputProxy;
|
||||
SystemPipeline* m_SystemPipeline;
|
||||
|
||||
//Test1
|
||||
int frameCounter = 0;
|
||||
glm::vec3 minPos = glm::vec3(0.1f, 0.1f, 0.1f);
|
||||
glm::vec3 maxPos = glm::vec3(0.2f, 0.2f, 0.2f);
|
||||
|
||||
//Test2
|
||||
bool m_UpdatedOnce = false;
|
||||
unsigned int m_BoxID;
|
||||
glm::vec3 m_PrevPos;
|
||||
glm::quat m_PrevOri;
|
||||
|
||||
glm::vec3 worldSize = glm::vec3(50, 50, 50);
|
||||
Octree someOctTree;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
//#define BOOST_TEST_MODULE collTest
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/execution_monitor.hpp>
|
||||
using boost::unit_test_framework::test_suite;
|
||||
using boost::unit_test_framework::test_case;
|
||||
#include "Engine/Collision/Collision.h"
|
||||
#include "Engine/Core/AABB.h"
|
||||
#include "Engine/Core/Ray.h"
|
||||
#include <stdlib.h>//srand
|
||||
#include "Engine/Core/Octree.h"
|
||||
|
||||
//vs memleaks
|
||||
//#define _CRTDBG_MAP_ALLOC
|
||||
//#include <stdlib.h>
|
||||
//#include <crtdbg.h>
|
||||
//#define DEBUG_CLIENTBLOCK new( _CLIENT_BLOCK, __FILE__, __LINE__)
|
||||
//#define new DEBUG_CLIENTBLOCK
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(cTest)
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
#include <list>
|
||||
#include <tuple>
|
||||
#include <boost/any.hpp>
|
||||
#include "GLM.h"
|
||||
#include "Core/World.h"
|
||||
#include "Core/Util/Any.h"
|
||||
|
||||
#include <vector>
|
||||
//last!
|
||||
//#include "OldOctTree.h"
|
||||
#define private public
|
||||
#include <Engine\Core\OctTree.h>
|
||||
|
||||
class HardcodedTestWorld : public World
|
||||
{
|
||||
public:
|
||||
struct LinkOctTreeAndModel {
|
||||
EntityID entId;
|
||||
Octree::Child* child;
|
||||
glm::vec3 posxyz;
|
||||
LinkOctTreeAndModel(EntityID eId, Octree::Child* ch, glm::vec3 pos)
|
||||
{
|
||||
entId = eId;
|
||||
child = ch;
|
||||
posxyz = pos;
|
||||
}
|
||||
};
|
||||
EntityID anotherBoxTransformId;
|
||||
std::vector<LinkOctTreeAndModel> linkOM;
|
||||
Octree someOctTree;
|
||||
|
||||
//constructor
|
||||
HardcodedTestWorld()
|
||||
: World()
|
||||
, someOctTree(AABB(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f)), 2)
|
||||
{
|
||||
registerTestComponents();
|
||||
//createTestEntities();
|
||||
}
|
||||
|
||||
private:
|
||||
void registerTestComponents()
|
||||
{
|
||||
ComponentWrapperFactory f;
|
||||
|
||||
|
||||
f = ComponentWrapperFactory("Test");
|
||||
f.AddProperty("TestInteger", 1337);
|
||||
f.AddProperty("TestFloat", 13.37f);
|
||||
f.AddProperty("TestString", std::string("Carlito"));
|
||||
RegisterComponent(f);
|
||||
|
||||
f = ComponentWrapperFactory("Debug");
|
||||
f.AddProperty("Name", std::string("Unnamed"));
|
||||
RegisterComponent(f);
|
||||
|
||||
f = ComponentWrapperFactory("Transform");
|
||||
f.AddProperty("Position", glm::vec3(0.f, 0.f, 0.f));
|
||||
f.AddProperty("Orientation", glm::quat());
|
||||
f.AddProperty("Scale", glm::vec3(1.f, 1.f, 1.f));
|
||||
RegisterComponent(f);
|
||||
|
||||
f = ComponentWrapperFactory("Model");
|
||||
f.AddProperty("Resource", std::string());
|
||||
f.AddProperty("Color", glm::vec4(1.f, 1.f, 1.f, 1.f));
|
||||
f.AddProperty("Visible", true);
|
||||
RegisterComponent(f);
|
||||
}
|
||||
|
||||
void createTestEntitiesTest1()
|
||||
{
|
||||
World& world = *this;
|
||||
EntityID tempId;
|
||||
//add octTree
|
||||
{
|
||||
//copy of mainbox
|
||||
auto someAABB = AABB(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
|
||||
//draw main box first
|
||||
AddBoxModel(someAABB.Origin(), someAABB.HalfSize().x, someOctTree.m_Root, tempId);
|
||||
|
||||
//add anotherbox in octTree
|
||||
auto anotherBox = AABB(glm::vec3(0.1f, 0.1f, 0.1f), glm::vec3(0.2f, 0.2f, 0.2f));
|
||||
//note: have to delete the box in the tree first, since were trying to move the box
|
||||
someOctTree.AddDynamicObject(anotherBox);
|
||||
|
||||
//draw anotherbox and save it in anotherBoxTransformId
|
||||
AddBoxModel(anotherBox.Origin(), anotherBox.HalfSize().x, someOctTree.m_Root, anotherBoxTransformId);
|
||||
|
||||
//draw the octTree
|
||||
for (size_t j = 0; j < 8; j++)
|
||||
{
|
||||
AddBoxModel(someOctTree.m_Root->m_Children[j]->m_Box.Origin(),
|
||||
someOctTree.m_Root->m_Children[j]->m_Box.HalfSize().x, someOctTree.m_Root->m_Children[j], tempId);
|
||||
|
||||
auto someChild = someOctTree.m_Root->m_Children[j];
|
||||
|
||||
for (size_t i = 0; i < 8; i++)
|
||||
{
|
||||
AddBoxModel(someChild->m_Children[i]->m_Box.Origin(),
|
||||
someChild->m_Children[i]->m_Box.HalfSize().x, someChild->m_Children[i], tempId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}//end CreateEnt
|
||||
|
||||
void createTestEntitiesTest2()
|
||||
{
|
||||
World& world = *this;
|
||||
|
||||
EntityID entityCollisionBox = world.CreateEntity();
|
||||
ComponentWrapper transform = world.AttachComponent(entityCollisionBox, "Transform");
|
||||
transform["Position"] = glm::vec3(0.f, 2.f, 0.f);
|
||||
ComponentWrapper model = world.AttachComponent(entityCollisionBox, "Model");
|
||||
model["Resource"] = "Models/Core/UnitBox.obj";
|
||||
}
|
||||
|
||||
void AddBoxModel(const glm::vec3 ¢er, const float &halfSize, Octree::Child* child, EntityID &outEntityId) {
|
||||
World& world = *this;
|
||||
|
||||
EntityID entityDummyScene = world.CreateEntity();
|
||||
outEntityId = entityDummyScene;
|
||||
ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform");
|
||||
transform["Position"] = center;
|
||||
transform["Scale"] = glm::vec3(1.0f, 1.0f, 1.0f)*halfSize*2.0f*0.97f;
|
||||
ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model");
|
||||
model["Resource"] = "Models/Core/UnitBox.obj";
|
||||
model["Color"] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
if (child->m_DynamicObjIndices.size() != 0)
|
||||
model["Color"] = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
linkOM.emplace_back(entityDummyScene, child, center);
|
||||
}
|
||||
};
|
||||
@@ -100,7 +100,7 @@ void OctTree::Update(float dt, World* world, Camera* cam)
|
||||
{
|
||||
AABB aabb;
|
||||
for (ComponentWrapper& c : *world->GetComponents("Collision")) {
|
||||
aabb.CreateFromCenter(c["BoxCenter"], c["BoxSize"]);
|
||||
aabb.FromOriginSize(c["BoxCenter"], c["BoxSize"]);
|
||||
AddStaticObject(aabb);
|
||||
}
|
||||
const glm::vec4 redCol = glm::vec4(1, 0.2f, 0, 1);
|
||||
@@ -118,7 +118,7 @@ void OctTree::Update(float dt, World* world, Camera* cam)
|
||||
|
||||
AABB box;
|
||||
auto boxPos = cam->Position() + 1.2f*cam->Forward();
|
||||
box.CreateFromCenter(boxPos, boxSize);
|
||||
box.FromOriginSize(boxPos, boxSize);
|
||||
ComponentWrapper transform = world->GetComponent(m_BoxID, "Transform");
|
||||
transform["Position"] = boxPos;
|
||||
ComponentWrapper model = world->GetComponent(m_BoxID, "Model");
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "Core/ResourceManager.h"
|
||||
#include "Core/ConfigFile.h"
|
||||
#include "Rendering/Renderer.h"
|
||||
#include "Engine\Rendering\Texture.h"
|
||||
#include "Engine/Rendering/Texture.h"
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(resourceManagerTests)
|
||||
|
||||
@@ -19,16 +19,14 @@ BOOST_AUTO_TEST_CASE(resourceManagerTest)
|
||||
|
||||
ResourceManager::RegisterType<ConfigFile>("ConfigFile");
|
||||
BOOST_CHECK(!ResourceManager::IsResourceLoaded("ConfigFile", "Config.ini"));
|
||||
auto m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||
|
||||
BOOST_CHECK_NO_THROW(ResourceManager::Load<ConfigFile>("Config.ini"));
|
||||
BOOST_CHECK(ResourceManager::IsResourceLoaded("ConfigFile", "Config.ini"));
|
||||
ResourceManager::Release("ConfigFile", "Config.ini");
|
||||
BOOST_CHECK(!ResourceManager::IsResourceLoaded("ConfigFile", "Config.ini"));
|
||||
|
||||
//configfile without register
|
||||
//check so output says "EE failed to load: type not registered..."
|
||||
auto m_ScreenQuadNoRegister = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
||||
BOOST_CHECK(!ResourceManager::IsResourceLoaded("Model", "Models/Core/ScreenQuad.obj"));
|
||||
|
||||
BOOST_CHECK_THROW(ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj"),Resource::FailedLoadingException);
|
||||
//there is no error feedback to check if you try to release the wrong resources - hence that cant be tested either
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user