Merge remote-tracking branch 'origin/master' into Forward+
# Conflicts: # include/Engine/Rendering/Renderer.h # resources/Schema/Components.xsd # resources/Schema/Entities/Test.xml # src/Engine/Rendering/Renderer.cpp
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
#ifndef Collision_h__
|
||||
#define Collision_h__
|
||||
|
||||
//NOTE: Collision.h needs to be #included before <GLFW/glfw3.h>,
|
||||
//because Collision #includes "RawModel.h", which has "Texture.h", which has "OpenGL.h" which must be #included first
|
||||
//or you will get "fatal error C1189: #error: gl.h included before glew.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Core/Ray.h"
|
||||
#include "Core/AABB.h"
|
||||
#include "Engine/Rendering/RawModel.h"
|
||||
#include "Core/Entity.h"
|
||||
|
||||
class World;
|
||||
struct ComponentWrapper;
|
||||
|
||||
namespace Collision
|
||||
{
|
||||
//Return true if the ray hits the box.
|
||||
bool RayAABBIntr(const Ray& ray, const AABB& box);
|
||||
bool RayVsAABB(const Ray& ray, const AABB& box);
|
||||
//Return true if the ray hits the box, also outputs distance from ray origin to intersection point in [outDistance].
|
||||
bool RayVsAABB(const Ray& ray, const AABB& box, float& outDistance);
|
||||
|
||||
//Return true if the ray hits any of the triangles in the model. Stops checking when a hit is detected.
|
||||
bool RayVsModel(const Ray& ray,
|
||||
const std::vector<RawModel::Vertex>& modelVertices,
|
||||
const std::vector<unsigned int>& modelIndices);
|
||||
//Return true if the ray hits any of the triangles in the model.
|
||||
//Also returns the position of the intersection point. Will loop through all the whole model indices.
|
||||
bool RayVsModel(const Ray& ray,
|
||||
const std::vector<RawModel::Vertex>& modelVertices,
|
||||
const std::vector<unsigned int>& modelIndices,
|
||||
glm::vec3& outHitPosition);
|
||||
//Return true if the ray hits any of the triangles in the model.
|
||||
//Also returns the distance from the ray origin to the closest
|
||||
//intersection point, and the barycentric u,v-coordinates. Will loop through all the whole model indices.
|
||||
bool RayVsModel(const Ray& ray,
|
||||
const std::vector<RawModel::Vertex>& modelVertices,
|
||||
const std::vector<unsigned int>& modelIndices,
|
||||
float& outDistance,
|
||||
float& outUCoord,
|
||||
float& outVCoord);
|
||||
|
||||
//Return true if the boxes are intersecting.
|
||||
bool AABBVsAABB(const AABB& a, const AABB& b);
|
||||
//Return true if the boxes are intersecting.
|
||||
//Also outputs the minimum translation that box [a] would need in order to resolve collision.
|
||||
bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation);
|
||||
bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon = 0.0001f);
|
||||
|
||||
//Returns true if the entity has a boundingbox. Outputs the aabb in [outBox].
|
||||
bool GetEntityBox(World* world, EntityID entity, AABB& outBox, bool forceBoxFromModel = false);
|
||||
bool GetEntityBox(World* world, ComponentWrapper& AABBComponent, AABB& outBox);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef CollisionSystem_h__
|
||||
#define CollisionSystem_h__
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/common.hpp>
|
||||
|
||||
#include "Common.h"
|
||||
#include "Core/System.h"
|
||||
#include "Core/EventBroker.h"
|
||||
#include "Core/EKeyUp.h"
|
||||
|
||||
class CollisionSystem : public PureSystem
|
||||
{
|
||||
public:
|
||||
CollisionSystem(EventBroker* eventBroker)
|
||||
: PureSystem(eventBroker, "AABB")
|
||||
, zPress(false)
|
||||
{
|
||||
//TODO: Debug stuff, remove later.
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &CollisionSystem::OnKeyUp);
|
||||
}
|
||||
|
||||
virtual void UpdateComponent(World* world, ComponentWrapper& cAABB, double dt) override;
|
||||
|
||||
private:
|
||||
bool zPress;
|
||||
EventRelay<CollisionSystem, Events::KeyUp> m_EKeyUp;
|
||||
bool OnKeyUp(const Events::KeyUp &event);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef Events_TriggerEnter_h__
|
||||
#define Events_TriggerEnter_h__
|
||||
|
||||
#include "../Core/EventBroker.h"
|
||||
#include "../Core/Entity.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
/** Thrown once, when an entity is only touching a trigger. */
|
||||
struct TriggerTouch : Event
|
||||
{
|
||||
/** The id of the entity that touches the trigger. */
|
||||
EntityID Entity;
|
||||
/** The id of the trigger entity. */
|
||||
EntityID Trigger;
|
||||
};
|
||||
|
||||
/** Thrown once, when an entity has completely left a trigger. */
|
||||
struct TriggerLeave : Event
|
||||
{
|
||||
/** The id of the entity that left the trigger. */
|
||||
EntityID Entity;
|
||||
/** The id of the trigger entity. */
|
||||
EntityID Trigger;
|
||||
};
|
||||
|
||||
/** Thrown once, when an entity is completely contained inside a trigger. */
|
||||
struct TriggerEnter : Event
|
||||
{
|
||||
/** The id of the entity that entered the trigger. */
|
||||
EntityID Entity;
|
||||
/** The id of the trigger entity. */
|
||||
EntityID Trigger;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef TriggerSystem_h__
|
||||
#define TriggerSystem_h__
|
||||
|
||||
#include <glm/common.hpp>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "Core/System.h"
|
||||
#include "Core/EventBroker.h"
|
||||
#include "ETrigger.h"
|
||||
|
||||
class AABB;
|
||||
|
||||
class TriggerSystem : public PureSystem
|
||||
{
|
||||
public:
|
||||
TriggerSystem(EventBroker* eventBroker)
|
||||
: PureSystem(eventBroker, "Trigger")
|
||||
{}
|
||||
|
||||
virtual void UpdateComponent(World* world, ComponentWrapper& collision, double dt) override;
|
||||
|
||||
private:
|
||||
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesTouchingTrigger;
|
||||
std::unordered_map<EntityID, std::unordered_set<EntityID>> m_EntitiesCompletelyInTrigger;
|
||||
|
||||
//True if leave event was thrown.
|
||||
bool throwLeaveIfWasInTrigger(std::unordered_set<EntityID>& triggerSet, EntityID pId, EntityID tId);
|
||||
template<typename Event>
|
||||
void publish(EntityID pId, EntityID tId)
|
||||
{
|
||||
Event e;
|
||||
e.Trigger = tId;
|
||||
e.Entity = pId;
|
||||
m_EventBroker->Publish(e);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -4,4 +4,5 @@
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Core/Util/Logging.h"
|
||||
#include "Core/Util/Logging.h"
|
||||
#include "Core/Util/IfDebug.h"
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef AABB_h__
|
||||
#define AABB_h__
|
||||
|
||||
#include "../GLM.h"
|
||||
|
||||
class AABB
|
||||
{
|
||||
public:
|
||||
AABB() = default;
|
||||
//No checks are made. Values in minPos must be less than values in maxPos, i.e. min.x < max.x, etc.
|
||||
AABB(const glm::vec3& minPos, const glm::vec3& maxPos);
|
||||
AABB(const glm::vec4& minPos, const glm::vec4& maxPos);
|
||||
//No checks are made. Size must consist of non-negative numbers.
|
||||
virtual void CreateFromCenter(const glm::vec3& center, const glm::vec3& size);
|
||||
virtual ~AABB();
|
||||
|
||||
const glm::vec3& MinCorner() const { return m_MinCorner; }
|
||||
const glm::vec3& MaxCorner() const { return m_MaxCorner; }
|
||||
const glm::vec3& Center() const { return m_Center; }
|
||||
const glm::vec3 Size() const { return 2.0f * m_HalfSize; }
|
||||
const glm::vec3& HalfSize() const { return m_HalfSize; }
|
||||
private:
|
||||
glm::vec3 m_MinCorner;
|
||||
glm::vec3 m_MaxCorner;
|
||||
glm::vec3 m_Center;
|
||||
glm::vec3 m_HalfSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
~ComponentPoolForwardIterator() = default;
|
||||
ComponentPoolForwardIterator& operator=(const ComponentPoolForwardIterator& other) = default;
|
||||
ComponentPoolForwardIterator& operator++();
|
||||
ComponentPoolForwardIterator& operator++(int);
|
||||
ComponentPoolForwardIterator operator++(int);
|
||||
bool operator!=(const ComponentPoolForwardIterator& other) const;
|
||||
bool operator==(const ComponentPoolForwardIterator& other) const;
|
||||
ComponentWrapper operator*() const;
|
||||
|
||||
@@ -253,7 +253,7 @@ public:
|
||||
}
|
||||
|
||||
//Postfix increment i.e. iter++. Prefer pre-increment (++iter) for efficiency.
|
||||
MemoryPoolForwardIterator& operator++(int)
|
||||
MemoryPoolForwardIterator operator++(int)
|
||||
{
|
||||
MemoryPoolForwardIterator<T> copyIter(*this);
|
||||
operator++();
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#ifndef OctTree_h__
|
||||
#define OctTree_h__
|
||||
|
||||
#include "Core/AABB.h"
|
||||
|
||||
class Ray;
|
||||
|
||||
class OctTree
|
||||
{
|
||||
public:
|
||||
struct Output
|
||||
{
|
||||
float CollideDistance;
|
||||
};
|
||||
|
||||
OctTree();
|
||||
~OctTree();
|
||||
//For the root OctTree, [octTreeBounds] should be a box containing the entire level.
|
||||
OctTree(const AABB& octTreeBounds, int subDivisions);
|
||||
|
||||
//We cannot copy the OctTree as of now, because of the recursive dynamic allocation.
|
||||
//Define these if the OctTree suddenly needs to be copied, think of the children OctChild* ptrs.
|
||||
OctTree(const OctTree& other) = delete;
|
||||
OctTree(const OctTree&& other) = delete;
|
||||
OctTree& operator= (const OctTree& other) = delete;
|
||||
//Add a dynamic object (one that moves around) into the tree.
|
||||
void AddDynamicObject(const AABB& box);
|
||||
//Add a static object (that does not move) into the tree.
|
||||
void AddStaticObject(const AABB& box);
|
||||
//Get the boxes that are in the same area as the input [box], the boxes are put in [outBoxes].
|
||||
void BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes);
|
||||
//Empty the tree of all objects, static and dynamic.
|
||||
void ClearObjects();
|
||||
//Empty the tree of all dynamic objects. Static objects remain in the tree.
|
||||
void ClearDynamicObjects();
|
||||
|
||||
//Returns true if the ray collides with something in the tree. Result is written to [data].
|
||||
bool RayCollides(const Ray& ray, Output& data);
|
||||
//Returns true if the box collides with something in the tree.
|
||||
//On collision with a box, that box is written to [outBoxIntersected].
|
||||
//Note: More efficient than calling BoxesInSameRegion from outside and testing there.
|
||||
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected);
|
||||
|
||||
private:
|
||||
struct OctChild; //Fwd declaration;
|
||||
struct ContainedObject
|
||||
{
|
||||
ContainedObject()
|
||||
: Box(AABB())
|
||||
, Checked(false)
|
||||
{}
|
||||
ContainedObject(AABB box)
|
||||
: Box(box)
|
||||
, Checked(false)
|
||||
{}
|
||||
AABB Box;
|
||||
bool Checked;
|
||||
};
|
||||
OctChild* m_Root;
|
||||
std::vector<ContainedObject> m_StaticObjects;
|
||||
std::vector<ContainedObject> m_DynamicObjects;
|
||||
|
||||
bool m_UpdatedOnce;
|
||||
unsigned int m_BoxID;
|
||||
glm::vec3 m_PrevPos;
|
||||
glm::quat m_PrevOri;
|
||||
|
||||
void falsifyObjectChecks();
|
||||
|
||||
struct OctChild
|
||||
{
|
||||
~OctChild();
|
||||
OctChild(const AABB& octTreeBounds,
|
||||
int subDivisions,
|
||||
std::vector<OctTree::ContainedObject>& staticObjects,
|
||||
std::vector<OctTree::ContainedObject>& dynamicObjects);
|
||||
OctChild(const OctChild& other) = delete;
|
||||
OctChild(const OctChild&& other) = delete;
|
||||
OctChild& operator= (const OctChild& other) = delete;
|
||||
void AddDynamicObject(const AABB& box);
|
||||
void AddStaticObject(const AABB& box);
|
||||
void BoxesInSameRegion(const AABB& box, std::vector<AABB>& outBoxes) const;
|
||||
void ClearObjects();
|
||||
void ClearDynamicObjects();
|
||||
bool RayCollides(const Ray& ray, Output& data) const;
|
||||
bool BoxCollides(const AABB& boxToTest, AABB& outBoxIntersected) const;
|
||||
|
||||
OctChild* m_Children[8];
|
||||
//Indices into the lists in OctTree.
|
||||
std::vector<int> m_StaticObjIndices;
|
||||
std::vector<int> m_DynamicObjIndices;
|
||||
AABB m_Box;
|
||||
//Reference to the lists in OctTree.
|
||||
std::vector<OctTree::ContainedObject>& m_StaticObjectsRef;
|
||||
std::vector<OctTree::ContainedObject>& m_DynamicObjectsRef;
|
||||
|
||||
inline bool hasChildren() const;
|
||||
int childIndexContainingPoint(const glm::vec3& point) const;
|
||||
std::vector<int> childIndicesContainingBox(const AABB& box) const;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef Ray_h__
|
||||
#define Ray_h__
|
||||
|
||||
#include "../GLM.h"
|
||||
#include "Common.h"
|
||||
|
||||
class Ray
|
||||
{
|
||||
public:
|
||||
Ray(const glm::vec3& origin, const glm::vec3& dir)
|
||||
: m_Origin(origin)
|
||||
, m_Direction(glm::normalize(dir))
|
||||
{
|
||||
DEBUG_IF(true) {
|
||||
if (glm::any(glm::isnan(m_Direction))) {
|
||||
LOG_WARNING("Ray Direction was set to the zero-vector, expect unknown side effects and/or crashes.");
|
||||
}
|
||||
}
|
||||
}
|
||||
const glm::vec3& Origin() const { return m_Origin; }
|
||||
const glm::vec3& Direction() const { return m_Direction; }
|
||||
//Sets the ray origin at parameter.
|
||||
void SetOrigin(const glm::vec3& origin) { m_Origin = origin; }
|
||||
//Normalizes the parameter and sets direction to it.
|
||||
void SetDirection(const glm::vec3& direction) { m_Direction = glm::normalize(direction); }
|
||||
private:
|
||||
glm::vec3 m_Origin;
|
||||
glm::vec3 m_Direction;
|
||||
};
|
||||
|
||||
#endif // Ray_h__
|
||||
@@ -7,10 +7,13 @@
|
||||
|
||||
class System
|
||||
{
|
||||
friend class SystemPipeline;
|
||||
|
||||
protected:
|
||||
System(EventBroker* eventBroker)
|
||||
: m_EventBroker(eventBroker)
|
||||
{ }
|
||||
virtual ~System() = default;
|
||||
|
||||
EventBroker* m_EventBroker;
|
||||
};
|
||||
@@ -24,6 +27,7 @@ protected:
|
||||
: System(eventBroker)
|
||||
, m_ComponentType(componentType)
|
||||
{ }
|
||||
virtual ~PureSystem() = default;
|
||||
|
||||
const std::string m_ComponentType;
|
||||
|
||||
@@ -38,6 +42,7 @@ protected:
|
||||
ImpureSystem(EventBroker* eventBroker)
|
||||
: System(eventBroker)
|
||||
{ }
|
||||
virtual ~ImpureSystem() = default;
|
||||
|
||||
virtual void Update(World* world, double dt) = 0;
|
||||
};
|
||||
|
||||
@@ -14,10 +14,8 @@ public:
|
||||
{ }
|
||||
~SystemPipeline()
|
||||
{
|
||||
for (auto& pair : m_PureSystems) {
|
||||
for (auto& system : pair.second) {
|
||||
delete system;
|
||||
}
|
||||
for (auto& pair : m_Systems) {
|
||||
delete pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Example:
|
||||
// DEBUG_IF(condition) {
|
||||
// // This code is executed only in debug mode and if condition is true.
|
||||
// }
|
||||
// NOTE: condition statement is not executed at all in release mode.
|
||||
#ifndef DEBUG_IF
|
||||
#ifndef DEBUG
|
||||
#define DEBUG_IF(c) if(c)
|
||||
#else
|
||||
#define DEBUG_IF(c) if(false)
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,14 +1,84 @@
|
||||
#ifndef Client_h__
|
||||
#define Client_h__
|
||||
|
||||
#include <boost\asio.hpp>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
|
||||
class Client
|
||||
#include <glm/common.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include "Network/Network.h"
|
||||
#include "Network/MessageType.h"
|
||||
#include "Network/PlayerDefinition.h"
|
||||
#include "Network/SnapshotDefinitions.h"
|
||||
#include "Core/World.h"
|
||||
#include "Core/EventBroker.h"
|
||||
#include "Core/ConfigFile.h"
|
||||
#include "Input/EInputCommand.h"
|
||||
|
||||
class Client : public Network
|
||||
{
|
||||
Client();
|
||||
~Client();
|
||||
public:
|
||||
Client(ConfigFile* config);
|
||||
~Client();
|
||||
void Start(World* world, EventBroker* eventBroker) override;
|
||||
void Update() override;
|
||||
void Close();
|
||||
private:
|
||||
// Assio UDP logic
|
||||
boost::asio::ip::udp::endpoint m_ReceiverEndpoint;
|
||||
boost::asio::io_service m_IOService;
|
||||
boost::asio::ip::udp::socket m_Socket;
|
||||
|
||||
// Sending message to server logic
|
||||
int bytesRead = -1;
|
||||
char readBuf[1024] = { 0 };
|
||||
int snapshotInterval = 33;
|
||||
std::clock_t previousSnapshotMessage = std::clock();
|
||||
|
||||
// Packet loss logic
|
||||
unsigned int m_PacketID = 0;
|
||||
unsigned int m_PreviousPacketID = 0;
|
||||
unsigned int m_SendPacketID = 0;
|
||||
|
||||
// Game logic
|
||||
World* m_World;
|
||||
std::string m_PlayerName;
|
||||
int m_PlayerID = -1;
|
||||
|
||||
// Network logic
|
||||
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
|
||||
SnapshotDefinitions m_NextSnapshot;
|
||||
bool m_ThreadIsRunning = true;
|
||||
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;
|
||||
|
||||
// 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 parseConnect(Packet& packet);
|
||||
void parsePing();
|
||||
void parseServerPing();
|
||||
void parseSnapshot(Packet& packet);
|
||||
void identifyPacketLoss();
|
||||
bool isConnected();
|
||||
EntityID createPlayer();
|
||||
|
||||
// Events
|
||||
EventBroker* m_EventBroker;
|
||||
EventRelay<Client, Events::InputCommand> m_EInputCommand;
|
||||
bool OnInputCommand(const Events::InputCommand &e);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef MessageType_h__
|
||||
#define MessageType_h__
|
||||
|
||||
// Message types used by both server and client.
|
||||
// Used to determine what type of message was sent.
|
||||
enum class MessageType
|
||||
{
|
||||
Connect,
|
||||
Disconnect,
|
||||
ClientPing,
|
||||
ServerPing,
|
||||
Message,
|
||||
Snapshot,
|
||||
Event,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef Network_h__
|
||||
#define Network_h__
|
||||
|
||||
#include "Core/World.h"
|
||||
#include "Core/EventBroker.h"
|
||||
#include "Network/Packet.h"
|
||||
|
||||
#define MAXCONNECTIONS 8
|
||||
#define INPUTSIZE 128
|
||||
|
||||
class Network
|
||||
{
|
||||
public:
|
||||
virtual ~Network() { };
|
||||
virtual void Start(World* m_world, EventBroker *eventBroker) = 0;
|
||||
virtual void Update() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,61 @@
|
||||
#ifndef Packet_h__
|
||||
#define Packet_h__
|
||||
|
||||
#include <string>
|
||||
#include "Network/MessageType.h"
|
||||
#include "Core/Util/Logging.h"
|
||||
|
||||
// Defines the
|
||||
class Packet
|
||||
{
|
||||
public:
|
||||
// arg1: Type of message (Connect, Disconnect...)
|
||||
// arg2: PacketID for identifying packet loss.
|
||||
Packet(MessageType type, unsigned int& packetID);
|
||||
// Used to create packet from already existing data buffer.
|
||||
Packet(char* data, const int sizeOfPacket);
|
||||
|
||||
~Packet();
|
||||
// Add primitive types like int, float, char...
|
||||
template<typename T>
|
||||
void WritePrimitive(T val)
|
||||
{
|
||||
// Check if we are trying to add more than the package can fit.
|
||||
if (m_MaxPacketSize < m_Offset + sizeof(T)) {
|
||||
LOG_WARNING("Packet AddPrimitive(): You are trying to add more than we have allocated for!");
|
||||
}
|
||||
memcpy(m_Data + m_Offset, &val, sizeof(T));
|
||||
m_Offset += sizeof(T);
|
||||
}
|
||||
// Pops the first element as if it was a primitive.
|
||||
template<typename T>
|
||||
T ReadPrimitive()
|
||||
{
|
||||
if (m_Offset < m_ReturnDataOffset + sizeof(T)) {
|
||||
LOG_WARNING("Packet PopFrontPrimitive(): You are trying to remove more than what exists in this packet!");
|
||||
return -1;
|
||||
}
|
||||
T returnValue;
|
||||
memcpy(&returnValue, m_Data + m_ReturnDataOffset, sizeof(T));
|
||||
m_ReturnDataOffset += sizeof(T);
|
||||
return returnValue;
|
||||
}
|
||||
// Add a string to the message
|
||||
void WriteString(std::string str);
|
||||
// Add data to the message
|
||||
void WriteData(char* data, int sizeOfData);
|
||||
// Pops the first element as if it was a string.
|
||||
std::string ReadString();
|
||||
char* ReadData(int SizeOfData);
|
||||
|
||||
int Size() { return m_Offset; };
|
||||
char* Data() { return m_Data; };
|
||||
|
||||
private:
|
||||
char* m_Data;
|
||||
unsigned int m_ReturnDataOffset = 0;
|
||||
int m_Offset = 0;
|
||||
unsigned int m_MaxPacketSize = 128;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef PlayerDefinition_h__
|
||||
#define PlayerDefinition_h__
|
||||
#include <string>
|
||||
|
||||
struct PlayerDefinition {
|
||||
int EntityID = -1;
|
||||
std::string Name = "";
|
||||
boost::asio::ip::udp::endpoint Endpoint;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,12 +1,85 @@
|
||||
#ifndef Server_h__
|
||||
#define Server_h__
|
||||
|
||||
#include <boost\asio.hpp>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
|
||||
class Server
|
||||
#include <glm/common.hpp>
|
||||
#include <boost/asio/ip/udp.hpp>
|
||||
|
||||
#include "Network/MessageType.h"
|
||||
#include "Network/PlayerDefinition.h"
|
||||
#include "Core/World.h"
|
||||
#include "Core/EventBroker.h"
|
||||
#include "Network/Network.h"
|
||||
|
||||
class Server : public Network
|
||||
{
|
||||
Server();
|
||||
~Server();
|
||||
public:
|
||||
Server();
|
||||
~Server();
|
||||
void Start(World* m_world, EventBroker *eventBroker) override;
|
||||
void Update() override;
|
||||
void Close();
|
||||
|
||||
private:
|
||||
// UDP logic
|
||||
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
|
||||
char readBuffer[1024] = { 0 };
|
||||
int bytesRead = 0;
|
||||
// time for previouse message
|
||||
std::clock_t previousePingMessage = std::clock();
|
||||
std::clock_t previousSnapshotMessage = std::clock();
|
||||
std::clock_t timOutTimer = std::clock();
|
||||
// How often we send messages (milliseconds)
|
||||
int intervalMs = 1000;
|
||||
int snapshotInterval = 50;
|
||||
int checkTimeOutInterval = 100;
|
||||
|
||||
//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;
|
||||
|
||||
// Close logic
|
||||
bool m_ThreadIsRunning = true;
|
||||
|
||||
// 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 parseConnect(Packet& packet);
|
||||
void parseDisconnect();
|
||||
void parseClientPing();
|
||||
void parseServerPing();
|
||||
void parseSnapshot(Packet& packet);
|
||||
void identifyPacketLoss();
|
||||
EntityID createPlayer();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef SnapshotDefinitions_h__
|
||||
#define SnapshotDefinitions_h__
|
||||
|
||||
struct SnapshotDefinitions
|
||||
{
|
||||
// "+Forward" is 8 characters * sizeof(char) = 8
|
||||
std::string InputForward;
|
||||
// "+Right" is 6 characters * sizeof(char) = 6
|
||||
std::string InputRight;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
virtual void Draw(RenderQueueCollection& rq) = 0;
|
||||
|
||||
protected:
|
||||
Rectangle m_Resolution = Rectangle(1280, 720);
|
||||
Rectangle m_Resolution = Rectangle::Rectangle(1280, 720);
|
||||
bool m_Fullscreen = false;
|
||||
bool m_VSYNC = false;
|
||||
int m_GLVersion[2];
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "../Core/World.h"
|
||||
#include "PickingPass.h"
|
||||
#include "DrawScenePass.h"
|
||||
#include "DebugCameraInputController.h"
|
||||
#include "LightCullingPass.h"
|
||||
#include "DrawFinalPass.h"
|
||||
|
||||
@@ -34,6 +35,8 @@ private:
|
||||
//----------------------Variables----------------------//
|
||||
EventBroker* m_EventBroker;
|
||||
|
||||
std::shared_ptr<DebugCameraInputController<Renderer>> m_DebugCameraInputController;
|
||||
|
||||
Texture* m_ErrorTexture;
|
||||
Texture* m_WhiteTexture;
|
||||
float m_CameraMoveSpeed;
|
||||
|
||||
Reference in New Issue
Block a user