Compare commits
88 Commits
Forward+
...
Networking
| Author | SHA1 | Date | |
|---|---|---|---|
| ac0c6ff952 | |||
| 06f64f8fbf | |||
| 0c56a05144 | |||
| 382eff169f | |||
| d4797b0808 | |||
| 25890c8d6c | |||
| 0fb1dbcae1 | |||
| 9f3d887ac4 | |||
| b4081b3e45 | |||
| 8d61632c26 | |||
| 2eaad2aa00 | |||
| 235b26ad61 | |||
| f80fb5eda8 | |||
| aa115befa9 | |||
| aa20b48188 | |||
| 96a735c542 | |||
| 3261e21d96 | |||
| 666f1fd878 | |||
| 373bb33cf0 | |||
| 4c5d17b203 | |||
| 8286d052b3 | |||
| aaa11d2109 | |||
| 67477ff3ae | |||
| b5b1140f5c | |||
| 7567f47a68 | |||
| 97d70f8e32 | |||
| 3baa988ad4 | |||
| 1ce9128da8 | |||
| a28748b35d | |||
| 132de88d28 | |||
| f1835fd89c | |||
| ecdb5ed07d | |||
| 6d2c656a04 | |||
| 2bf0434bcb | |||
| 666ef6589e | |||
| b83d773627 | |||
| 482689fd48 | |||
| 32f73201c5 | |||
| 3aeeb3cad5 | |||
| 4d5cbb6057 | |||
| db0e67b9bd | |||
| 31e7340daf | |||
| 3ac3311c0c | |||
| 90867b094a | |||
| 55ee2bb3bf | |||
| 406b730ef3 | |||
| b37b20b7d8 | |||
| 750442d224 | |||
| 389e057611 | |||
| 74d9bae896 | |||
| 74c95089ea | |||
| ca2aab449e | |||
| 08c476e9e3 | |||
| 10c3b475bf | |||
| 08fcdb382b | |||
| b1ea5429ce | |||
| fcc9d64e7a | |||
| 7a95880e10 | |||
| 6cd073c3c8 | |||
| 1e3fc1ae2d | |||
| c984f76b2f | |||
| 84b7cf165c | |||
| 386e76f642 | |||
| a47317bb32 | |||
| e643581971 | |||
| 3826142e94 | |||
| 2a3009212a | |||
| 16c39df439 | |||
| 8437b9c734 | |||
| 6317a6092d | |||
| 4e70439653 | |||
| 24486c314d | |||
| 7b62dc19bf | |||
| 0e90382fd1 | |||
| 1667358e0c | |||
| eb5fca898f | |||
| c9db46564f | |||
| 509a989d3b | |||
| bc4cc5db54 | |||
| 73708ec706 | |||
| 67017fcaf4 | |||
| 498afb3a5e | |||
| 4e535c1102 | |||
| 1689370356 | |||
| 60b3ce89b2 | |||
| a22d086e60 | |||
| 74c1beed20 | |||
| c8cb0ee939 |
@@ -4,3 +4,11 @@ bin/
|
|||||||
lib/
|
lib/
|
||||||
# Because apparently nobody has any self control
|
# Because apparently nobody has any self control
|
||||||
*.orig
|
*.orig
|
||||||
|
|
||||||
|
*.suo
|
||||||
|
*.sdf
|
||||||
|
tools/MayaExporter/MayaExporter/x64/Debug/
|
||||||
|
tools/MayaExporter/x64/Debug/
|
||||||
|
|
||||||
|
tools/MayaExporter/MayaExporter/Debug/
|
||||||
|
tools/MayaExporter/MayaExporter/GeneratedFiles/
|
||||||
|
|||||||
+1
-1
Submodule assets updated: e8174f630f...068fbb2d20
@@ -10,7 +10,8 @@
|
|||||||
|
|
||||||
#include "../Core/Ray.h"
|
#include "../Core/Ray.h"
|
||||||
#include "../Core/AABB.h"
|
#include "../Core/AABB.h"
|
||||||
#include "../Rendering/RawModel.h"
|
#include "Rendering/RawModelCustom.h"
|
||||||
|
//#include "Rendering/RawModelAssimp.h"
|
||||||
#include "../Core/Transform.h"
|
#include "../Core/Transform.h"
|
||||||
#include "../Core/Entity.h"
|
#include "../Core/Entity.h"
|
||||||
#include "../Core/EntityWrapper.h"
|
#include "../Core/EntityWrapper.h"
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef EComponentDeleted_h__
|
||||||
|
#define EComponentDeleted_h__
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "Event.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct ComponentDeleted : Event
|
||||||
|
{
|
||||||
|
EntityID Entity;
|
||||||
|
std::string ComponentType;
|
||||||
|
// True if the component was deleted as a result of the entity it was attached to being deleted
|
||||||
|
bool Cascaded;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef EEntityDeleted_h__
|
||||||
|
#define EEntityDeleted_h__
|
||||||
|
|
||||||
|
#include "Event.h"
|
||||||
|
#include "Entity.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct EntityDeleted : Event
|
||||||
|
{
|
||||||
|
EntityID DeletedEntity;
|
||||||
|
// True if the entity deletion was triggered because the entity's parent was deleted before it
|
||||||
|
bool Cascaded;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -2,15 +2,15 @@
|
|||||||
#define EPlayerDamage_h__
|
#define EPlayerDamage_h__
|
||||||
|
|
||||||
#include "EventBroker.h"
|
#include "EventBroker.h"
|
||||||
#include "../Core/Entity.h"
|
#include "../Core/EntityWrapper.h"
|
||||||
|
|
||||||
namespace Events
|
namespace Events
|
||||||
{
|
{
|
||||||
|
|
||||||
struct PlayerDamage : Event
|
struct PlayerDamage : Event
|
||||||
{
|
{
|
||||||
double DamageAmount;
|
EntityWrapper Player;
|
||||||
EntityID PlayerDamagedID;
|
double Damage;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef EPlayerSpawned_h__
|
||||||
|
#define EPlayerSpawned_h__
|
||||||
|
|
||||||
|
#include "Core/Event.h"
|
||||||
|
#include "Core/EntityWrapper.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct PlayerSpawned : Event
|
||||||
|
{
|
||||||
|
int PlayerID;
|
||||||
|
EntityWrapper Player;
|
||||||
|
EntityWrapper Spawner;
|
||||||
|
std::string PlayerName;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -2,16 +2,14 @@
|
|||||||
#define EShoot_h__
|
#define EShoot_h__
|
||||||
|
|
||||||
#include "EventBroker.h"
|
#include "EventBroker.h"
|
||||||
#include "../Core/Entity.h"
|
#include "../Core/EntityWrapper.h"
|
||||||
#include "Engine/GLM.h"
|
|
||||||
|
|
||||||
namespace Events
|
namespace Events
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Shoot : Event
|
struct Shoot : Event
|
||||||
{
|
{
|
||||||
//ID for who made the shot
|
EntityWrapper Player;
|
||||||
EntityID shooter;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,11 @@ struct EntityWrapper
|
|||||||
|
|
||||||
static const EntityWrapper Invalid;
|
static const EntityWrapper Invalid;
|
||||||
|
|
||||||
bool HasComponent(const std::string& componentName);
|
bool HasComponent(const std::string& componentType);
|
||||||
EntityWrapper Parent();
|
EntityWrapper Parent();
|
||||||
|
EntityWrapper FirstChildByName(const std::string& name);
|
||||||
|
EntityWrapper FirstParentWithComponent(const std::string& componentType);
|
||||||
|
bool IsChildOf(EntityWrapper potentialParent);
|
||||||
bool Valid();
|
bool Valid();
|
||||||
|
|
||||||
ComponentWrapper operator[](const char* componentName);
|
ComponentWrapper operator[](const char* componentName);
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ struct Child
|
|||||||
std::vector<ContainedObject>& m_StaticObjectsRef;
|
std::vector<ContainedObject>& m_StaticObjectsRef;
|
||||||
std::vector<ContainedObject>& m_DynamicObjectsRef;
|
std::vector<ContainedObject>& m_DynamicObjectsRef;
|
||||||
|
|
||||||
inline bool hasChildren() const;
|
bool hasChildren() const;
|
||||||
int childIndexContainingPoint(const glm::vec3& point) const;
|
int childIndexContainingPoint(const glm::vec3& point) const;
|
||||||
std::vector<int> childIndicesContainingBox(const AABB& box) const;
|
std::vector<int> childIndicesContainingBox(const AABB& box) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ public:
|
|||||||
};
|
};
|
||||||
struct FailedLoadingException : public std::exception
|
struct FailedLoadingException : public std::exception
|
||||||
{
|
{
|
||||||
virtual const char* what() const throw()
|
FailedLoadingException(char const* const _Message)
|
||||||
{
|
: std::exception(_Message)
|
||||||
return "Resource is failed to load.";
|
{ }
|
||||||
}
|
FailedLoadingException() :std::exception("Resource failed to load.") { };
|
||||||
};
|
};
|
||||||
|
|
||||||
// Pretend that this is a pure virtual function that you have to implement
|
// Pretend that this is a pure virtual function that you have to implement
|
||||||
|
|||||||
@@ -3,13 +3,18 @@
|
|||||||
|
|
||||||
#include "../GLM.h"
|
#include "../GLM.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
#include "EntityWrapper.h"
|
||||||
|
|
||||||
namespace Transform
|
namespace Transform
|
||||||
{
|
{
|
||||||
|
|
||||||
|
glm::vec3 AbsolutePosition(EntityWrapper entity);
|
||||||
glm::vec3 AbsolutePosition(World* world, EntityID entity);
|
glm::vec3 AbsolutePosition(World* world, EntityID entity);
|
||||||
|
glm::quat AbsoluteOrientation(EntityWrapper entity);
|
||||||
glm::quat AbsoluteOrientation(World* world, EntityID entity);
|
glm::quat AbsoluteOrientation(World* world, EntityID entity);
|
||||||
|
glm::vec3 AbsoluteScale(EntityWrapper entity);
|
||||||
glm::vec3 AbsoluteScale(World* world, EntityID entity);
|
glm::vec3 AbsoluteScale(World* world, EntityID entity);
|
||||||
|
glm::mat4 ModelMatrix(EntityWrapper entity);
|
||||||
glm::mat4 ModelMatrix(EntityID entity, World* world);
|
glm::mat4 ModelMatrix(EntityID entity, World* world);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,15 @@
|
|||||||
#include "Entity.h"
|
#include "Entity.h"
|
||||||
#include "ObjectPool.h"
|
#include "ObjectPool.h"
|
||||||
#include "ComponentPool.h"
|
#include "ComponentPool.h"
|
||||||
|
#include "EventBroker.h"
|
||||||
|
|
||||||
class World
|
class World
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
World() = default;
|
World() = default;
|
||||||
|
World(EventBroker* eventBroker)
|
||||||
|
: m_EventBroker(eventBroker)
|
||||||
|
{ }
|
||||||
~World();
|
~World();
|
||||||
|
|
||||||
// Create empty entity
|
// Create empty entity
|
||||||
@@ -46,6 +50,7 @@ public:
|
|||||||
std::string GetName(EntityID entity) const;
|
std::string GetName(EntityID entity) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
EventBroker* m_EventBroker = nullptr;
|
||||||
EntityID m_CurrentEntityID = 0;
|
EntityID m_CurrentEntityID = 0;
|
||||||
|
|
||||||
std::unordered_map<EntityID, EntityID> m_EntityParents;
|
std::unordered_map<EntityID, EntityID> m_EntityParents;
|
||||||
@@ -55,6 +60,7 @@ private:
|
|||||||
std::unordered_map<EntityID, std::string> m_EntityNames;
|
std::unordered_map<EntityID, std::string> m_EntityNames;
|
||||||
|
|
||||||
EntityID generateEntityID();
|
EntityID generateEntityID();
|
||||||
|
void deleteEntityRecursive(EntityID entity, bool cascaded = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
#ifndef EditorCameraInputController_h__
|
||||||
|
#define EditorCameraInputController_h__
|
||||||
|
|
||||||
|
#include <imgui/imgui.h>
|
||||||
|
#include "../Input/FirstPersonInputController.h"
|
||||||
|
#include "../Core/EMousePress.h"
|
||||||
|
#include "../Core/EMouseRelease.h"
|
||||||
|
#include "../Core/EMouseScroll.h"
|
||||||
|
#include "../Core/ConfigFile.h"
|
||||||
|
|
||||||
|
template <typename EventContext>
|
||||||
|
class EditorCameraInputController : public FirstPersonInputController<EventContext>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditorCameraInputController(EventBroker* eventBroker, unsigned int playerID)
|
||||||
|
: FirstPersonInputController(eventBroker, playerID)
|
||||||
|
{
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorCameraInputController::OnMousePress);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &EditorCameraInputController::OnMouseRelease);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EMouseScroll, &EditorCameraInputController::OnMouseScroll);
|
||||||
|
|
||||||
|
m_Config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
|
m_SpeedMultiplier = m_Config->Get<float>("Editor.CameraSpeed", 3.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const glm::vec3 Movement() const override { return m_Movement * m_SpeedMultiplier; }
|
||||||
|
|
||||||
|
void Enable() { m_Enabled = true; }
|
||||||
|
void Disable() { m_Enabled = false; }
|
||||||
|
|
||||||
|
virtual bool OnCommand(const Events::InputCommand& e) override
|
||||||
|
{
|
||||||
|
if (glm::abs(e.Value) > 0 && !m_MouseLocked) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
if (glm::abs(e.Value) > 0 && (io.WantCaptureKeyboard || io.WantCaptureMouse)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Command == "Jump") {
|
||||||
|
if (e.Value > 0) {
|
||||||
|
m_Movement.y = glm::max(e.Value, 1.f);
|
||||||
|
} else {
|
||||||
|
m_Movement.y = 0.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Command == "Crouch") {
|
||||||
|
if (e.Value > 0) {
|
||||||
|
m_Movement.y = glm::min(-e.Value, -1.f);
|
||||||
|
} else {
|
||||||
|
m_Movement.y = 0.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Command == "Sprint") {
|
||||||
|
if (e.Value > 0) {
|
||||||
|
m_SpeedMultiplier *= 2.f;
|
||||||
|
} else {
|
||||||
|
m_SpeedMultiplier /= 2.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FirstPersonInputController::OnCommand(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ConfigFile* m_Config;
|
||||||
|
bool m_Enabled = false;
|
||||||
|
float m_SpeedMultiplier = 1.f;
|
||||||
|
|
||||||
|
EventRelay<EventContext, Events::MousePress> m_EMousePress;
|
||||||
|
bool OnMousePress(const Events::MousePress& e)
|
||||||
|
{
|
||||||
|
if (!m_Enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Button == GLFW_MOUSE_BUTTON_2) {
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
if (!io.WantCaptureMouse) {
|
||||||
|
LockMouse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
EventRelay<EventContext, Events::MouseRelease> m_EMouseRelease;
|
||||||
|
bool OnMouseRelease(const Events::MouseRelease& e)
|
||||||
|
{
|
||||||
|
if (!m_Enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Button == GLFW_MOUSE_BUTTON_2) {
|
||||||
|
UnlockMouse();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
EventRelay<EventContext, Events::MouseScroll> m_EMouseScroll;
|
||||||
|
bool OnMouseScroll(const Events::MouseScroll& e)
|
||||||
|
{
|
||||||
|
if (!m_Enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_SpeedMultiplier += e.DeltaY * (0.1f * m_SpeedMultiplier);
|
||||||
|
m_Config->Set("Editor.CameraSpeed", m_SpeedMultiplier);
|
||||||
|
m_Config->SaveToDisk();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "../Core/System.h"
|
#include "../Core/System.h"
|
||||||
#include "../Rendering/IRenderer.h"
|
#include "../Rendering/IRenderer.h"
|
||||||
#include "../Rendering/Camera.h"
|
#include "../Rendering/Camera.h"
|
||||||
#include "../Rendering/DebugCameraInputController.h"
|
|
||||||
#include "../Rendering/ESetCamera.h"
|
#include "../Rendering/ESetCamera.h"
|
||||||
#include "../Core/World.h"
|
#include "../Core/World.h"
|
||||||
#include "../Core/SystemPipeline.h"
|
#include "../Core/SystemPipeline.h"
|
||||||
@@ -10,8 +9,10 @@
|
|||||||
#include "../Core/EntityFileParser.h"
|
#include "../Core/EntityFileParser.h"
|
||||||
#include "../Core/EntityFileWriter.h"
|
#include "../Core/EntityFileWriter.h"
|
||||||
#include "../Core/EMousePress.h"
|
#include "../Core/EMousePress.h"
|
||||||
|
#include "../Input/EInputCommand.h"
|
||||||
#include "EditorGUI.h"
|
#include "EditorGUI.h"
|
||||||
#include "EditorStats.h"
|
#include "EditorStats.h"
|
||||||
|
#include "EditorCameraInputController.h"
|
||||||
|
|
||||||
class EditorSystem : public ImpureSystem
|
class EditorSystem : public ImpureSystem
|
||||||
{
|
{
|
||||||
@@ -21,18 +22,24 @@ public:
|
|||||||
|
|
||||||
void Update(double dt);
|
void Update(double dt);
|
||||||
|
|
||||||
|
void Enable();
|
||||||
|
void Disable();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IRenderer* m_Renderer;
|
IRenderer* m_Renderer;
|
||||||
RenderFrame* m_RenderFrame;
|
RenderFrame* m_RenderFrame;
|
||||||
World* m_EditorWorld;
|
World* m_EditorWorld;
|
||||||
SystemPipeline* m_EditorWorldSystemPipeline;
|
SystemPipeline* m_EditorWorldSystemPipeline;
|
||||||
Camera* m_EditorCamera;
|
//Camera* m_EditorCamera;
|
||||||
EntityWrapper m_Camera = EntityWrapper::Invalid;
|
EntityWrapper m_EditorCamera = EntityWrapper::Invalid;
|
||||||
DebugCameraInputController<EditorSystem>* m_DebugCameraInputController;
|
EntityWrapper m_ActualCamera = EntityWrapper::Invalid;
|
||||||
|
EditorCameraInputController<EditorSystem>* m_EditorCameraInputController;
|
||||||
EditorGUI* m_EditorGUI;
|
EditorGUI* m_EditorGUI;
|
||||||
EditorStats* m_EditorStats;
|
EditorStats* m_EditorStats;
|
||||||
|
|
||||||
// State
|
// State
|
||||||
|
double m_LastTime = 0.f;
|
||||||
|
bool m_Enabled = true;
|
||||||
EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate;
|
EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate;
|
||||||
EntityWrapper m_Widget = EntityWrapper::Invalid;
|
EntityWrapper m_Widget = EntityWrapper::Invalid;
|
||||||
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
|
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
|
||||||
@@ -56,4 +63,8 @@ private:
|
|||||||
bool OnMousePress(const Events::MousePress& e);
|
bool OnMousePress(const Events::MousePress& e);
|
||||||
EventRelay<EditorSystem, Events::WidgetDelta> m_EWidgetDelta;
|
EventRelay<EditorSystem, Events::WidgetDelta> m_EWidgetDelta;
|
||||||
bool OnWidgetDelta(const Events::WidgetDelta& e);
|
bool OnWidgetDelta(const Events::WidgetDelta& e);
|
||||||
|
EventRelay<EditorSystem, Events::InputCommand> m_EInputCommand;
|
||||||
|
bool OnInputCommand(const Events::InputCommand& e);
|
||||||
|
EventRelay<EditorSystem, Events::SetCamera> m_ESetCamera;
|
||||||
|
bool OnSetCamera(const Events::SetCamera& e);
|
||||||
};
|
};
|
||||||
@@ -9,7 +9,7 @@ namespace Events
|
|||||||
struct InputCommand : Event
|
struct InputCommand : Event
|
||||||
{
|
{
|
||||||
/** Numerical ID of the player. */
|
/** Numerical ID of the player. */
|
||||||
unsigned int PlayerID;
|
int PlayerID;
|
||||||
/** The command that was sent. */
|
/** The command that was sent. */
|
||||||
std::string Command;
|
std::string Command;
|
||||||
/** The value of the command. */
|
/** The value of the command. */
|
||||||
|
|||||||
@@ -9,62 +9,119 @@ template <typename EventContext>
|
|||||||
class FirstPersonInputController : public InputController<EventContext>
|
class FirstPersonInputController : public InputController<EventContext>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID)
|
FirstPersonInputController(EventBroker* eventBroker, int playerID);
|
||||||
: InputController(eventBroker)
|
|
||||||
, m_PlayerID(playerID)
|
|
||||||
{
|
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse);
|
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse);
|
|
||||||
}
|
|
||||||
|
|
||||||
const glm::quat Orientation() const { return m_Orientation; }
|
virtual const glm::vec3 Movement() const { return m_Movement; }
|
||||||
|
virtual const glm::vec3 Rotation() const { return m_Rotation; }
|
||||||
|
virtual bool Jumping() const { return m_Jumping; }
|
||||||
|
virtual bool Crouching() const { return m_Crouching; }
|
||||||
|
|
||||||
void LockMouse()
|
void LockMouse();
|
||||||
{
|
void UnlockMouse();
|
||||||
Events::LockMouse e;
|
virtual bool OnCommand(const Events::InputCommand& e) override;
|
||||||
m_EventBroker->Publish(e);
|
virtual void Reset();
|
||||||
m_MouseLocked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnlockMouse()
|
protected:
|
||||||
{
|
const int m_PlayerID;
|
||||||
Events::UnlockMouse e;
|
bool m_MouseLocked = false;
|
||||||
m_EventBroker->Publish(e);
|
glm::vec3 m_Rotation;
|
||||||
m_MouseLocked = false;
|
glm::vec3 m_Movement;
|
||||||
}
|
bool m_Jumping = false;
|
||||||
|
bool m_Crouching = false;
|
||||||
|
|
||||||
|
EventRelay<EventContext, Events::LockMouse> m_ELockMouse;
|
||||||
|
bool OnLockMouse(const Events::LockMouse& e);
|
||||||
|
EventRelay<EventContext, Events::UnlockMouse> m_EUnlockMouse;
|
||||||
|
bool OnUnlockMouse(const Events::UnlockMouse& e);
|
||||||
|
};
|
||||||
|
|
||||||
virtual bool OnCommand(const Events::InputCommand& e) override
|
template <typename EventContext>
|
||||||
{
|
FirstPersonInputController<EventContext>::FirstPersonInputController(EventBroker* eventBroker, int playerID)
|
||||||
if (m_PlayerID != e.PlayerID) {
|
: InputController(eventBroker)
|
||||||
return false;
|
, m_PlayerID(playerID)
|
||||||
}
|
{
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_MouseLocked) {
|
template <typename EventContext>
|
||||||
if (e.Command == "Pitch") {
|
void FirstPersonInputController<EventContext>::Reset()
|
||||||
float val = glm::radians(e.Value);
|
{
|
||||||
m_Orientation = m_Orientation * glm::angleAxis<float>(-val, glm::vec3(1, 0, 0));
|
m_Rotation = glm::vec3(0.f, 0.f, 0.f);
|
||||||
return true;
|
m_Jumping = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Command == "Yaw") {
|
template <typename EventContext>
|
||||||
float val = glm::radians(e.Value);
|
void FirstPersonInputController<EventContext>::LockMouse()
|
||||||
m_Orientation = glm::angleAxis<float>(-val, glm::vec3(0, 1, 0)) * m_Orientation;
|
{
|
||||||
return true;
|
Events::LockMouse e;
|
||||||
}
|
m_EventBroker->Publish(e);
|
||||||
}
|
m_MouseLocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename EventContext>
|
||||||
|
void FirstPersonInputController<EventContext>::UnlockMouse()
|
||||||
|
{
|
||||||
|
Events::UnlockMouse e;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
m_MouseLocked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename EventContext>
|
||||||
|
bool FirstPersonInputController<EventContext>::OnCommand(const Events::InputCommand& e)
|
||||||
|
{
|
||||||
|
if (m_PlayerID != e.PlayerID) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
if (e.Command == "Pitch") {
|
||||||
const unsigned int m_PlayerID;
|
float val = glm::radians(e.Value);
|
||||||
glm::quat m_Orientation;
|
m_Rotation.x += -val;
|
||||||
bool m_MouseLocked = false;
|
//m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi<float>(), glm::half_pi<float>());
|
||||||
|
}
|
||||||
EventRelay<EventContext, Events::LockMouse> m_ELockMouse;
|
|
||||||
bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; }
|
if (e.Command == "Yaw") {
|
||||||
EventRelay<EventContext, Events::UnlockMouse> m_EUnlockMouse;
|
float val = glm::radians(e.Value);
|
||||||
bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; }
|
m_Rotation.y += -val;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
if (e.Command == "Forward" || e.Command == "Right") {
|
||||||
|
if (e.Command == "Forward") {
|
||||||
|
float val = glm::clamp(e.Value, -1.f, 1.f);
|
||||||
|
m_Movement.z = -val;
|
||||||
|
}
|
||||||
|
if (e.Command == "Right") {
|
||||||
|
float val = glm::clamp(e.Value, -1.f, 1.f);
|
||||||
|
m_Movement.x = val;
|
||||||
|
}
|
||||||
|
if (glm::length2(m_Movement) > 0) {
|
||||||
|
m_Movement = glm::normalize(m_Movement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Command == "Jump") {
|
||||||
|
m_Jumping = e.Value > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Command == "Crouch") {
|
||||||
|
m_Crouching = e.Value > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename EventContext>
|
||||||
|
bool FirstPersonInputController<EventContext>::OnUnlockMouse(const Events::UnlockMouse& e)
|
||||||
|
{
|
||||||
|
m_MouseLocked = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename EventContext>
|
||||||
|
bool FirstPersonInputController<EventContext>::OnLockMouse(const Events::LockMouse& e)
|
||||||
|
{
|
||||||
|
m_MouseLocked = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "Input/EInputCommand.h"
|
#include "Input/EInputCommand.h"
|
||||||
#include "Core/EPlayerDamage.h"
|
#include "Core/EPlayerDamage.h"
|
||||||
#include "Network/EInterpolate.h"
|
#include "Network/EInterpolate.h"
|
||||||
|
#include "Core/EPlayerSpawned.h"
|
||||||
|
|
||||||
class Client : public Network
|
class Client : public Network
|
||||||
{
|
{
|
||||||
@@ -39,16 +40,18 @@ private:
|
|||||||
char readBuf[INPUTSIZE] = { 0 };
|
char readBuf[INPUTSIZE] = { 0 };
|
||||||
|
|
||||||
// Packet loss logic
|
// Packet loss logic
|
||||||
unsigned int m_PacketID = 0;
|
PacketID m_PacketID = 0;
|
||||||
unsigned int m_PreviousPacketID = 0;
|
PacketID m_PreviousPacketID = 0;
|
||||||
unsigned int m_SendPacketID = 0;
|
PacketID m_SendPacketID = 0;
|
||||||
|
AckBitPattern ackBitField = 0;
|
||||||
|
|
||||||
// Game logic
|
// Game logic
|
||||||
World* m_World;
|
World* m_World;
|
||||||
std::string m_PlayerName;
|
std::string m_PlayerName;
|
||||||
int m_PlayerID = -1;
|
PlayerID m_PlayerID = -1;
|
||||||
EntityID m_ServerEntityID = std::numeric_limits<EntityID>::max();
|
EntityID m_ServerEntityID = std::numeric_limits<EntityID>::max();
|
||||||
bool m_IsConnected = false;
|
bool m_IsConnected = false;
|
||||||
|
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
|
||||||
// Server Client Lookup map
|
// Server Client Lookup map
|
||||||
// Assumes that root node for client and server is EntityID 0.
|
// Assumes that root node for client and server is EntityID 0.
|
||||||
|
|
||||||
@@ -57,31 +60,36 @@ private:
|
|||||||
std::unordered_map<EntityID, EntityID> m_ClientIDToServerID;
|
std::unordered_map<EntityID, EntityID> m_ClientIDToServerID;
|
||||||
|
|
||||||
// Network logic
|
// Network logic
|
||||||
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
|
PlayerDefinition m_PlayerDefinitions[8];
|
||||||
SnapshotDefinitions m_NextSnapshot;
|
SnapshotDefinitions m_NextSnapshot;
|
||||||
double m_DurationOfPingTime;
|
double m_DurationOfPingTime;
|
||||||
std::clock_t m_StartPingTime;
|
std::clock_t m_StartPingTime;
|
||||||
|
std::clock_t m_TimeSinceSentInputs;
|
||||||
|
unsigned int m_SendInputIntervalMs;
|
||||||
std::vector<Events::InputCommand> m_InputCommandBuffer;
|
std::vector<Events::InputCommand> m_InputCommandBuffer;
|
||||||
|
|
||||||
// Private member functions
|
// Private member functions
|
||||||
void readFromServer();
|
void readFromServer();
|
||||||
int receive(char* data, size_t length);
|
int receive(char* data);
|
||||||
void send(Packet& packet);
|
void send(Packet& packet);
|
||||||
void connect();
|
void connect();
|
||||||
void disconnect();
|
void disconnect();
|
||||||
void ping();
|
|
||||||
void parseMessageType(Packet& packet);
|
void parseMessageType(Packet& packet);
|
||||||
void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType);
|
void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType);
|
||||||
void parseConnect(Packet& packet);
|
void parseConnect(Packet& packet);
|
||||||
void parsePlayerConnected(Packet& packet);
|
void parsePlayerConnected(Packet& packet);
|
||||||
void parsePing();
|
void parsePing();
|
||||||
void parseServerPing();
|
void parseKick();
|
||||||
|
void parsePlayersSpawned(Packet& packet);
|
||||||
|
void parseEntityDeletion(Packet& packet);
|
||||||
|
void parseComponentDeletion(Packet& packet);
|
||||||
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
|
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
|
||||||
void parseSnapshot(Packet& packet);
|
void parseSnapshot(Packet& packet);
|
||||||
void identifyPacketLoss();
|
void identifyPacketLoss();
|
||||||
bool hasServerTimedOut();
|
bool hasServerTimedOut();
|
||||||
EntityID createPlayer();
|
EntityID createPlayer();
|
||||||
void sendInputCommands();
|
void sendInputCommands();
|
||||||
|
void sendLocalPlayerTransform();
|
||||||
void becomePlayer();
|
void becomePlayer();
|
||||||
// Mapping Logic
|
// Mapping Logic
|
||||||
// Returns if local EntityID exist in map
|
// Returns if local EntityID exist in map
|
||||||
@@ -89,13 +97,16 @@ private:
|
|||||||
// Returns if server EntityID exist in map
|
// Returns if server EntityID exist in map
|
||||||
bool serverClientMapsHasEntity(EntityID serverEntityID);
|
bool serverClientMapsHasEntity(EntityID serverEntityID);
|
||||||
void insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID);
|
void insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID);
|
||||||
|
void deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID);
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
EventRelay<Client, Events::InputCommand> m_EInputCommand;
|
EventRelay<Client, Events::InputCommand> m_EInputCommand;
|
||||||
bool OnInputCommand(const Events::InputCommand& e);
|
bool OnInputCommand(const Events::InputCommand& e);
|
||||||
EventRelay<Client, Events::PlayerDamage> m_EPlayeDamage;
|
EventRelay<Client, Events::PlayerDamage> m_EPlayerDamage;
|
||||||
bool OnPlayerDamage(const Events::PlayerDamage& e);
|
bool OnPlayerDamage(const Events::PlayerDamage& e);
|
||||||
|
EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
|
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef Events_PlayerDisconnected
|
||||||
|
#define Events_PlayerDisconnected
|
||||||
|
|
||||||
|
#include "Core/EventBroker.h"
|
||||||
|
#include "Core/Entity.h"
|
||||||
|
|
||||||
|
namespace Events
|
||||||
|
{
|
||||||
|
|
||||||
|
struct PlayerDisconnected : public Event
|
||||||
|
{
|
||||||
|
unsigned int PlayerID;
|
||||||
|
EntityID Entity;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -5,16 +5,20 @@
|
|||||||
// Used to determine what type of message was sent.
|
// Used to determine what type of message was sent.
|
||||||
enum class MessageType
|
enum class MessageType
|
||||||
{
|
{
|
||||||
Connect,
|
Connect,
|
||||||
Disconnect,
|
Disconnect,
|
||||||
ClientPing,
|
Ping,
|
||||||
ServerPing,
|
Message,
|
||||||
Message,
|
Snapshot,
|
||||||
Snapshot,
|
|
||||||
OnInputCommand,
|
OnInputCommand,
|
||||||
OnPlayerDamage,
|
OnPlayerDamage,
|
||||||
PlayerConnected,
|
PlayerConnected,
|
||||||
BecomePlayer
|
BecomePlayer,
|
||||||
|
Kick,
|
||||||
|
OnPlayerSpawned,
|
||||||
|
EntityDeleted,
|
||||||
|
ComponentDeleted,
|
||||||
|
PlayerTransform
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
#ifndef Network_h__
|
#ifndef Network_h__
|
||||||
#define Network_h__
|
#define Network_h__
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
#include "Core/World.h"
|
#include "Core/World.h"
|
||||||
#include "Core/EventBroker.h"
|
#include "Core/EventBroker.h"
|
||||||
#include "Network/Packet.h"
|
#include "Network/Packet.h"
|
||||||
|
#include "Network/NetworkData.h"
|
||||||
|
#include "Core/ResourceManager.h"
|
||||||
|
#include "Core/ConfigFile.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
#define MAXCONNECTIONS 8
|
|
||||||
#define INPUTSIZE 4097
|
#define INPUTSIZE 4097
|
||||||
#define TIMEOUTMS 15000
|
typedef unsigned int PlayerID;
|
||||||
|
typedef unsigned int PacketID;
|
||||||
|
typedef unsigned int AckBitPattern;
|
||||||
|
|
||||||
class Network
|
class Network
|
||||||
{
|
{
|
||||||
@@ -15,6 +24,17 @@ public:
|
|||||||
virtual ~Network() { };
|
virtual ~Network() { };
|
||||||
virtual void Start(World* m_world, EventBroker *eventBroker) = 0;
|
virtual void Start(World* m_world, EventBroker *eventBroker) = 0;
|
||||||
virtual void Update() = 0;
|
virtual void Update() = 0;
|
||||||
|
protected:
|
||||||
|
// For Debug
|
||||||
|
bool isReadingData = false;
|
||||||
|
NetworkData m_NetworkData;
|
||||||
|
unsigned int m_SaveDataIntervalMs = 1000;
|
||||||
|
std::clock_t m_SaveDataTimer;
|
||||||
|
unsigned int m_MaxConnections;
|
||||||
|
unsigned int m_TimeoutMs;
|
||||||
|
void saveToFile();
|
||||||
|
void updateNetworkData();
|
||||||
|
void initialize();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef NetworkData_h__
|
||||||
|
#define NetworkData_h__
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct NetworkData {
|
||||||
|
unsigned int TotalTime = 0;
|
||||||
|
unsigned int TotalDataReceived = 0;
|
||||||
|
unsigned int TotalDataSent = 0;
|
||||||
|
unsigned int AmountOfMessagesReceived = 0;
|
||||||
|
unsigned int AmountOfMessagesSent = 0;
|
||||||
|
// Interval based
|
||||||
|
unsigned int DataReceivedThisInterval = 0;
|
||||||
|
unsigned int DataSentThisInterval = 0;
|
||||||
|
// pair: first=reveived, second=send
|
||||||
|
std::vector<std::pair<unsigned int, unsigned int>> BandwidthBytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -11,12 +11,12 @@ class Packet
|
|||||||
public:
|
public:
|
||||||
// arg1: Type of message (Connect, Disconnect...)
|
// arg1: Type of message (Connect, Disconnect...)
|
||||||
// arg2: PacketID for identifying packet loss.
|
// arg2: PacketID for identifying packet loss.
|
||||||
Packet(MessageType type, unsigned int& packetID);
|
Packet(MessageType type, unsigned int& packetID, unsigned int lastReceivedPacket, unsigned int ackBitField);
|
||||||
// Used to create packet from already existing data buffer.
|
// Used to create packet from already existing data buffer.
|
||||||
Packet(char* data, const int sizeOfPacket);
|
Packet(char* data, const int sizeOfPacket);
|
||||||
Packet(MessageType type);
|
Packet(MessageType type);
|
||||||
~Packet();
|
~Packet();
|
||||||
void Init(MessageType type, unsigned int& packetID);
|
void Init(MessageType type, unsigned int& packetID, unsigned int lastReceivedPacket, unsigned int ackBitField);
|
||||||
|
|
||||||
// Add primitive types like int, float, char...
|
// Add primitive types like int, float, char...
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -50,17 +50,21 @@ public:
|
|||||||
// Pops the first element as if it was a string.
|
// Pops the first element as if it was a string.
|
||||||
std::string ReadString();
|
std::string ReadString();
|
||||||
char* ReadData(int SizeOfData);
|
char* ReadData(int SizeOfData);
|
||||||
void ChangePacketID(unsigned int& packetID);
|
// No purpose any more
|
||||||
|
//void ChangePacketID(unsigned int& packetID);
|
||||||
|
void ChangeHeaderInfo(unsigned int& packetID, unsigned int lastReceivedPacket, unsigned int ackBitField);
|
||||||
int Size() { return m_Offset; };
|
int Size() { return m_Offset; };
|
||||||
char* Data() { return m_Data; };
|
char* Data() { return m_Data; };
|
||||||
unsigned int DataReadSize() { return m_ReturnDataOffset; }
|
unsigned int DataReadSize() { return m_ReturnDataOffset; }
|
||||||
unsigned int MaxSize() { return m_MaxPacketSize; }
|
unsigned int MaxSize() { return m_MaxPacketSize; }
|
||||||
|
unsigned int HeaderSize() { return m_HeaderSize; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* m_Data;
|
char* m_Data;
|
||||||
unsigned int m_ReturnDataOffset = 0;
|
unsigned int m_ReturnDataOffset = 0;
|
||||||
int m_Offset = 0;
|
int m_Offset = 0;
|
||||||
unsigned int m_MaxPacketSize = 512;
|
unsigned int m_MaxPacketSize = 512;
|
||||||
|
unsigned int m_HeaderSize = 0;
|
||||||
void resizeData();
|
void resizeData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
#ifndef PlayerDefinition_h__
|
#ifndef PlayerDefinition_h__
|
||||||
#define PlayerDefinition_h__
|
#define PlayerDefinition_h__
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "../Core/Entity.h"
|
||||||
|
|
||||||
struct PlayerDefinition {
|
struct PlayerDefinition {
|
||||||
int EntityID = -1;
|
::EntityID EntityID = EntityID_Invalid;
|
||||||
std::string Name = "";
|
std::string Name = "";
|
||||||
boost::asio::ip::udp::endpoint Endpoint;
|
boost::asio::ip::udp::endpoint Endpoint;
|
||||||
|
// The ID of the last sent packet. (Local sequence number)
|
||||||
unsigned int PacketID;
|
unsigned int PacketID;
|
||||||
|
// The ID of the last received packet. (Remote sequence number)
|
||||||
|
// This is sent as the ackNumber.
|
||||||
|
unsigned int LastPacketReceivedID;
|
||||||
|
// The bit pattern of the last 32 received packets.
|
||||||
|
unsigned int AckBitField;
|
||||||
std::clock_t StopTime;
|
std::clock_t StopTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
#include "../Network/Network.h"
|
#include "../Network/Network.h"
|
||||||
#include "Input/EInputCommand.h"
|
#include "Input/EInputCommand.h"
|
||||||
#include "Core/EPlayerDamage.h"
|
#include "Core/EPlayerDamage.h"
|
||||||
|
#include "Network/EPlayerDisconnected.h"
|
||||||
|
#include "Core/EPlayerSpawned.h"
|
||||||
|
#include "Core/EEntityDeleted.h"
|
||||||
|
#include "Core/EComponentDeleted.h"
|
||||||
|
|
||||||
class Server : public Network
|
class Server : public Network
|
||||||
{
|
{
|
||||||
@@ -29,18 +33,18 @@ private:
|
|||||||
boost::asio::ip::udp::socket m_Socket;
|
boost::asio::ip::udp::socket m_Socket;
|
||||||
|
|
||||||
// Sending messages to client logic
|
// Sending messages to client logic
|
||||||
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
|
std::map<PlayerID, PlayerDefinition> m_ConnectedPlayers;
|
||||||
std::vector<PlayerDefinition> m_ConnectedUsers;
|
|
||||||
char readBuffer[INPUTSIZE] = { 0 };
|
char readBuffer[INPUTSIZE] = { 0 };
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
// time for previouse message
|
// time for previouse message
|
||||||
std::clock_t previousePingMessage = std::clock();
|
std::clock_t previousPingMessage = std::clock();
|
||||||
std::clock_t previousSnapshotMessage = std::clock();
|
std::clock_t previousSnapshotMessage = std::clock();
|
||||||
std::clock_t timOutTimer = std::clock();
|
std::clock_t timOutTimer = std::clock();
|
||||||
// How often we send messages (milliseconds)
|
// How often we send messages (milliseconds)
|
||||||
int intervalMs = 1000;
|
int pingIntervalMs;
|
||||||
int snapshotInterval = 50;
|
int snapshotInterval;
|
||||||
int checkTimeOutInterval = 100;
|
int checkTimeOutInterval = 100;
|
||||||
|
int m_NextPlayerID = 0;
|
||||||
|
|
||||||
//Timers
|
//Timers
|
||||||
std::clock_t m_StartPingTime;
|
std::clock_t m_StartPingTime;
|
||||||
@@ -50,32 +54,41 @@ private:
|
|||||||
EventBroker* m_EventBroker;
|
EventBroker* m_EventBroker;
|
||||||
|
|
||||||
// Packet loss logic
|
// Packet loss logic
|
||||||
unsigned int m_PacketID = 0;
|
PacketID m_PacketID = 0;
|
||||||
unsigned int m_PreviousPacketID = 0;
|
PacketID m_PreviousPacketID = 0;
|
||||||
|
|
||||||
// Private member functions
|
// Private member functions
|
||||||
int receive(char* data, size_t length);
|
void addChildrenToPacket(Packet& packet, EntityID entityID);
|
||||||
void readFromClients();
|
|
||||||
void send(Packet& packet, int playerID);
|
|
||||||
void send(Packet& packet);
|
|
||||||
void broadcast(Packet& packet);
|
void broadcast(Packet& packet);
|
||||||
|
void checkForTimeOuts();
|
||||||
|
void disconnect(PlayerID playerID);
|
||||||
|
void identifyPacketLoss();
|
||||||
|
void kick(PlayerID player);
|
||||||
|
int receive(char* data);
|
||||||
|
void readFromClients();
|
||||||
|
void send(PlayerID playerID, Packet& packet);
|
||||||
|
void send(Packet& packet);
|
||||||
void sendSnapshot();
|
void sendSnapshot();
|
||||||
void sendPing();
|
void sendPing();
|
||||||
void checkForTimeOuts();
|
void parseClientPing(PlayerID playerID);
|
||||||
void disconnect(int i);
|
void parseConnect(Packet& packet, PlayerID playerID);
|
||||||
|
void parseDisconnect();
|
||||||
void parseMessageType(Packet& packet);
|
void parseMessageType(Packet& packet);
|
||||||
void parseOnInputCommand(Packet& packet);
|
void parseOnInputCommand(Packet& packet);
|
||||||
void parseOnPlayerDamage(Packet& packet);
|
void parseOnPlayerDamage(Packet& packet);
|
||||||
void parseConnect(Packet& packet);
|
void parsePing();
|
||||||
void parseDisconnect();
|
|
||||||
void parseClientPing();
|
PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
|
||||||
void parseServerPing();
|
|
||||||
void identifyPacketLoss();
|
|
||||||
void createPlayer();
|
|
||||||
int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
|
|
||||||
// Debug event
|
// Debug event
|
||||||
EventRelay<Server, Events::InputCommand> m_EInputCommand;
|
EventRelay<Server, Events::InputCommand> m_EInputCommand;
|
||||||
bool OnInputCommand(const Events::InputCommand& e);
|
bool OnInputCommand(const Events::InputCommand& e);
|
||||||
|
EventRelay<Server, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
|
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
|
||||||
|
EventRelay<Server, Events::EntityDeleted> m_EEntityDeleted;
|
||||||
|
bool OnEntityDeleted(const Events::EntityDeleted& e);
|
||||||
|
EventRelay<Server, Events::ComponentDeleted> m_EComponentDeleted;
|
||||||
|
bool OnComponentDeleted(const Events::ComponentDeleted& e);
|
||||||
|
void parsePlayerTransform(Packet& packet);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
#ifndef DebugCameraInputController_h__
|
|
||||||
#define DebugCameraInputController_h__
|
|
||||||
|
|
||||||
#include <imgui/imgui.h>
|
|
||||||
#include "../Input/FirstPersonInputController.h"
|
|
||||||
#include "../Core/EMousePress.h"
|
|
||||||
#include "../Core/EMouseRelease.h"
|
|
||||||
|
|
||||||
template <typename EventContext>
|
|
||||||
class DebugCameraInputController : public FirstPersonInputController<EventContext>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID)
|
|
||||||
: FirstPersonInputController(eventBroker, playerID)
|
|
||||||
{
|
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &DebugCameraInputController::OnMousePress);
|
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &DebugCameraInputController::OnMouseRelease);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPosition(const glm::vec3 position) { m_Position = position; }
|
|
||||||
void SetOrientation(const glm::quat orientation) { m_Orientation = orientation; }
|
|
||||||
|
|
||||||
const glm::vec3 Position() const { return m_Position; }
|
|
||||||
void SetBaseSpeed(float speed) { m_BaseSpeed = speed; }
|
|
||||||
|
|
||||||
virtual bool OnCommand(const Events::InputCommand& e) override
|
|
||||||
{
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
if (!io.WantCaptureKeyboard) {
|
|
||||||
if (e.Command == "Right") {
|
|
||||||
float value = std::max(-1.f, std::min(e.Value, 1.f));
|
|
||||||
m_Velocity.x = value;
|
|
||||||
}
|
|
||||||
if (e.Command == "Forward") {
|
|
||||||
float value = std::max(-1.f, std::min(e.Value, 1.f));
|
|
||||||
m_Velocity.z = -value;
|
|
||||||
}
|
|
||||||
if (e.Command == "Sprint") {
|
|
||||||
if (e.Value > 0.f) {
|
|
||||||
m_Speed = m_BaseSpeed * 2.f * (e.Value);
|
|
||||||
} else {
|
|
||||||
m_Speed = m_BaseSpeed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FirstPersonInputController::OnCommand(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update(double dt)
|
|
||||||
{
|
|
||||||
if (glm::length2(m_Velocity) > 0) {
|
|
||||||
m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_Speed * (float)dt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
glm::vec3 m_Position = glm::vec3(0, 0, 0);
|
|
||||||
glm::vec3 m_Velocity = glm::vec3(0, 0, 0);
|
|
||||||
float m_BaseSpeed = 2.0f;
|
|
||||||
float m_Speed = m_BaseSpeed;
|
|
||||||
EventRelay<EventContext, Events::MousePress> m_EMousePress;
|
|
||||||
bool OnMousePress(const Events::MousePress& e)
|
|
||||||
{
|
|
||||||
if (e.Button == GLFW_MOUSE_BUTTON_2) {
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
if (!io.WantCaptureMouse) {
|
|
||||||
LockMouse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
EventRelay<EventContext, Events::MouseRelease> m_EMouseRelease;
|
|
||||||
bool OnMouseRelease(const Events::MouseRelease& e)
|
|
||||||
{
|
|
||||||
if (e.Button == GLFW_MOUSE_BUTTON_2) {
|
|
||||||
UnlockMouse();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
#ifndef Model_h__
|
#ifndef Model_h__
|
||||||
#define Model_h__
|
#define Model_h__
|
||||||
|
|
||||||
#include "RawModel.h"
|
#include "Rendering/RawModelCustom.h"
|
||||||
|
//#include "Rendering/RawModelAssimp.h"
|
||||||
#include "../OpenGL.h"
|
#include "../OpenGL.h"
|
||||||
|
|
||||||
class Model : public ThreadUnsafeResource
|
class Model : public ThreadUnsafeResource
|
||||||
@@ -19,12 +20,11 @@ public:
|
|||||||
|
|
||||||
GLuint VAO;
|
GLuint VAO;
|
||||||
GLuint ElementBuffer;
|
GLuint ElementBuffer;
|
||||||
|
RawModel* m_RawModel;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RawModel* m_RawModel;
|
|
||||||
GLuint VertexBuffer;
|
GLuint VertexBuffer;
|
||||||
GLuint DiffuseVertexColorBuffer;
|
|
||||||
GLuint SpecularVertexColorBuffer;
|
|
||||||
GLuint NormalBuffer;
|
GLuint NormalBuffer;
|
||||||
GLuint TangentNormalsBuffer;
|
GLuint TangentNormalsBuffer;
|
||||||
GLuint BiTangentNormalsBuffer;
|
GLuint BiTangentNormalsBuffer;
|
||||||
|
|||||||
@@ -24,6 +24,10 @@ struct ModelJob : RenderJob
|
|||||||
DiffuseTexture = matGroup.Texture.get();
|
DiffuseTexture = matGroup.Texture.get();
|
||||||
NormalTexture = matGroup.NormalMap.get();
|
NormalTexture = matGroup.NormalMap.get();
|
||||||
SpecularTexture = matGroup.SpecularMap.get();
|
SpecularTexture = matGroup.SpecularMap.get();
|
||||||
|
IncandescenceTexture = matGroup.IncandescenceMap.get();
|
||||||
|
DiffuseColor = matGroup.DiffuseColor;
|
||||||
|
SpecularColor = matGroup.SpecularColor;
|
||||||
|
IncandescenceColor = matGroup.IncandescenceColor;
|
||||||
StartIndex = matGroup.StartIndex;
|
StartIndex = matGroup.StartIndex;
|
||||||
EndIndex = matGroup.EndIndex;
|
EndIndex = matGroup.EndIndex;
|
||||||
Matrix = matrix;
|
Matrix = matrix;
|
||||||
@@ -43,9 +47,13 @@ struct ModelJob : RenderJob
|
|||||||
const Texture* DiffuseTexture;
|
const Texture* DiffuseTexture;
|
||||||
const Texture* NormalTexture;
|
const Texture* NormalTexture;
|
||||||
const Texture* SpecularTexture;
|
const Texture* SpecularTexture;
|
||||||
|
const Texture* IncandescenceTexture;
|
||||||
float Shininess = 0.f;
|
float Shininess = 0.f;
|
||||||
glm::vec4 Color;
|
glm::vec4 Color;
|
||||||
const ::Model* Model = nullptr;
|
const ::Model* Model = nullptr;
|
||||||
|
glm::vec4 DiffuseColor;
|
||||||
|
glm::vec4 SpecularColor;
|
||||||
|
glm::vec4 IncandescenceColor;
|
||||||
unsigned int StartIndex = 0;
|
unsigned int StartIndex = 0;
|
||||||
unsigned int EndIndex = 0;
|
unsigned int EndIndex = 0;
|
||||||
World* World;
|
World* World;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#ifndef RawModel_h__
|
#ifndef RawModelAssimp_h__
|
||||||
#define RawModel_h__
|
#define RawModelAssimp_h__
|
||||||
|
|
||||||
|
#ifdef USING_ASSIMP_AS_IMPORTER
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -18,29 +20,27 @@
|
|||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "Skeleton.h"
|
#include "Skeleton.h"
|
||||||
|
|
||||||
class RawModel : public Resource
|
#define RawModel RawModelAssimp
|
||||||
|
|
||||||
|
class RawModelAssimp : public Resource
|
||||||
{
|
{
|
||||||
friend class ResourceManager;
|
friend class ResourceManager;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RawModel(std::string fileName);
|
RawModelAssimp(std::string fileName);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~RawModel();
|
~RawModelAssimp();
|
||||||
|
|
||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
glm::vec3 Position;
|
glm::vec3 Position;
|
||||||
glm::vec3 Normal;
|
glm::vec3 Normal;
|
||||||
glm::vec3 Tangent;
|
glm::vec3 Tangent;
|
||||||
glm::vec3 BiTangent;
|
glm::vec3 BiNormal;
|
||||||
glm::vec2 TextureCoords;
|
glm::vec2 TextureCoords;
|
||||||
glm::vec4 DiffuseVertexColor;
|
glm::vec4 BoneIndices;
|
||||||
glm::vec4 SpecularVertexColor;
|
glm::vec4 BoneWeights;
|
||||||
glm::vec4 BoneIndices1;
|
|
||||||
glm::vec4 BoneIndices2;
|
|
||||||
glm::vec4 BoneWeights1;
|
|
||||||
glm::vec4 BoneWeights2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MaterialGroup
|
struct MaterialGroup
|
||||||
@@ -68,8 +68,6 @@ private:
|
|||||||
std::vector<glm::ivec2> BoneIndices;
|
std::vector<glm::ivec2> BoneIndices;
|
||||||
std::vector<glm::vec2> BoneWeights;
|
std::vector<glm::vec2> BoneWeights;
|
||||||
std::vector<glm::vec3> Normals;
|
std::vector<glm::vec3> Normals;
|
||||||
std::vector<glm::vec4> DiffuseVertexColor;
|
|
||||||
std::vector<glm::vec4> SpecularVertexColor;
|
|
||||||
std::vector<glm::vec3> TangentNormals;
|
std::vector<glm::vec3> TangentNormals;
|
||||||
std::vector<glm::vec3> BiTangentNormals;
|
std::vector<glm::vec3> BiTangentNormals;
|
||||||
std::vector<glm::vec2> TextureCoords;
|
std::vector<glm::vec2> TextureCoords;
|
||||||
@@ -78,3 +76,4 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
#ifndef RawModelCustom_h__
|
||||||
|
#define RawModelCustom_h__
|
||||||
|
|
||||||
|
#ifndef USING_ASSIMP_AS_IMPORTER
|
||||||
|
|
||||||
|
#define RawModel RawModelCustom
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
|
#include "../Common.h"
|
||||||
|
#include "../GLM.h"
|
||||||
|
#include "../Core/ResourceManager.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
#include "Skeleton.h"
|
||||||
|
|
||||||
|
#include "boost\endian\buffers.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class RawModelCustom : public Resource
|
||||||
|
{
|
||||||
|
friend class ResourceManager;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
RawModelCustom(std::string fileName);
|
||||||
|
|
||||||
|
public:
|
||||||
|
~RawModelCustom();
|
||||||
|
|
||||||
|
struct Vertex
|
||||||
|
{
|
||||||
|
glm::vec3 Position;
|
||||||
|
glm::vec3 Normal;
|
||||||
|
glm::vec3 Tangent;
|
||||||
|
glm::vec3 BiNormal;
|
||||||
|
glm::vec2 TextureCoords;
|
||||||
|
glm::vec4 BoneIndices;
|
||||||
|
glm::vec4 BoneWeights;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MaterialGroup
|
||||||
|
{
|
||||||
|
float SpecularExponent;
|
||||||
|
float ReflectionFactor;
|
||||||
|
glm::vec4 DiffuseColor{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
glm::vec4 SpecularColor{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
glm::vec4 IncandescenceColor{ 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
unsigned int StartIndex;
|
||||||
|
unsigned int EndIndex;
|
||||||
|
//float Transparency;
|
||||||
|
std::string TexturePath;
|
||||||
|
std::shared_ptr<::Texture> Texture;
|
||||||
|
std::string NormalMapPath;
|
||||||
|
std::shared_ptr<::Texture> NormalMap;
|
||||||
|
std::string SpecularMapPath;
|
||||||
|
std::shared_ptr<::Texture> SpecularMap;
|
||||||
|
std::string IncandescenceMapPath;
|
||||||
|
std::shared_ptr<::Texture> IncandescenceMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<MaterialGroup> MaterialGroups;
|
||||||
|
|
||||||
|
std::vector<Vertex> m_Vertices;
|
||||||
|
std::vector<unsigned int> m_Indices;
|
||||||
|
Skeleton* m_Skeleton = nullptr;
|
||||||
|
glm::mat4 m_Matrix;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
void ReadMeshFile(std::string filePath);
|
||||||
|
void ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
|
||||||
|
void ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
|
||||||
|
void ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
|
||||||
|
void ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
|
||||||
|
|
||||||
|
void ReadMaterialFile(std::string filePath);
|
||||||
|
void ReadMaterials(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
|
||||||
|
void ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
|
||||||
|
|
||||||
|
void ReadAnimationFile(std::string filePath);
|
||||||
|
void ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
|
||||||
|
void ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
|
||||||
|
void ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips);
|
||||||
|
void ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex);
|
||||||
|
void ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfJoints, Skeleton::Animation& animation);
|
||||||
|
|
||||||
|
//void CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID);
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include "RawModelAssimp.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "PointLightJob.h"
|
#include "PointLightJob.h"
|
||||||
#include "../Core/Transform.h"
|
#include "../Core/Transform.h"
|
||||||
#include "DebugCameraInputController.h"
|
#include "../Core/EPlayerSpawned.h"
|
||||||
|
|
||||||
class RenderSystem : public ImpureSystem
|
class RenderSystem : public ImpureSystem
|
||||||
{
|
{
|
||||||
@@ -30,6 +30,7 @@ private:
|
|||||||
RenderFrame* m_RenderFrame;
|
RenderFrame* m_RenderFrame;
|
||||||
Camera* m_Camera;
|
Camera* m_Camera;
|
||||||
EntityWrapper m_CurrentCamera = EntityWrapper::Invalid;
|
EntityWrapper m_CurrentCamera = EntityWrapper::Invalid;
|
||||||
|
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
|
||||||
|
|
||||||
EventRelay<RenderSystem, Events::SetCamera> m_ESetCamera;
|
EventRelay<RenderSystem, Events::SetCamera> m_ESetCamera;
|
||||||
bool OnSetCamera(Events::SetCamera &event);
|
bool OnSetCamera(Events::SetCamera &event);
|
||||||
@@ -41,6 +42,9 @@ private:
|
|||||||
|
|
||||||
void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs);
|
void fillModels(std::list<std::shared_ptr<RenderJob>>& jobs);
|
||||||
void fillLight(std::list<std::shared_ptr<RenderJob>>& jobs);
|
void fillLight(std::list<std::shared_ptr<RenderJob>>& jobs);
|
||||||
|
|
||||||
|
EventRelay<RenderSystem, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
|
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "../GLM.h"
|
#include "../GLM.h"
|
||||||
|
#include <glm/gtx/matrix_decompose.hpp>
|
||||||
|
|
||||||
//struct Bone
|
//struct Bone
|
||||||
//{
|
//{
|
||||||
@@ -38,9 +39,9 @@ public:
|
|||||||
, OffsetMatrix(offsetMatrix)
|
, OffsetMatrix(offsetMatrix)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
int ID;
|
|
||||||
std::string Name;
|
std::string Name;
|
||||||
glm::mat4 OffsetMatrix;
|
glm::mat4 OffsetMatrix;
|
||||||
|
int ID;
|
||||||
|
|
||||||
Bone* Parent;
|
Bone* Parent;
|
||||||
std::vector<Bone*> Children;
|
std::vector<Bone*> Children;
|
||||||
|
|||||||
@@ -10,11 +10,12 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
#include "Core/EventBroker.h"
|
#include "Core/EventBroker.h"
|
||||||
|
#include "Core/ResourceManager.h"
|
||||||
|
#include "Core/ConfigFile.h"
|
||||||
|
#include "Core/EPlayerSpawned.h"
|
||||||
|
|
||||||
#include "Network/EInterpolate.h"
|
#include "Network/EInterpolate.h"
|
||||||
|
|
||||||
#define SNAPSHOTINTERVAL 0.05f
|
|
||||||
|
|
||||||
class InterpolationSystem : public PureSystem
|
class InterpolationSystem : public PureSystem
|
||||||
{
|
{
|
||||||
struct Transform
|
struct Transform
|
||||||
@@ -25,29 +26,28 @@ class InterpolationSystem : public PureSystem
|
|||||||
double interpolationTime;
|
double interpolationTime;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
InterpolationSystem(World* world, EventBroker* eventBroker)
|
InterpolationSystem(World* world, EventBroker* eventBroker);
|
||||||
: System(world, eventBroker)
|
|
||||||
, PureSystem("Transform")
|
|
||||||
{
|
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate);
|
|
||||||
}
|
|
||||||
~InterpolationSystem() { }
|
~InterpolationSystem() { }
|
||||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) override;
|
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) override;
|
||||||
private:
|
private:
|
||||||
std::unordered_map<EntityID, Transform> m_NextTransform;
|
std::unordered_map<EntityID, Transform> m_NextTransform;
|
||||||
std::unordered_map<EntityID, Transform> m_LastReceivedTransform;
|
std::unordered_map<EntityID, Transform> m_LastReceivedTransform;
|
||||||
|
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
|
||||||
|
|
||||||
//glm::vec3 vectorInterpolation(glm::vec3 prev, glm::vec3 next, double currentTime);
|
//glm::vec3 vectorInterpolation(glm::vec3 prev, glm::vec3 next, double currentTime);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T vectorInterpolation(T prev, T next, double currentTime)
|
T vectorInterpolation(T prev, T next, double currentTime)
|
||||||
{
|
{
|
||||||
T difference = next - prev;
|
T difference = next - prev;
|
||||||
T vector = (difference / SNAPSHOTINTERVAL) * static_cast<float>(currentTime);
|
T vector = (difference / m_SnapshotInterval) * static_cast<float>(currentTime);
|
||||||
return vector;
|
return vector;
|
||||||
}
|
}
|
||||||
|
float m_SnapshotInterval;
|
||||||
|
|
||||||
EventRelay<InterpolationSystem, Events::Interpolate> m_EInterpolate;
|
EventRelay<InterpolationSystem, Events::Interpolate> m_EInterpolate;
|
||||||
bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e);
|
bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e);
|
||||||
|
EventRelay<InterpolationSystem, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
|
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "GLM.h"
|
#include "GLM.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
|
#include "Core/EPlayerSpawned.h"
|
||||||
|
#include "Input/FirstPersonInputController.h"
|
||||||
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
class PlayerMovementSystem : public PureSystem
|
class PlayerMovementSystem : public ImpureSystem, PureSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PlayerMovementSystem(World* world, EventBroker* eventBroker)
|
PlayerMovementSystem(World* world, EventBroker* eventBroker);
|
||||||
: System(world, eventBroker)
|
~PlayerMovementSystem();
|
||||||
, PureSystem("Player")
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
virtual void Update(double dt) override;
|
||||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt);
|
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// State
|
||||||
|
std::unordered_map<EntityWrapper, FirstPersonInputController<PlayerMovementSystem>*> m_PlayerInputControllers;
|
||||||
|
|
||||||
|
EventRelay<PlayerMovementSystem, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
|
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
||||||
};
|
};
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
#include "Input/EInputCommand.h"
|
#include "Input/EInputCommand.h"
|
||||||
#include "Systems/SpawnerSystem.h"
|
#include "Systems/SpawnerSystem.h"
|
||||||
#include "Events/ESpawnerSpawn.h"
|
#include "Events/ESpawnerSpawn.h"
|
||||||
|
#include "Core/EPlayerSpawned.h"
|
||||||
|
#include "Rendering/ESetCamera.h"
|
||||||
|
#include "Core/ConfigFile.h"
|
||||||
|
|
||||||
class PlayerSpawnSystem : public ImpureSystem
|
class PlayerSpawnSystem : public ImpureSystem
|
||||||
{
|
{
|
||||||
@@ -11,8 +14,18 @@ public:
|
|||||||
virtual void Update(double dt) override;
|
virtual void Update(double dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct SpawnRequest
|
||||||
|
{
|
||||||
|
int PlayerID;
|
||||||
|
ComponentInfo::EnumType Team;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool m_NetworkEnabled = false;
|
||||||
|
std::vector<SpawnRequest> m_SpawnRequests;
|
||||||
|
std::map<int, EntityWrapper> m_PlayerEntities;
|
||||||
|
|
||||||
EventRelay<PlayerSpawnSystem, Events::InputCommand> m_OnInputCommand;
|
EventRelay<PlayerSpawnSystem, Events::InputCommand> m_OnInputCommand;
|
||||||
bool OnInputCommand(const Events::InputCommand& e);
|
bool OnInputCommand(const Events::InputCommand& e);
|
||||||
|
EventRelay<PlayerSpawnSystem, Events::PlayerSpawned> m_OnPlayerSpawnerd;
|
||||||
std::vector<int> m_SpawnRequests;
|
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
||||||
};
|
};
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
#include "Core/EPlayerDamage.h"
|
#include "Core/EPlayerDamage.h"
|
||||||
#include "Core/EShoot.h"
|
#include "Core/EShoot.h"
|
||||||
|
#include "Core/EPlayerSpawned.h"
|
||||||
#include "Input/EInputCommand.h"
|
#include "Input/EInputCommand.h"
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
@@ -23,16 +24,18 @@ public:
|
|||||||
virtual void Update(double dt) override;
|
virtual void Update(double dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//methods which will take care of specific events
|
|
||||||
EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
|
|
||||||
bool WeaponSystem::OnShoot(const Events::Shoot& e);
|
|
||||||
|
|
||||||
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
|
|
||||||
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e);
|
|
||||||
|
|
||||||
IRenderer* m_Renderer;
|
IRenderer* m_Renderer;
|
||||||
|
|
||||||
std::vector<std::tuple<EntityID, glm::vec2>> m_EShootVector;
|
// State
|
||||||
|
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
|
||||||
|
|
||||||
|
// Events
|
||||||
|
EventRelay<WeaponSystem, Events::PlayerSpawned> m_EPlayerSpawned;
|
||||||
|
bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e);
|
||||||
|
EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
|
||||||
|
bool WeaponSystem::OnShoot(const Events::Shoot& e);
|
||||||
|
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
|
||||||
|
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
[Debug]
|
[Debug]
|
||||||
LogLevel=1
|
LogLevel=1
|
||||||
LoadMap=
|
LoadMap=
|
||||||
EditorEnabled=false
|
|
||||||
; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
|
; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
|
||||||
; if false -> Use pool allocation.
|
; if false -> Use pool allocation.
|
||||||
DisableMemoryPool=false
|
DisableMemoryPool=false
|
||||||
|
|
||||||
|
[Editor]
|
||||||
|
CameraSpeed=3
|
||||||
|
|
||||||
[Video]
|
[Video]
|
||||||
Fullscreen=false
|
Fullscreen=false
|
||||||
VSYNC=false
|
VSYNC=false
|
||||||
@@ -19,6 +21,11 @@ IsServer=false
|
|||||||
Name=Bob
|
Name=Bob
|
||||||
Address=127.0.0.1
|
Address=127.0.0.1
|
||||||
Port=13
|
Port=13
|
||||||
|
MaxConnections=8
|
||||||
|
SnapshotInterval=0.05
|
||||||
|
SendInputIntervalMs=33
|
||||||
|
PingIntervalMs= 1000
|
||||||
|
TimeoutMs=15000
|
||||||
|
|
||||||
[Multithreading]
|
[Multithreading]
|
||||||
ResourceLoading=true
|
ResourceLoading=true
|
||||||
|
|||||||
@@ -21,4 +21,5 @@ F1=ToggleEditor
|
|||||||
X=EditorToggleTransformSpace
|
X=EditorToggleTransformSpace
|
||||||
C=ConnectToServer
|
C=ConnectToServer
|
||||||
N=SwitchToServer
|
N=SwitchToServer
|
||||||
M=SwitchToClient
|
M=SwitchToClient
|
||||||
|
P=SwitchToPlayer
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Player.xsd">
|
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Player.xsd">
|
||||||
<Velocity X="0" Y="0" Z="0"/>
|
<MovementSpeed>3</MovementSpeed>
|
||||||
<Forward>false</Forward>
|
<CrouchSpeed>1.5</CrouchSpeed>
|
||||||
<Left>false</Left>
|
|
||||||
<Back>false</Back>
|
|
||||||
<Right>false</Right>
|
|
||||||
</Player>
|
</Player>
|
||||||
@@ -9,11 +9,8 @@
|
|||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:all>
|
<xs:all>
|
||||||
<xs:element name="Velocity" type="t:Vector" minOccurs="0"/>
|
<xs:element name="MovementSpeed" type="t:float" minOccurs="0"/>
|
||||||
<xs:element name="Forward" type="t:bool" minOccurs="0"/>
|
<xs:element name="CrouchSpeed" type="t:float" minOccurs="0"/>
|
||||||
<xs:element name="Left" type="t:bool" minOccurs="0"/>
|
|
||||||
<xs:element name="Back" type="t:bool" minOccurs="0"/>
|
|
||||||
<xs:element name="Right" type="t:bool" minOccurs="0"/>
|
|
||||||
</xs:all>
|
</xs:all>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
|||||||
@@ -0,0 +1,273 @@
|
|||||||
|
<?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:Camera/>
|
||||||
|
<c:Listener/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="4.52910185" Y="5.50171423" Z="7.69566345"/>
|
||||||
|
<Orientation X="-0.453785568" Y="0.436270237" Z="-1.03594937e-06"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>models/dummyscene.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="-0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>models/animtest.</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.0966923237" Y="1.2939688" Z="0.399702221"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>models/animTest.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="1.31816244" Z="1.1888907"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>models/animTest.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.708824873" Y="1.30000007" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>models/animTest.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="1.36948848" Y="1.20000005" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:DirectionalLight>
|
||||||
|
<Intensity>0.13000047206878662</Intensity>
|
||||||
|
</c:DirectionalLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="2.77622533" Z="0"/>
|
||||||
|
<Orientation X="0" Y="1.30900002" Z="1.73600006"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0.30000001192092896</Speed>
|
||||||
|
<Axis X="0" Y="5" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Orientation X="117.03714" Y="3023.50244" Z="3.03297734"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="1" G="1" R="0"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="1" Z="1.29999995"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="0" G="1" R="0"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
<Intensity>0.80000001192092896</Intensity>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="1" Z="-1.29999995"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="1" G="0" R="0.478431374"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-1.30000007" Y="1" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="0" G="1" R="1"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="1.29999995" Y="1" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:RaptorCopter>
|
||||||
|
<Speed>0.50999981164932251</Speed>
|
||||||
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
|
</c:RaptorCopter>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="-0.100000001" Z="0"/>
|
||||||
|
<Orientation X="0" Y="191.457993" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="0.301960796" G="0.0901960805" R="0.247058824"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
<Intensity>5</Intensity>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="3" Z="5"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="0.960784316" G="1" R="0"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="3" Z="-7.66608238"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="0.00784313772" G="1" R="1"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-3.47176075" Y="3" Z="-8.09415054"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="0" G="0" R="1"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-9.50536728" Y="2" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="1" G="0" R="1"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="3" Z="4.40877533"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="0.431372553" G="0.0745098069" R="1"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="5.83008432" Y="3" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="0" G="0.623529434" R="0.929411769"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="3.72500014" Y="3" Z="-4.26100016"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="3" Z="-7.50000048"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Color A="1" B="0.192156866" G="1" R="0"/>
|
||||||
|
<Radius>5</Radius>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-5.90153885" Y="3" Z="-5.40681458"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
<Resource>../assets/Models/DummyScene.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<HomePointForTeam>3</HomePointForTeam>
|
<HomePointForTeam>3</HomePointForTeam>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.200000003" R="0"/>
|
<Color A="1" B="1" G="0.200000003" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<CapturePointNumber>1</CapturePointNumber>
|
<CapturePointNumber>1</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="1" R="1"/>
|
<Color A="1" B="0" G="1" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
<CapturePointNumber>2</CapturePointNumber>
|
<CapturePointNumber>2</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="1" R="0"/>
|
<Color A="1" B="1" G="1" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
<CapturePointNumber>3</CapturePointNumber>
|
<CapturePointNumber>3</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -120,7 +120,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -138,7 +138,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
<Resource>../assets/Models/DummyScene.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
<CaptureTimer>6.9158446328696002</CaptureTimer>
|
<CaptureTimer>6.9158446328696002</CaptureTimer>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="1" R="1"/>
|
<Color A="1" B="0" G="1" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
<CapturePointNumber>1</CapturePointNumber>
|
<CapturePointNumber>1</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="1" R="0"/>
|
<Color A="1" B="1" G="1" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
<CapturePointNumber>2</CapturePointNumber>
|
<CapturePointNumber>2</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
<CapturePointNumber>3</CapturePointNumber>
|
<CapturePointNumber>3</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
<Resource>../assets/Models/DummyScene.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<HomePointForTeam>3</HomePointForTeam>
|
<HomePointForTeam>3</HomePointForTeam>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.200000003" R="0"/>
|
<Color A="1" B="1" G="0.200000003" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<CapturePointNumber>1</CapturePointNumber>
|
<CapturePointNumber>1</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="1" R="0"/>
|
<Color A="1" B="1" G="1" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team/>
|
<c:Team/>
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
<CapturePointNumber>2</CapturePointNumber>
|
<CapturePointNumber>2</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="1" R="1"/>
|
<Color A="1" B="0" G="1" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team/>
|
<c:Team/>
|
||||||
@@ -98,7 +98,7 @@
|
|||||||
<CapturePointNumber>3</CapturePointNumber>
|
<CapturePointNumber>3</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -116,7 +116,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
<Resource>../assets/Models/DummyScene.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<HomePointForTeam>3</HomePointForTeam>
|
<HomePointForTeam>3</HomePointForTeam>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.200000003" R="0"/>
|
<Color A="1" B="1" G="0.200000003" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<CapturePointNumber>1</CapturePointNumber>
|
<CapturePointNumber>1</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="1" R="1"/>
|
<Color A="1" B="0" G="1" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
<CapturePointNumber>2</CapturePointNumber>
|
<CapturePointNumber>2</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="1" R="0"/>
|
<Color A="1" B="1" G="1" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
<CapturePointNumber>3</CapturePointNumber>
|
<CapturePointNumber>3</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
<CapturePointNumber>4</CapturePointNumber>
|
<CapturePointNumber>4</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -176,7 +176,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -194,7 +194,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
<Resource>../assets/Models/DummyScene.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<HomePointForTeam>3</HomePointForTeam>
|
<HomePointForTeam>3</HomePointForTeam>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.200000003" R="0"/>
|
<Color A="1" B="1" G="0.200000003" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<CapturePointNumber>1</CapturePointNumber>
|
<CapturePointNumber>1</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="1" R="0"/>
|
<Color A="1" B="1" G="1" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team/>
|
<c:Team/>
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
<CapturePointNumber>2</CapturePointNumber>
|
<CapturePointNumber>2</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team/>
|
<c:Team/>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
<CapturePointNumber>3</CapturePointNumber>
|
<CapturePointNumber>3</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="1" R="1"/>
|
<Color A="1" B="0" G="1" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team/>
|
<c:Team/>
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
<CapturePointNumber>4</CapturePointNumber>
|
<CapturePointNumber>4</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -169,7 +169,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -187,7 +187,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
<Color A="1" B="1" G="0.196078435" R="0.196078435"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?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:AABB/>
|
||||||
|
<c:Collidable/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children/>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<Static>false</Static>
|
<Static>false</Static>
|
||||||
</c:Collidable>
|
</c:Collidable>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0" G="1" R="0"/>
|
<Color A="1" B="0" G="1" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<Orientation X="0" Y="0" Z="0"/>
|
<Orientation X="0" Y="0" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/DummyScene.obj</Resource>
|
<Resource>Models/DummyScene.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<Scale X="1" Y="1" Z="1"/>
|
<Scale X="1" Y="1" Z="1"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitSphere.obj</Resource>
|
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
</Entity>
|
</Entity>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<Scale X="2" Y="2" Z="2"/>
|
<Scale X="2" Y="2" Z="2"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/RotationWidgetX.obj</Resource>
|
<Resource>Models/RotationWidgetX.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Trigger>
|
<c:Trigger>
|
||||||
</c:Trigger>
|
</c:Trigger>
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
<Position X="2.5"/>
|
<Position X="2.5"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:AABB>
|
<c:AABB>
|
||||||
</c:AABB>
|
</c:AABB>
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
<Orientation X="0.0" Y="0" Z="1.0"/>
|
<Orientation X="0.0" Y="0" Z="1.0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitRaptor.obj</Resource>
|
<Resource>Models/Core/UnitRaptor.mesh</Resource>
|
||||||
<Color R="1" G="0.4" B="0.8"/>
|
<Color R="1" G="0.4" B="0.8"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
<Orientation X="0" Y="0" Z="0"/>
|
<Orientation X="0" Y="0" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color R="1" G="0.4" B="0.8"/>
|
<Color R="1" G="0.4" B="0.8"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
<Orientation X="0" Y="1.57" Z="0"/>
|
<Orientation X="0" Y="1.57" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color R="1" G="0.4" B="0.8"/>
|
<Color R="1" G="0.4" B="0.8"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Scale X="100" Y="1" Z="100"/>
|
<Scale X="100" Y="1" Z="100"/>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:DirectionalLight/>
|
<c:DirectionalLight/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/DirectionalLightWidget.obj</Resource>
|
<Resource>Models/DirectionalLightWidget.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="2.1529963" Y="6.59221172" Z="0.169116676"/>
|
<Position X="2.1529963" Y="6.59221172" Z="0.169116676"/>
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Assault.obj</Resource>
|
<Resource>Models/Assault.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-2.00568962" Y="0.527161121" Z="0"/>
|
<Position X="-2.00568962" Y="0.527161121" Z="0"/>
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitSphere.obj</Resource>
|
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="3.70000029" Z="0"/>
|
<Position X="0" Y="3.70000029" Z="0"/>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
<Axis X="1" Y="0" Z="0"/>
|
<Axis X="1" Y="0" Z="0"/>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/RotationWidgetX.obj</Resource>
|
<Resource>Models/RotationWidgetX.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
<Axis X="0" Y="1" Z="0"/>
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/RotationWidgetY.obj</Resource>
|
<Resource>Models/RotationWidgetY.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
<Axis X="0" Y="0" Z="1"/>
|
<Axis X="0" Y="0" Z="1"/>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/RotationWidgetZ.obj</Resource>
|
<Resource>Models/RotationWidgetZ.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/ScaleWidgetOrigin.obj</Resource>
|
<Resource>Models/ScaleWidgetOrigin.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
<c:UniformScale>
|
<c:UniformScale>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
</Type>
|
</Type>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/ScaleWidgetX.obj</Resource>
|
<Resource>Models/ScaleWidgetX.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
</Type>
|
</Type>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/ScaleWidgetY.obj</Resource>
|
<Resource>Models/ScaleWidgetY.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
</Type>
|
</Type>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/ScaleWidgetZ.obj</Resource>
|
<Resource>Models/ScaleWidgetZ.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/TranslationWidgetOrigin.obj</Resource>
|
<Resource>Models/TranslationWidgetOrigin.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
<c:UniformScale>
|
<c:UniformScale>
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<Axis X="1" Y="0" Z="0"/>
|
<Axis X="1" Y="0" Z="0"/>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/TranslationWidgetX.obj</Resource>
|
<Resource>Models/TranslationWidgetX.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<Axis X="0" Y="1" Z="0"/>
|
<Axis X="0" Y="1" Z="0"/>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/TranslationWidgetY.obj</Resource>
|
<Resource>Models/TranslationWidgetY.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
<Axis X="0" Y="0" Z="1"/>
|
<Axis X="0" Y="0" Z="1"/>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/TranslationWidgetZ.obj</Resource>
|
<Resource>Models/TranslationWidgetZ.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
<Axis X="0" Y="1" Z="1"/>
|
<Axis X="0" Y="1" Z="1"/>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/WidgetPlaneX.obj</Resource>
|
<Resource>Models/WidgetPlaneX.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
<Axis X="1" Y="0" Z="1"/>
|
<Axis X="1" Y="0" Z="1"/>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/WidgetPlaneY.obj</Resource>
|
<Resource>Models/WidgetPlaneY.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
<Axis X="1" Y="1" Z="0"/>
|
<Axis X="1" Y="1" Z="0"/>
|
||||||
</c:EditorWidget>
|
</c:EditorWidget>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/WidgetPlaneZ.obj</Resource>
|
<Resource>Models/WidgetPlaneZ.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
|
|||||||
@@ -5,6 +5,16 @@
|
|||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
<Children/>
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource></Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
</Entity>
|
</Entity>
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
<?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 name="Scenemesh">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models\MapVersion1.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="DirectionalLight">
|
||||||
|
<Components>
|
||||||
|
<c:DirectionalLight>
|
||||||
|
<Intensity>2</Intensity>
|
||||||
|
</c:DirectionalLight>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/DirectionalLightWidget.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="61.9050903" Z="0"/>
|
||||||
|
<Scale X="50" Y="50" Z="50"/>
|
||||||
|
<Orientation X="4.42700005" Y="0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="PointLight">
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Radius>8</Radius>
|
||||||
|
<Intensity>2.7999999523162842</Intensity>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.370978802" Y="1.88588905" Z="-0.55370003"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="PointLight">
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Radius>8</Radius>
|
||||||
|
<Intensity>2.7999999523162842</Intensity>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="38.0347443" Y="1.88588905" Z="62.7340622"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:AABB/>
|
||||||
|
<c:Collidable/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.904668212" Y="0" Z="8.48177528"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:AABB/>
|
||||||
|
<c:Collidable/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-4.61666441" Y="0" Z="-8.51156044"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:AABB/>
|
||||||
|
<c:Collidable/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-7.56803513" Y="-0.0658408776" Z="0.59418112"/>
|
||||||
|
<Scale X="1.20000005" Y="0.900000036" Z="1.30000007"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:AABB/>
|
||||||
|
<c:Collidable/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="10.460474" Y="0" Z="-3.92580295"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:AABB/>
|
||||||
|
<c:Collidable/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="1.09146011" Y="-0.315138876" Z="-0.333906144"/>
|
||||||
|
<Scale X="150" Y="1" Z="180"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?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:Camera/>
|
||||||
|
<c:Listener/>
|
||||||
|
<c:Transform>
|
||||||
|
<Orientation X="0" Y="-0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>models/animTest.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform/>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -6,66 +6,178 @@
|
|||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
<Children>
|
<Children>
|
||||||
<Entity>
|
<Entity name="Ground">
|
||||||
<Components>
|
<Components>
|
||||||
<c:Camera/>
|
<c:AABB/>
|
||||||
|
<c:Collidable/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
<Color A="1" B="0.513725519" G="0" R="1"/>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="7" Y="-0.727000058" Z="-1.22800004"/>
|
||||||
|
<Scale X="50" Y="1.45100009" Z="50"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="RedSpawn">
|
||||||
|
<Components>
|
||||||
|
<c:PlayerSpawn/>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/Player.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Team>
|
||||||
|
<Team>
|
||||||
|
<Red/>
|
||||||
|
</Team>
|
||||||
|
</c:Team>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.300000012" Y="0.0270000007" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:SpawnPoint/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Assault.mesh</Resource>
|
||||||
|
<Color A="1" B="0" G="0" R="1"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.800000012" Y="0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:SpawnPoint/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Assault.mesh</Resource>
|
||||||
|
<Color A="1" B="0.0117647061" G="0" R="1"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.600000024" Y="0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="DirectionalLight">
|
||||||
|
<Components>
|
||||||
|
<c:DirectionalLight/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/DirectionalLightWidget.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-6.00145912" Y="1.42697716" Z="3.04144025"/>
|
||||||
|
<Orientation X="5.69400024" Y="841.179565" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="ObstacleCourse">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Test/ObstacleCourse.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity>
|
<Entity name="ObstacleCoursePlayerBox">
|
||||||
<Components>
|
<Components>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0.513725519" G="0" R="1"/>
|
<Visible>false</Visible>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="2" Z="0"/>
|
<Position X="6.32800007" Y="0.807000041" Z="-2.2750001"/>
|
||||||
<Scale X="5" Y="1" Z="5"/>
|
<Scale X="1" Y="1.60000002" Z="1"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
<Entity name="Player">
|
<Entity name="ObstacleCourse1uHigh">
|
||||||
<Components>
|
|
||||||
<c:AABB>
|
|
||||||
<Origin X="0" Y="0.773000062" Z="0"/>
|
|
||||||
<Size X="1" Y="1.60000002" Z="1"/>
|
|
||||||
</c:AABB>
|
|
||||||
<c:Collidable/>
|
|
||||||
<c:Physics/>
|
|
||||||
<c:Model>
|
|
||||||
<Resource>Models/Assault.obj</Resource>
|
|
||||||
<Color A="1" B="1" G="0" R="0"/>
|
|
||||||
</c:Model>
|
|
||||||
<c:Player/>
|
|
||||||
<c:Transform>
|
|
||||||
<Position X="0" Y="2.52699995" Z="0.0542778969"/>
|
|
||||||
</c:Transform>
|
|
||||||
</Components>
|
|
||||||
<Children/>
|
|
||||||
</Entity>
|
|
||||||
<Entity>
|
|
||||||
<Components>
|
<Components>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Physics>
|
|
||||||
<Velocity X="0" Y="-0.0934068039" Z="0"/>
|
|
||||||
</c:Physics>
|
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0" G="1" R="1"/>
|
<Visible>false</Visible>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="4.15580511" Z="0"/>
|
<Position X="9.11900043" Y="0.5" Z="-2.10900021"/>
|
||||||
<Scale X="0.704558551" Y="0.115156889" Z="1"/>
|
<Scale X="1" Y="1" Z="8.1960001"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
<Children/>
|
<Children/>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
<Entity name="ObstacleCourseWhoTheFuckKnows">
|
||||||
|
<Components>
|
||||||
|
<c:AABB/>
|
||||||
|
<c:Collidable/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="13.2370005" Y="1.28600001" Z="-1.71700013"/>
|
||||||
|
<Scale X="2.58000016" Y="2.58300018" Z="21.1860008"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="BlueSpawn">
|
||||||
|
<Components>
|
||||||
|
<c:PlayerSpawn/>
|
||||||
|
<c:Spawner>
|
||||||
|
<EntityFile>Schema/Entities/Player.xml</EntityFile>
|
||||||
|
</c:Spawner>
|
||||||
|
<c:Team>
|
||||||
|
<Team>
|
||||||
|
<Blue/>
|
||||||
|
</Team>
|
||||||
|
</c:Team>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.300000012" Y="0.0270000007" Z="6.67400026"/>
|
||||||
|
<Orientation X="0" Y="3.20700026" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:SpawnPoint/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Assault.mesh</Resource>
|
||||||
|
<Color A="1" B="1" G="0.254901975" R="0"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.800000012" Y="0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity>
|
||||||
|
<Components>
|
||||||
|
<c:SpawnPoint/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Assault.mesh</Resource>
|
||||||
|
<Color A="1" B="1" G="0.254901975" R="0"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.600000024" Y="0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
|
|
||||||
</Entity>
|
</Entity>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0" R="0"/>
|
<Color A="1" B="1" G="0" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<Static>false</Static>
|
<Static>false</Static>
|
||||||
</c:Collidable>
|
</c:Collidable>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0" R="1"/>
|
<Color A="1" B="0" G="0" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
<Static>false</Static>
|
<Static>false</Static>
|
||||||
</c:Collidable>
|
</c:Collidable>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0" G="1" R="0"/>
|
<Color A="1" B="0" G="1" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
|
|||||||
@@ -2,17 +2,118 @@
|
|||||||
<Entity name="Player" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
<Entity name="Player" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
<Components>
|
<Components>
|
||||||
<c:AABB/>
|
<c:AABB>
|
||||||
<c:Physics/>
|
<Origin X="0" Y="0.772000015" Z="0"/>
|
||||||
|
<Size X="1" Y="1.60000002" Z="1"/>
|
||||||
|
</c:AABB>
|
||||||
<c:Collidable/>
|
<c:Collidable/>
|
||||||
<c:Model>
|
<c:Model/>
|
||||||
<Resource>Models/Core/UnitSphere.obj</Resource>
|
<c:Physics/>
|
||||||
<Color A="1" B="1" G="0" R="0"/>
|
<c:Player>
|
||||||
</c:Model>
|
<MovementSpeed>5</MovementSpeed>
|
||||||
<c:Player/>
|
</c:Player>
|
||||||
<c:Transform/>
|
<c:Team>
|
||||||
|
<Team>
|
||||||
|
<Red/>
|
||||||
|
</Team>
|
||||||
|
</c:Team>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.246963501" Y="0.0265000071" Z="3.01600003"/>
|
||||||
|
<Orientation X="0" Y="2.14675093" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
</Components>
|
</Components>
|
||||||
|
|
||||||
<Children/>
|
<Children>
|
||||||
|
<Entity name="Camera">
|
||||||
|
<Components>
|
||||||
|
<c:Camera/>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="1.37700009" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children>
|
||||||
|
<Entity name="PlayerName">
|
||||||
|
<Components>
|
||||||
|
<c:Text>
|
||||||
|
<Resource>Fonts/DroidSans.ttf,100</Resource>
|
||||||
|
<Color A="1" B="0" G="1" R="0"/>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Text>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.247910097" Z="-0.447844714"/>
|
||||||
|
<Scale X="0.100000001" Y="0.113000005" Z="0.5"/>
|
||||||
|
<Orientation X="0" Y="3.14199996" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="CameraModel">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Camera.mesh</Resource>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.0331346765" Z="-0.0792061687"/>
|
||||||
|
<Scale X="1.30000007" Y="1.50000012" Z="1"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="ThirdPersonCamera">
|
||||||
|
<Components>
|
||||||
|
<c:Camera/>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Camera.mesh</Resource>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="-0.284000009" Y="1.83800006" Z="1.18900001"/>
|
||||||
|
<Orientation X="5.95600033" Y="0" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="PlayerModel">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/AssaultHeadless.mesh</Resource>
|
||||||
|
<Color A="1" B="0" G="0" R="1"/>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Orientation X="0" Y="3.14159274" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AABBStanding">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
<Color A="0.427450985" B="1" G="1" R="1"/>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.772000015" Z="0"/>
|
||||||
|
<Scale X="1" Y="1.60000002" Z="1"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
<Entity name="AABBCrouching">
|
||||||
|
<Components>
|
||||||
|
<c:Model>
|
||||||
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
|
<Color A="0.745098054" B="1" G="0" R="1"/>
|
||||||
|
<Visible>false</Visible>
|
||||||
|
</c:Model>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0" Y="0.772000015" Z="0"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
<Children/>
|
||||||
|
</Entity>
|
||||||
|
</Children>
|
||||||
|
|
||||||
</Entity>
|
</Entity>
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||||
|
<Entity name="PointLight" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
|
||||||
|
|
||||||
|
<Components>
|
||||||
|
<c:PointLight>
|
||||||
|
<Radius>8</Radius>
|
||||||
|
<Intensity>2.7999999523162842</Intensity>
|
||||||
|
</c:PointLight>
|
||||||
|
<c:Transform>
|
||||||
|
<Position X="0.370978802" Y="1.88588905" Z="-0.55370003"/>
|
||||||
|
</c:Transform>
|
||||||
|
</Components>
|
||||||
|
|
||||||
|
<Children/>
|
||||||
|
|
||||||
|
</Entity>
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
<Orientation X="0.0" Y="0" Z="0.0"/>
|
<Orientation X="0.0" Y="0" Z="0.0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitRaptor.obj</Resource>
|
<Resource>Models/Core/UnitRaptor.mesh</Resource>
|
||||||
<Color R="1" G="0.4" B="0.8"/>
|
<Color R="1" G="0.4" B="0.8"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<Scale X="0.1" Y="0.4" Z="0.1"/>
|
<Scale X="0.1" Y="0.4" Z="0.1"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCylinder.obj</Resource>
|
<Resource>Models/Core/UnitCylinder.mesh</Resource>
|
||||||
<Color R="1" G="0.4" B="0.8"/>
|
<Color R="1" G="0.4" B="0.8"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
<Orientation X="0" Y="0" Z="0"/>
|
<Orientation X="0" Y="0" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color R="1" G="0.4" B="0.8"/>
|
<Color R="1" G="0.4" B="0.8"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
<Orientation X="0" Y="1.57" Z="0"/>
|
<Orientation X="0" Y="1.57" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color R="1" G="0.4" B="0.8"/>
|
<Color R="1" G="0.4" B="0.8"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<Name>ActionCamera</Name>
|
<Name>ActionCamera</Name>
|
||||||
</c:Camera>
|
</c:Camera>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Camera.obj</Resource>
|
<Resource>Models/Camera.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-0.504807115" Y="6.00582743" Z="9.68687439"/>
|
<Position X="-0.504807115" Y="6.00582743" Z="9.68687439"/>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitPlane.obj</Resource>
|
<Resource>Models/Core/UnitPlane.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="-1" Z="0.600000024"/>
|
<Position X="0" Y="-1" Z="0.600000024"/>
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Assault.obj</Resource>
|
<Resource>Models/Assault.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-2.5" Y="0" Z="1"/>
|
<Position X="-2.5" Y="0" Z="1"/>
|
||||||
@@ -190,7 +190,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Assault.obj</Resource>
|
<Resource>Models/Assault.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="2.5" Y="0" Z="1"/>
|
<Position X="2.5" Y="0" Z="1"/>
|
||||||
@@ -205,7 +205,7 @@
|
|||||||
</c:Camera>
|
</c:Camera>
|
||||||
<c:Listener/>
|
<c:Listener/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Camera.obj</Resource>
|
<Resource>Models/Camera.mesh</Resource>
|
||||||
<Visible>false</Visible>
|
<Visible>false</Visible>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
@@ -237,7 +237,7 @@
|
|||||||
<Intensity>0.80000001192092896</Intensity>
|
<Intensity>0.80000001192092896</Intensity>
|
||||||
</c:DirectionalLight>
|
</c:DirectionalLight>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/DirectionalLightWidget.obj</Resource>
|
<Resource>Models/DirectionalLightWidget.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-0.0013256073" Y="1.89540339" Z="6.53467274"/>
|
<Position X="-0.0013256073" Y="1.89540339" Z="6.53467274"/>
|
||||||
@@ -249,7 +249,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="-5.4082036" Y="0" Z="-1.84950542"/>
|
<Position X="-5.4082036" Y="0" Z="-1.84950542"/>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<Entity>
|
<Entity>
|
||||||
<Components>
|
<Components>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/DummyScene.obj</Resource>
|
<Resource>../assets/Models/DummyScene.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
</Components>
|
</Components>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<HomePointForTeam>3</HomePointForTeam>
|
<HomePointForTeam>3</HomePointForTeam>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.200000003" R="0"/>
|
<Color A="1" B="1" G="0.200000003" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
<CapturePointNumber>1</CapturePointNumber>
|
<CapturePointNumber>1</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="1" G="1" R="0"/>
|
<Color A="1" B="1" G="1" R="0"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team/>
|
<c:Team/>
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
<CapturePointNumber>2</CapturePointNumber>
|
<CapturePointNumber>2</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team/>
|
<c:Team/>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
<CapturePointNumber>3</CapturePointNumber>
|
<CapturePointNumber>3</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="1" R="1"/>
|
<Color A="1" B="0" G="1" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team/>
|
<c:Team/>
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
<CapturePointNumber>4</CapturePointNumber>
|
<CapturePointNumber>4</CapturePointNumber>
|
||||||
</c:CapturePoint>
|
</c:CapturePoint>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
|
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0.200000003" R="1"/>
|
<Color A="1" B="0" G="0.200000003" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Team>
|
<c:Team>
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -151,7 +151,7 @@
|
|||||||
<c:Health/>
|
<c:Health/>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
<Color A="1" B="0.482352942" G="0.490196079" R="1"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -171,7 +171,7 @@
|
|||||||
</c:Health>
|
</c:Health>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0" R="2.25"/>
|
<Color A="1" B="0" G="0" R="2.25"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
@@ -191,7 +191,7 @@
|
|||||||
</c:Health>
|
</c:Health>
|
||||||
<c:AABB/>
|
<c:AABB/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>../assets/Models/Core/UnitCube.obj</Resource>
|
<Resource>../assets/Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="0" G="0" R="4.5"/>
|
<Color A="1" B="0" G="0" R="4.5"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Player/>
|
<c:Player/>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<FilePath></FilePath>
|
<FilePath></FilePath>
|
||||||
</c:SoundEmitter>
|
</c:SoundEmitter>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitCube.obj</Resource>
|
<Resource>Models/Core/UnitCube.mesh</Resource>
|
||||||
<Color A="1" B="1" G="0.58431375" R="0.43921569"/>
|
<Color A="1" B="1" G="0.58431375" R="0.43921569"/>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform/>
|
<c:Transform/>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:SpawnPoint/>
|
<c:SpawnPoint/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitSphere.obj</Resource>
|
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="0" Z="1.26689196"/>
|
<Position X="0" Y="0" Z="1.26689196"/>
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
<Components>
|
<Components>
|
||||||
<c:SpawnPoint/>
|
<c:SpawnPoint/>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Core/UnitSphere.obj</Resource>
|
<Resource>Models/Core/UnitSphere.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
<c:Transform>
|
<c:Transform>
|
||||||
<Position X="0" Y="0" Z="-1.14786315"/>
|
<Position X="0" Y="0" Z="-1.14786315"/>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<Orientation X="0" Y="0" Z="0"/>
|
<Orientation X="0" Y="0" Z="0"/>
|
||||||
</c:Transform>
|
</c:Transform>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/DummyScene.obj</Resource>
|
<Resource>Models/DummyScene.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
<Children>
|
<Children>
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<c:Camera>
|
<c:Camera>
|
||||||
</c:Camera>
|
</c:Camera>
|
||||||
<c:Model>
|
<c:Model>
|
||||||
<Resource>Models/Camera.obj</Resource>
|
<Resource>Models/Camera.mesh</Resource>
|
||||||
</c:Model>
|
</c:Model>
|
||||||
</Components>
|
</Components>
|
||||||
</Entity>
|
</Entity>
|
||||||
|
|||||||
@@ -16,6 +16,9 @@
|
|||||||
<xs:simpleType name="double">
|
<xs:simpleType name="double">
|
||||||
<xs:restriction base="xs:decimal"></xs:restriction>
|
<xs:restriction base="xs:decimal"></xs:restriction>
|
||||||
</xs:simpleType>
|
</xs:simpleType>
|
||||||
|
<xs:simpleType name="float">
|
||||||
|
<xs:restriction base="xs:decimal"></xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
<xs:simpleType name="string">
|
<xs:simpleType name="string">
|
||||||
<xs:restriction base="xs:string"></xs:restriction>
|
<xs:restriction base="xs:string"></xs:restriction>
|
||||||
</xs:simpleType>
|
</xs:simpleType>
|
||||||
|
|||||||
@@ -9,18 +9,14 @@ layout(location = 1) in vec3 Normal;
|
|||||||
layout(location = 2) in vec3 Tangent;
|
layout(location = 2) in vec3 Tangent;
|
||||||
layout(location = 3) in vec3 BiTangent;
|
layout(location = 3) in vec3 BiTangent;
|
||||||
layout(location = 4) in vec2 TextureCoords;
|
layout(location = 4) in vec2 TextureCoords;
|
||||||
layout(location = 5) in vec4 DiffuseVertexColor;
|
layout(location = 5) in vec4 BoneIndices;
|
||||||
layout(location = 6) in vec4 SpecularVertexColor;
|
layout(location = 6) in vec4 BoneWeights;
|
||||||
layout(location = 7) in vec4 BoneIndices1;
|
|
||||||
layout(location = 8) in vec4 BoneIndices2;
|
|
||||||
layout(location = 9) in vec4 BoneWeights1;
|
|
||||||
layout(location = 10) in vec4 BoneWeights2;
|
|
||||||
|
|
||||||
out VertexData{
|
out VertexData{
|
||||||
vec3 Position;
|
vec3 Position;
|
||||||
vec3 Normal;
|
vec3 Normal;
|
||||||
vec2 TextureCoordinate;
|
vec2 TextureCoordinate;
|
||||||
vec4 DiffuseColor;
|
|
||||||
}Output;
|
}Output;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
@@ -30,5 +26,4 @@ void main()
|
|||||||
Output.Position = Position;
|
Output.Position = Position;
|
||||||
Output.TextureCoordinate = TextureCoords;
|
Output.TextureCoordinate = TextureCoords;
|
||||||
Output.Normal = Normal;
|
Output.Normal = Normal;
|
||||||
Output.DiffuseColor = DiffuseVertexColor;
|
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ uniform mat4 M;
|
|||||||
uniform mat4 V;
|
uniform mat4 V;
|
||||||
uniform mat4 P;
|
uniform mat4 P;
|
||||||
uniform vec4 Color;
|
uniform vec4 Color;
|
||||||
|
uniform vec4 DiffuseColor;
|
||||||
uniform vec2 ScreenDimensions;
|
uniform vec2 ScreenDimensions;
|
||||||
layout (binding = 0) uniform sampler2D DiffuseTexture;
|
layout (binding = 0) uniform sampler2D DiffuseTexture;
|
||||||
layout (binding = 1) uniform sampler2D GlowMap;
|
layout (binding = 1) uniform sampler2D GlowMap;
|
||||||
@@ -46,7 +47,6 @@ in VertexData{
|
|||||||
vec3 Position;
|
vec3 Position;
|
||||||
vec3 Normal;
|
vec3 Normal;
|
||||||
vec2 TextureCoordinate;
|
vec2 TextureCoordinate;
|
||||||
vec4 DiffuseColor;
|
|
||||||
}Input;
|
}Input;
|
||||||
|
|
||||||
out vec4 sceneColor;
|
out vec4 sceneColor;
|
||||||
@@ -135,7 +135,7 @@ void main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//sceneColor += Input.DiffuseColor;
|
//sceneColor += Input.DiffuseColor;
|
||||||
vec4 color_result = Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color;
|
vec4 color_result = DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color;
|
||||||
//bloomColor = vec4(0.3, 0.8, 0.6, 1.0);
|
//bloomColor = vec4(0.3, 0.8, 0.6, 1.0);
|
||||||
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
|
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
|
||||||
//These if statements should be removed if they are slow.
|
//These if statements should be removed if they are slow.
|
||||||
|
|||||||
@@ -3,32 +3,37 @@
|
|||||||
uniform mat4 M;
|
uniform mat4 M;
|
||||||
uniform mat4 V;
|
uniform mat4 V;
|
||||||
uniform mat4 P;
|
uniform mat4 P;
|
||||||
|
uniform mat4 Bones[100];
|
||||||
|
|
||||||
layout(location = 0) in vec3 Position;
|
layout(location = 0) in vec3 Position;
|
||||||
layout(location = 1) in vec3 Normal;
|
layout(location = 1) in vec3 Normal;
|
||||||
layout(location = 2) in vec3 Tangent;
|
layout(location = 2) in vec3 Tangent;
|
||||||
layout(location = 3) in vec3 BiTangent;
|
layout(location = 3) in vec3 BiTangent;
|
||||||
layout(location = 4) in vec2 TextureCoords;
|
layout(location = 4) in vec2 TextureCoords;
|
||||||
layout(location = 5) in vec4 DiffuseVertexColor;
|
layout(location = 5) in vec4 BoneIndices;
|
||||||
layout(location = 6) in vec4 SpecularVertexColor;
|
layout(location = 6) in vec4 BoneWeights;
|
||||||
layout(location = 7) in vec4 BoneIndices1;
|
|
||||||
layout(location = 8) in vec4 BoneIndices2;
|
|
||||||
layout(location = 9) in vec4 BoneWeights1;
|
|
||||||
layout(location = 10) in vec4 BoneWeights2;
|
|
||||||
|
|
||||||
out VertexData{
|
out VertexData{
|
||||||
vec3 Position;
|
vec3 Position;
|
||||||
vec3 Normal;
|
vec3 Normal;
|
||||||
vec2 TextureCoordinate;
|
vec2 TextureCoordinate;
|
||||||
vec4 DiffuseColor;
|
|
||||||
}Output;
|
}Output;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = P*V*M * vec4(Position, 1.0);
|
|
||||||
|
|
||||||
Output.Position = Position;
|
|
||||||
|
mat4 boneTransform = mat4(1);
|
||||||
|
if(BoneWeights[0] > 0.0f){
|
||||||
|
boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])]
|
||||||
|
+ BoneWeights[1] * Bones[int(BoneIndices[1])]
|
||||||
|
+ BoneWeights[2] * Bones[int(BoneIndices[2])]
|
||||||
|
+ BoneWeights[3] * Bones[int(BoneIndices[3])];
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_Position = P*V*M*boneTransform * vec4(Position, 1.0);
|
||||||
|
|
||||||
|
Output.Position = (boneTransform * vec4(Position, 1.0)).xyz;
|
||||||
Output.TextureCoordinate = TextureCoords;
|
Output.TextureCoordinate = TextureCoords;
|
||||||
Output.Normal = vec3(M * vec4(Normal, 0.0));
|
Output.Normal = vec3(M * vec4(Normal, 0.0));
|
||||||
Output.DiffuseColor = DiffuseVertexColor;
|
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
|
|||||||
}
|
}
|
||||||
if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
|
if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
|
||||||
(glm::vec3&)cTransform["Position"] += resolutionVector;
|
(glm::vec3&)cTransform["Position"] += resolutionVector;
|
||||||
cPhysics["Velocity"] = glm::vec3(0, 0, 0);
|
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Inv
|
|||||||
|
|
||||||
bool EntityWrapper::HasComponent(const std::string& componentName)
|
bool EntityWrapper::HasComponent(const std::string& componentName)
|
||||||
{
|
{
|
||||||
|
if (!Valid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return World->HasComponent(ID, componentName);
|
return World->HasComponent(ID, componentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,6 +20,46 @@ EntityWrapper EntityWrapper::Parent()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityWrapper EntityWrapper::FirstChildByName(const std::string& name)
|
||||||
|
{
|
||||||
|
auto itPair = this->World->GetChildren(this->ID);
|
||||||
|
if (itPair.first == itPair.second) {
|
||||||
|
return EntityWrapper::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it = itPair.first; it != itPair.second; ++it) {
|
||||||
|
if (this->World->GetName(it->second) == name) {
|
||||||
|
return EntityWrapper(this->World, it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EntityWrapper::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& componentType)
|
||||||
|
{
|
||||||
|
EntityWrapper entity = *this;
|
||||||
|
while (entity.Parent().Valid()) {
|
||||||
|
entity = entity.Parent();
|
||||||
|
if (entity.HasComponent(componentType)) {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EntityWrapper::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityWrapper::IsChildOf(EntityWrapper potentialParent)
|
||||||
|
{
|
||||||
|
EntityWrapper entity = *this;
|
||||||
|
while (entity.Parent().Valid()) {
|
||||||
|
entity = entity.Parent();
|
||||||
|
if (entity == potentialParent) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool EntityWrapper::Valid()
|
bool EntityWrapper::Valid()
|
||||||
{
|
{
|
||||||
if (this->World == nullptr) {
|
if (this->World == nullptr) {
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ std::vector<int> Child::childIndicesContainingBox(const AABB& box) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Child::hasChildren() const
|
bool Child::hasChildren() const
|
||||||
{
|
{
|
||||||
return m_Children[0] != nullptr;
|
return m_Children[0] != nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
#include "Core/Transform.h"
|
#include "Core/Transform.h"
|
||||||
|
|
||||||
|
glm::vec3 Transform::AbsolutePosition(EntityWrapper entity)
|
||||||
|
{
|
||||||
|
return AbsolutePosition(entity.World, entity.ID);
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
|
glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
|
||||||
{
|
{
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
@@ -14,6 +19,11 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::quat Transform::AbsoluteOrientation(EntityWrapper entity)
|
||||||
|
{
|
||||||
|
return AbsoluteOrientation(entity.World, entity.ID);
|
||||||
|
}
|
||||||
|
|
||||||
glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity)
|
glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity)
|
||||||
{
|
{
|
||||||
glm::quat orientation;
|
glm::quat orientation;
|
||||||
@@ -27,6 +37,11 @@ glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity)
|
|||||||
return orientation;
|
return orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 Transform::AbsoluteScale(EntityWrapper entity)
|
||||||
|
{
|
||||||
|
return AbsoluteScale(entity.World, entity.ID);
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
|
glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
|
||||||
{
|
{
|
||||||
glm::vec3 scale(1.f);
|
glm::vec3 scale(1.f);
|
||||||
@@ -40,6 +55,11 @@ glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
|
|||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::mat4 Transform::ModelMatrix(EntityWrapper entity)
|
||||||
|
{
|
||||||
|
return ModelMatrix(entity.ID, entity.World);
|
||||||
|
}
|
||||||
|
|
||||||
glm::mat4 Transform::ModelMatrix(EntityID entity, World* world)
|
glm::mat4 Transform::ModelMatrix(EntityID entity, World* world)
|
||||||
{
|
{
|
||||||
glm::vec3 position = Transform::AbsolutePosition(world, entity);
|
glm::vec3 position = Transform::AbsolutePosition(world, entity);
|
||||||
|
|||||||
+66
-32
@@ -1,4 +1,6 @@
|
|||||||
#include "Core/World.h"
|
#include "Core/World.h"
|
||||||
|
#include "Core/EEntityDeleted.h"
|
||||||
|
#include "Core/EComponentDeleted.h"
|
||||||
|
|
||||||
World::~World()
|
World::~World()
|
||||||
{
|
{
|
||||||
@@ -21,37 +23,7 @@ EntityID World::CreateEntity(EntityID parent /*= 0*/)
|
|||||||
|
|
||||||
void World::DeleteEntity(EntityID entity)
|
void World::DeleteEntity(EntityID entity)
|
||||||
{
|
{
|
||||||
// Delete components
|
deleteEntityRecursive(entity, false);
|
||||||
for (auto& pair : m_ComponentPools) {
|
|
||||||
auto& pool = pair.second;
|
|
||||||
if (pool->KnowsEntity(entity)) {
|
|
||||||
auto& c = pool->GetByEntity(entity);
|
|
||||||
pool->Delete(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through children
|
|
||||||
std::vector<EntityID> childrenToDelete;
|
|
||||||
auto children = m_EntityChildren.equal_range(entity);
|
|
||||||
for (auto it = children.first; it != children.second; ++it) {
|
|
||||||
childrenToDelete.push_back(it->second);
|
|
||||||
}
|
|
||||||
for (auto& child : childrenToDelete) {
|
|
||||||
DeleteEntity(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityID parent = m_EntityParents.at(entity);
|
|
||||||
m_EntityParents.erase(entity);
|
|
||||||
auto parentChildren = m_EntityChildren.equal_range(parent);
|
|
||||||
for (auto it = parentChildren.first; it != parentChildren.second; ++it) {
|
|
||||||
if (it->second == entity) {
|
|
||||||
m_EntityChildren.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase potential name
|
|
||||||
m_EntityNames.erase(entity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::ValidEntity(EntityID entity) const
|
bool World::ValidEntity(EntityID entity) const
|
||||||
@@ -96,7 +68,15 @@ void World::DeleteComponent(EntityID entity, const std::string& componentType)
|
|||||||
{
|
{
|
||||||
ComponentPool* pool = m_ComponentPools.at(componentType);
|
ComponentPool* pool = m_ComponentPools.at(componentType);
|
||||||
ComponentWrapper c = pool->GetByEntity(entity);
|
ComponentWrapper c = pool->GetByEntity(entity);
|
||||||
return pool->Delete(c);
|
pool->Delete(c);
|
||||||
|
|
||||||
|
if (m_EventBroker != nullptr) {
|
||||||
|
Events::ComponentDeleted e;
|
||||||
|
e.Entity = entity;
|
||||||
|
e.ComponentType = componentType;
|
||||||
|
e.Cascaded = false;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ComponentPool* World::GetComponents(const std::string& componentType)
|
const ComponentPool* World::GetComponents(const std::string& componentType)
|
||||||
@@ -155,3 +135,57 @@ EntityID World::generateEntityID()
|
|||||||
return m_CurrentEntityID++;
|
return m_CurrentEntityID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void World::deleteEntityRecursive(EntityID entity, bool cascaded /*= false*/)
|
||||||
|
{
|
||||||
|
// Don't attempt to delete entities that don't exist anyway
|
||||||
|
if (!ValidEntity(entity)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_EventBroker != nullptr) {
|
||||||
|
Events::EntityDeleted e;
|
||||||
|
e.DeletedEntity = entity;
|
||||||
|
e.Cascaded = cascaded;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete components
|
||||||
|
for (auto& pair : m_ComponentPools) {
|
||||||
|
auto& pool = pair.second;
|
||||||
|
if (pool->KnowsEntity(entity)) {
|
||||||
|
auto& c = pool->GetByEntity(entity);
|
||||||
|
pool->Delete(c);
|
||||||
|
if (m_EventBroker != nullptr) {
|
||||||
|
Events::ComponentDeleted e;
|
||||||
|
e.Entity = entity;
|
||||||
|
e.ComponentType = pair.first;
|
||||||
|
e.Cascaded = true;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through children
|
||||||
|
std::vector<EntityID> childrenToDelete;
|
||||||
|
auto children = m_EntityChildren.equal_range(entity);
|
||||||
|
for (auto it = children.first; it != children.second; ++it) {
|
||||||
|
childrenToDelete.push_back(it->second);
|
||||||
|
}
|
||||||
|
for (auto& child : childrenToDelete) {
|
||||||
|
deleteEntityRecursive(child, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityID parent = m_EntityParents.at(entity);
|
||||||
|
m_EntityParents.erase(entity);
|
||||||
|
auto parentChildren = m_EntityChildren.equal_range(parent);
|
||||||
|
for (auto it = parentChildren.first; it != parentChildren.second; ++it) {
|
||||||
|
if (it->second == entity) {
|
||||||
|
m_EntityChildren.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Erase potential name
|
||||||
|
m_EntityNames.erase(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ void EditorRenderSystem::Update(double dt)
|
|||||||
continue;
|
continue;
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
try {
|
try {
|
||||||
model = ResourceManager::Load<::Model>("Models/Core/Error.obj");
|
model = ResourceManager::Load<::Model>("Models/Core/Error.mesh");
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,11 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
|
|||||||
m_EditorWorldSystemPipeline->AddSystem<EditorWidgetSystem>(0, m_Renderer);
|
m_EditorWorldSystemPipeline->AddSystem<EditorWidgetSystem>(0, m_Renderer);
|
||||||
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
|
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
|
||||||
|
|
||||||
m_Camera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
|
m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
|
||||||
m_EditorWorld->AttachComponent(m_Camera.ID, "Transform");
|
m_ActualCamera = m_EditorCamera;
|
||||||
m_EditorWorld->AttachComponent(m_Camera.ID, "Camera");
|
m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform");
|
||||||
m_DebugCameraInputController = new DebugCameraInputController<EditorSystem>(m_EventBroker, -1);
|
m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Camera");
|
||||||
|
m_EditorCameraInputController = new EditorCameraInputController<EditorSystem>(m_EventBroker, -1);
|
||||||
|
|
||||||
m_EditorGUI = new EditorGUI(m_World, m_EventBroker);
|
m_EditorGUI = new EditorGUI(m_World, m_EventBroker);
|
||||||
m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1));
|
m_EditorGUI->SetEntitySelectedCallback(std::bind(&EditorSystem::OnEntitySelected, this, std::placeholders::_1));
|
||||||
@@ -33,38 +34,70 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
|
|||||||
|
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
|
EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta);
|
EVENT_SUBSCRIBE_MEMBER(m_EWidgetDelta, &EditorSystem::OnWidgetDelta);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorSystem::OnSetCamera);
|
||||||
|
|
||||||
m_EditorStats = new EditorStats();
|
m_EditorStats = new EditorStats();
|
||||||
|
|
||||||
Events::SetCamera e;
|
if (m_Enabled) {
|
||||||
e.CameraEntity = m_Camera;
|
Enable();
|
||||||
m_EventBroker->Publish(e);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorSystem::~EditorSystem()
|
EditorSystem::~EditorSystem()
|
||||||
{
|
{
|
||||||
delete m_EditorStats;
|
delete m_EditorStats;
|
||||||
delete m_EditorGUI;
|
delete m_EditorGUI;
|
||||||
delete m_DebugCameraInputController;
|
delete m_EditorCameraInputController;
|
||||||
delete m_EditorWorldSystemPipeline;
|
delete m_EditorWorldSystemPipeline;
|
||||||
delete m_EditorWorld;
|
delete m_EditorWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorSystem::Update(double dt)
|
void EditorSystem::Update(double dt)
|
||||||
{
|
{
|
||||||
m_EventBroker->Process<EditorGUI>();
|
double now = glfwGetTime();
|
||||||
m_EditorGUI->Draw();
|
double actualDelta = now - m_LastTime;
|
||||||
m_EditorStats->Draw(dt);
|
m_LastTime = now;
|
||||||
|
|
||||||
if (m_CurrentSelection.Valid() && m_Widget.Valid()) {
|
if (m_Enabled) {
|
||||||
(glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID);
|
m_EventBroker->Process<EditorGUI>();
|
||||||
|
m_EditorGUI->Draw();
|
||||||
|
m_EditorStats->Draw(actualDelta);
|
||||||
|
|
||||||
|
if (m_CurrentSelection.Valid() && m_Widget.Valid()) {
|
||||||
|
(glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_EditorWorldSystemPipeline->Update(actualDelta);
|
||||||
|
|
||||||
|
ComponentWrapper& cameraTransform = m_EditorCamera["Transform"];
|
||||||
|
glm::vec3& ori = cameraTransform["Orientation"];
|
||||||
|
ori.x = m_EditorCameraInputController->Rotation().x;
|
||||||
|
ori.y = m_EditorCameraInputController->Rotation().y;
|
||||||
|
glm::vec3& pos = cameraTransform["Position"];
|
||||||
|
pos += m_EditorCameraInputController->Movement() * glm::inverse(glm::quat(ori)) * (float)actualDelta;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_EditorWorldSystemPipeline->Update(dt);
|
void EditorSystem::Enable()
|
||||||
|
{
|
||||||
|
m_EditorCameraInputController->Enable();
|
||||||
|
m_EventBroker->Publish(Events::UnlockMouse());
|
||||||
|
Events::SetCamera e;
|
||||||
|
e.CameraEntity = m_EditorCamera;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
(glm::vec3&)m_EditorCamera["Transform"]["Position"] = Transform::AbsolutePosition(m_ActualCamera);
|
||||||
|
m_Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
m_DebugCameraInputController->Update(dt);
|
void EditorSystem::Disable()
|
||||||
m_Camera["Transform"]["Position"] = m_DebugCameraInputController->Position();
|
{
|
||||||
m_Camera["Transform"]["Orientation"] = glm::eulerAngles(m_DebugCameraInputController->Orientation());
|
m_EditorCameraInputController->Disable();
|
||||||
|
m_EventBroker->Publish(Events::LockMouse());
|
||||||
|
Events::SetCamera e;
|
||||||
|
e.CameraEntity = m_ActualCamera;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
m_Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorSystem::OnEntitySelected(EntityWrapper entity)
|
void EditorSystem::OnEntitySelected(EntityWrapper entity)
|
||||||
@@ -148,6 +181,33 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EditorSystem::OnInputCommand(const Events::InputCommand& e)
|
||||||
|
{
|
||||||
|
if (e.PlayerID != -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Command == "ToggleEditor" && e.Value > 0) {
|
||||||
|
if (m_Enabled) {
|
||||||
|
Disable();
|
||||||
|
} else {
|
||||||
|
Enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorSystem::OnSetCamera(const Events::SetCamera& e)
|
||||||
|
{
|
||||||
|
if (m_Enabled && e.CameraEntity != m_EditorCamera) {
|
||||||
|
m_ActualCamera = e.CameraEntity;
|
||||||
|
Events::SetCamera e2;
|
||||||
|
e2.CameraEntity = m_EditorCamera;
|
||||||
|
m_EventBroker->Publish(e2);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem::path filePath)
|
EntityWrapper EditorSystem::importEntity(EntityWrapper parent, boost::filesystem::path filePath)
|
||||||
{
|
{
|
||||||
if (parent.World == nullptr) {
|
if (parent.World == nullptr) {
|
||||||
|
|||||||
+194
-88
@@ -5,14 +5,20 @@ using namespace boost::asio::ip;
|
|||||||
|
|
||||||
Client::Client(ConfigFile* config) : m_Socket(m_IOService)
|
Client::Client(ConfigFile* config) : m_Socket(m_IOService)
|
||||||
{
|
{
|
||||||
// Asumes root node is EntityID 0
|
Network::initialize();
|
||||||
insertIntoServerClientMaps(0, 0);
|
|
||||||
|
// Asumes root node is EntityID_Invalid
|
||||||
|
insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid);
|
||||||
|
// Init timer
|
||||||
|
m_TimeSinceSentInputs = std::clock();
|
||||||
// Default is local host
|
// Default is local host
|
||||||
std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1");
|
std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1");
|
||||||
int port = config->Get<int>("Networking.Port", 13);
|
int port = config->Get<int>("Networking.Port", 27666);
|
||||||
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
|
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
|
||||||
// Set up network stream
|
// Set up network stream
|
||||||
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
|
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
|
||||||
|
m_SendInputIntervalMs = config->Get<int>("Networking.SendInputIntervalMs", 33);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Client::~Client()
|
Client::~Client()
|
||||||
@@ -25,7 +31,8 @@ void Client::Start(World* world, EventBroker* eventBroker)
|
|||||||
|
|
||||||
// Subscribe to events
|
// Subscribe to events
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayeDamage, &Client::OnPlayerDamage);
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned);
|
||||||
|
|
||||||
m_Socket.connect(m_ReceiverEndpoint);
|
m_Socket.connect(m_ReceiverEndpoint);
|
||||||
LOG_INFO("I am client. BIP BOP");
|
LOG_INFO("I am client. BIP BOP");
|
||||||
@@ -37,19 +44,25 @@ void Client::Update()
|
|||||||
readFromServer();
|
readFromServer();
|
||||||
if (m_IsConnected) {
|
if (m_IsConnected) {
|
||||||
hasServerTimedOut();
|
hasServerTimedOut();
|
||||||
|
// Don't sent 1 input in 1 packet, bunch em up.
|
||||||
|
if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) {
|
||||||
|
sendInputCommands();
|
||||||
|
m_TimeSinceSentInputs = std::clock();
|
||||||
|
}
|
||||||
|
sendLocalPlayerTransform();
|
||||||
}
|
}
|
||||||
|
Network::Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::readFromServer()
|
void Client::readFromServer()
|
||||||
{
|
{
|
||||||
while (m_Socket.available()) {
|
while (m_Socket.available()) {
|
||||||
bytesRead = receive(readBuf, INPUTSIZE);
|
bytesRead = receive(readBuf);
|
||||||
if (bytesRead > 0) {
|
if (bytesRead > 0) {
|
||||||
Packet packet(readBuf, bytesRead);
|
Packet packet(readBuf, bytesRead);
|
||||||
parseMessageType(packet);
|
parseMessageType(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sendInputCommands();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::parseMessageType(Packet& packet)
|
void Client::parseMessageType(Packet& packet)
|
||||||
@@ -66,12 +79,9 @@ void Client::parseMessageType(Packet& packet)
|
|||||||
case MessageType::Connect:
|
case MessageType::Connect:
|
||||||
parseConnect(packet);
|
parseConnect(packet);
|
||||||
break;
|
break;
|
||||||
case MessageType::ClientPing:
|
case MessageType::Ping:
|
||||||
parsePing();
|
parsePing();
|
||||||
break;
|
break;
|
||||||
case MessageType::ServerPing:
|
|
||||||
parseServerPing();
|
|
||||||
break;
|
|
||||||
case MessageType::Message:
|
case MessageType::Message:
|
||||||
break;
|
break;
|
||||||
case MessageType::Snapshot:
|
case MessageType::Snapshot:
|
||||||
@@ -81,6 +91,19 @@ void Client::parseMessageType(Packet& packet)
|
|||||||
break;
|
break;
|
||||||
case MessageType::PlayerConnected:
|
case MessageType::PlayerConnected:
|
||||||
parsePlayerConnected(packet);
|
parsePlayerConnected(packet);
|
||||||
|
break;
|
||||||
|
case MessageType::Kick:
|
||||||
|
parseKick();
|
||||||
|
break;
|
||||||
|
case MessageType::OnPlayerSpawned:
|
||||||
|
parsePlayersSpawned(packet);
|
||||||
|
break;
|
||||||
|
case MessageType::EntityDeleted:
|
||||||
|
parseEntityDeletion(packet);
|
||||||
|
break;
|
||||||
|
case MessageType::ComponentDeleted:
|
||||||
|
parseComponentDeletion(packet);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -99,11 +122,6 @@ void Client::parsePlayerConnected(Packet & packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Client::parsePing()
|
void Client::parsePing()
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::parseServerPing()
|
|
||||||
{
|
{
|
||||||
// Might miss connect message so set it here instead.
|
// Might miss connect message so set it here instead.
|
||||||
m_IsConnected = true;
|
m_IsConnected = true;
|
||||||
@@ -112,11 +130,49 @@ void Client::parseServerPing()
|
|||||||
LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime);
|
LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime);
|
||||||
m_StartPingTime = std::clock();
|
m_StartPingTime = std::clock();
|
||||||
|
|
||||||
Packet packet(MessageType::ServerPing, m_SendPacketID);
|
Packet packet(MessageType::Ping, m_SendPacketID, m_PacketID, ackBitField);
|
||||||
packet.WriteString("Ping recieved");
|
packet.WriteString("Ping recieved");
|
||||||
send(packet);
|
send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::parseKick()
|
||||||
|
{
|
||||||
|
LOG_WARNING("You have been kicked from the server.");
|
||||||
|
m_IsConnected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::parsePlayersSpawned(Packet& packet)
|
||||||
|
{
|
||||||
|
Events::PlayerSpawned e;
|
||||||
|
e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
|
||||||
|
e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
|
||||||
|
e.PlayerID = -1;
|
||||||
|
e.PlayerName = packet.ReadString();
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::parseEntityDeletion(Packet & packet)
|
||||||
|
{
|
||||||
|
EntityID entityToDelete = packet.ReadPrimitive<EntityID>();
|
||||||
|
// TODO: What if an entity that didn't previously exist comes as a delete request and later comes in a delayed snapshot?
|
||||||
|
if (m_ServerIDToClientID.find(entityToDelete) != m_ServerIDToClientID.end()) {
|
||||||
|
EntityID localEntity = m_ServerIDToClientID.at(entityToDelete);
|
||||||
|
if (m_World->ValidEntity(localEntity)) {
|
||||||
|
m_World->DeleteEntity(localEntity);
|
||||||
|
deleteFromServerClientMaps(entityToDelete, localEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::parseComponentDeletion(Packet & packet)
|
||||||
|
{
|
||||||
|
EntityID entity = packet.ReadPrimitive<EntityID>();
|
||||||
|
std::string componentType = packet.ReadString();
|
||||||
|
if (m_World->HasComponent(entity, componentType)) {
|
||||||
|
m_World->DeleteComponent(m_ServerIDToClientID.at(entity), componentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fields with strings will not work right now
|
// Fields with strings will not work right now
|
||||||
void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType)
|
void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType)
|
||||||
{
|
{
|
||||||
@@ -151,75 +207,71 @@ void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, co
|
|||||||
|
|
||||||
void Client::parseSnapshot(Packet& packet)
|
void Client::parseSnapshot(Packet& packet)
|
||||||
{
|
{
|
||||||
std::string componentType = packet.ReadString();
|
|
||||||
while (packet.DataReadSize() < packet.Size()) {
|
while (packet.DataReadSize() < packet.Size()) {
|
||||||
// Components EntityID
|
EntityID serverEntityID = packet.ReadPrimitive<EntityID>();
|
||||||
EntityID receivedEntityID = packet.ReadPrimitive<EntityID>();
|
EntityID serverParentID = packet.ReadPrimitive<EntityID>();
|
||||||
// Parents EntityID
|
std::string serverEntityName = packet.ReadString();
|
||||||
EntityID receivedParentEntityID = packet.ReadPrimitive<EntityID>();
|
int ammountOfComponents = packet.ReadPrimitive<int>();
|
||||||
ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
|
for (int i = 0; i < ammountOfComponents; i++) {
|
||||||
// Check if the received EntityID is mapped to one of our local EntityIDs
|
std::string componentType = packet.ReadString();
|
||||||
if (serverClientMapsHasEntity(receivedEntityID)) {
|
ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
|
||||||
// Get the local EntityID
|
if (serverClientMapsHasEntity(serverEntityID)) {
|
||||||
EntityID entityID = m_ServerIDToClientID.at(receivedEntityID);
|
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
|
||||||
// Check if the component exists
|
// Update entity
|
||||||
if (m_World->HasComponent(entityID, componentType)) {
|
if (m_World->HasComponent(localEntityID, componentType)) {
|
||||||
// If the entity and the component exists update it
|
// Update component
|
||||||
if (componentType == "Transform") {
|
if (componentType == "Transform") {
|
||||||
InterpolateFields(packet, componentInfo, entityID, componentType);
|
// Interpolate only transform components
|
||||||
|
InterpolateFields(packet, componentInfo, localEntityID, componentType);
|
||||||
|
} else if (componentType == "Physics" && m_World->HasComponent(localEntityID, "Player")) {
|
||||||
|
// HACK: Ignore velocity of physics
|
||||||
|
packet.ReadData(componentInfo.Stride);
|
||||||
|
} else {
|
||||||
|
// Set component values
|
||||||
|
updateFields(packet, componentInfo, localEntityID, componentType);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
updateFields(packet, componentInfo, entityID, componentType);
|
// Has entity but no component
|
||||||
|
m_World->AttachComponent(localEntityID, componentType);
|
||||||
|
updateFields(packet, componentInfo, localEntityID, componentType);
|
||||||
}
|
}
|
||||||
// if entity exists but not the component
|
|
||||||
} else {
|
} else {
|
||||||
// Create component
|
// Create Entity and component
|
||||||
m_World->AttachComponent(entityID, componentType);
|
EntityID newLocalEntityID;
|
||||||
// Copy data to newly created component
|
if (serverParentID == EntityID_Invalid) {
|
||||||
updateFields(packet, componentInfo, entityID, componentType);
|
newLocalEntityID = m_World->CreateEntity(EntityID_Invalid);
|
||||||
|
} else {
|
||||||
|
newLocalEntityID = m_World->CreateEntity(m_ServerIDToClientID.at(serverParentID));
|
||||||
|
}
|
||||||
|
m_World->SetName(newLocalEntityID, serverEntityName);
|
||||||
|
insertIntoServerClientMaps(serverEntityID, newLocalEntityID);
|
||||||
|
m_World->AttachComponent(newLocalEntityID, componentType);
|
||||||
|
updateFields(packet, componentInfo, newLocalEntityID, componentType);
|
||||||
}
|
}
|
||||||
// If the entity dosent exist nor the component
|
|
||||||
} else {
|
|
||||||
// Create Entity
|
|
||||||
// If entity dosen't exist
|
|
||||||
EntityID newEntityID = m_World->CreateEntity();
|
|
||||||
insertIntoServerClientMaps(receivedEntityID, newEntityID);
|
|
||||||
// Check if EntityIDs are out of sync
|
|
||||||
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)");
|
|
||||||
}
|
|
||||||
// Create component
|
|
||||||
m_World->AttachComponent(newEntityID, componentType);
|
|
||||||
// Copy data to newly created component
|
|
||||||
updateFields(packet, componentInfo, newEntityID, componentType);
|
|
||||||
}
|
}
|
||||||
|
// Parent logic
|
||||||
// Parent Logic
|
// This should be enough beacause we know that the entities arives in pre-order (there will always be a parent)
|
||||||
// Don't need to check if receivedEntityID is mapped. (It should have been set)
|
if (serverParentID != EntityID_Invalid) {
|
||||||
if (receivedParentEntityID != std::numeric_limits<EntityID>::max()) {
|
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
|
||||||
if (serverClientMapsHasEntity(receivedParentEntityID)) {
|
m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID));
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Client::receive(char* data, size_t length)
|
int Client::receive(char* data)
|
||||||
{
|
{
|
||||||
boost::system::error_code error;
|
boost::system::error_code error;
|
||||||
|
|
||||||
int bytesReceived = m_Socket.receive_from(boost
|
int bytesReceived = m_Socket.receive_from(boost
|
||||||
::asio::buffer((void*)data, length),
|
::asio::buffer((void*)data, INPUTSIZE),
|
||||||
m_ReceiverEndpoint,
|
m_ReceiverEndpoint,
|
||||||
0, error);
|
0, error);
|
||||||
|
// Network Debug data
|
||||||
|
if (isReadingData) {
|
||||||
|
m_NetworkData.TotalDataReceived += bytesReceived;
|
||||||
|
m_NetworkData.DataReceivedThisInterval += bytesReceived;
|
||||||
|
m_NetworkData.AmountOfMessagesReceived++;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
//LOG_ERROR("receive: %s", error.message().c_str());
|
//LOG_ERROR("receive: %s", error.message().c_str());
|
||||||
}
|
}
|
||||||
@@ -232,11 +284,17 @@ void Client::send(Packet& packet)
|
|||||||
packet.Data(),
|
packet.Data(),
|
||||||
packet.Size()),
|
packet.Size()),
|
||||||
m_ReceiverEndpoint, 0);
|
m_ReceiverEndpoint, 0);
|
||||||
|
// Network Debug data
|
||||||
|
if (isReadingData) {
|
||||||
|
m_NetworkData.TotalDataSent += packet.Size();
|
||||||
|
m_NetworkData.DataSentThisInterval += packet.Size();
|
||||||
|
m_NetworkData.AmountOfMessagesSent++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::connect()
|
void Client::connect()
|
||||||
{
|
{
|
||||||
Packet packet(MessageType::Connect, m_SendPacketID);
|
Packet packet(MessageType::Connect, m_SendPacketID, m_PacketID, ackBitField);
|
||||||
packet.WriteString(m_PlayerName);
|
packet.WriteString(m_PlayerName);
|
||||||
m_StartPingTime = std::clock();
|
m_StartPingTime = std::clock();
|
||||||
send(packet);
|
send(packet);
|
||||||
@@ -246,18 +304,10 @@ void Client::disconnect()
|
|||||||
{
|
{
|
||||||
m_PreviousPacketID = 0;
|
m_PreviousPacketID = 0;
|
||||||
m_PacketID = 0;
|
m_PacketID = 0;
|
||||||
Packet packet(MessageType::Disconnect, m_SendPacketID);
|
Packet packet(MessageType::Disconnect, m_SendPacketID, m_PacketID, ackBitField);
|
||||||
send(packet);
|
send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::ping()
|
|
||||||
{
|
|
||||||
//Packet packet(MessageType::Connect, m_SendPacketID);
|
|
||||||
//packet.WriteString("Ping");
|
|
||||||
//m_StartPingTime = std::clock();
|
|
||||||
//send(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::OnInputCommand(const Events::InputCommand & e)
|
bool Client::OnInputCommand(const Events::InputCommand & e)
|
||||||
{
|
{
|
||||||
if (e.Command == "ConnectToServer") { // Connect for now
|
if (e.Command == "ConnectToServer") { // Connect for now
|
||||||
@@ -275,6 +325,15 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
|
|||||||
if (e.Value > 0) {
|
if (e.Value > 0) {
|
||||||
becomePlayer();
|
becomePlayer();
|
||||||
}
|
}
|
||||||
|
} else if (e.Command == "LogNetworkBandwidth") {
|
||||||
|
if (e.Value > 0) {
|
||||||
|
// Save to file if we no longer want to read data.
|
||||||
|
if (isReadingData) {
|
||||||
|
saveToFile();
|
||||||
|
}
|
||||||
|
isReadingData = !isReadingData;
|
||||||
|
m_SaveDataTimer = std::clock();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
m_InputCommandBuffer.push_back(e);
|
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);
|
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||||
@@ -285,13 +344,40 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
|
|||||||
|
|
||||||
bool Client::OnPlayerDamage(const Events::PlayerDamage & e)
|
bool Client::OnPlayerDamage(const Events::PlayerDamage & e)
|
||||||
{
|
{
|
||||||
Packet packet(MessageType::OnInputCommand, m_SendPacketID);
|
Packet packet(MessageType::OnPlayerDamage, m_SendPacketID, m_PacketID, ackBitField);
|
||||||
packet.WritePrimitive(e.DamageAmount);
|
packet.WritePrimitive(e.Damage);
|
||||||
packet.WritePrimitive(e.PlayerDamagedID);
|
packet.WritePrimitive(e.Player.ID);
|
||||||
send(packet);
|
send(packet);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e)
|
||||||
|
{
|
||||||
|
if (e.PlayerID == -1) {
|
||||||
|
m_LocalPlayer = e.Player;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::sendLocalPlayerTransform()
|
||||||
|
{
|
||||||
|
if (!m_LocalPlayer.Valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentWrapper cTransform = m_LocalPlayer["Transform"];
|
||||||
|
glm::vec3& position = cTransform["Position"];
|
||||||
|
glm::vec3& orientation = cTransform["Orientation"];
|
||||||
|
Packet packet(MessageType::PlayerTransform, m_SendPacketID, m_PacketID, ackBitField);
|
||||||
|
packet.WritePrimitive(position.x);
|
||||||
|
packet.WritePrimitive(position.y);
|
||||||
|
packet.WritePrimitive(position.z);
|
||||||
|
packet.WritePrimitive(orientation.x);
|
||||||
|
packet.WritePrimitive(orientation.y);
|
||||||
|
packet.WritePrimitive(orientation.z);
|
||||||
|
send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
void Client::identifyPacketLoss()
|
void Client::identifyPacketLoss()
|
||||||
{
|
{
|
||||||
// if no packets lost, difference should be equal to 1
|
// if no packets lost, difference should be equal to 1
|
||||||
@@ -305,7 +391,7 @@ bool Client::hasServerTimedOut()
|
|||||||
{
|
{
|
||||||
// Time in ms
|
// Time in ms
|
||||||
float timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
float timeSincePing = 1000 * (std::clock() - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
||||||
if (timeSincePing > TIMEOUTMS) {
|
if (timeSincePing > m_TimeoutMs) {
|
||||||
// Clear everything and go to menu.
|
// Clear everything and go to menu.
|
||||||
LOG_INFO("Server has timed out, returning to menu, Beep Boop.");
|
LOG_INFO("Server has timed out, returning to menu, Beep Boop.");
|
||||||
m_IsConnected = false;
|
m_IsConnected = false;
|
||||||
@@ -319,7 +405,7 @@ EntityID Client::createPlayer()
|
|||||||
EntityID entityID = m_World->CreateEntity();
|
EntityID entityID = m_World->CreateEntity();
|
||||||
ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform");
|
ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform");
|
||||||
ComponentWrapper model = m_World->AttachComponent(entityID, "Model");
|
ComponentWrapper model = m_World->AttachComponent(entityID, "Model");
|
||||||
model["Resource"] = "Models/Core/UnitSphere.obj";
|
model["Resource"] = "Models/Core/UnitSphere.mesh";
|
||||||
ComponentWrapper player = m_World->AttachComponent(entityID, "Player");
|
ComponentWrapper player = m_World->AttachComponent(entityID, "Player");
|
||||||
return entityID;
|
return entityID;
|
||||||
}
|
}
|
||||||
@@ -327,7 +413,7 @@ EntityID Client::createPlayer()
|
|||||||
void Client::sendInputCommands()
|
void Client::sendInputCommands()
|
||||||
{
|
{
|
||||||
if (m_InputCommandBuffer.size() > 0) {
|
if (m_InputCommandBuffer.size() > 0) {
|
||||||
Packet packet(MessageType::OnInputCommand, m_SendPacketID);
|
Packet packet(MessageType::OnInputCommand, m_SendPacketID, m_PacketID, ackBitField);
|
||||||
for (int i = 0; i < m_InputCommandBuffer.size(); i++) {
|
for (int i = 0; i < m_InputCommandBuffer.size(); i++) {
|
||||||
packet.WriteString(m_InputCommandBuffer[i].Command);
|
packet.WriteString(m_InputCommandBuffer[i].Command);
|
||||||
packet.WritePrimitive(m_InputCommandBuffer[i].Value);
|
packet.WritePrimitive(m_InputCommandBuffer[i].Value);
|
||||||
@@ -339,18 +425,32 @@ void Client::sendInputCommands()
|
|||||||
|
|
||||||
void Client::becomePlayer()
|
void Client::becomePlayer()
|
||||||
{
|
{
|
||||||
Packet packet = Packet(MessageType::BecomePlayer, m_SendPacketID);
|
Packet packet(MessageType::BecomePlayer, m_SendPacketID, m_PacketID, ackBitField);
|
||||||
send(packet);
|
send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
|
bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
|
||||||
{
|
{
|
||||||
return m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end();
|
if (m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end()) {
|
||||||
|
if (m_World->ValidEntity(clientEntityID)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
EntityID serverEntityID = m_ClientIDToServerID.at(clientEntityID);
|
||||||
|
deleteFromServerClientMaps(serverEntityID, clientEntityID);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::serverClientMapsHasEntity(EntityID serverEntityID)
|
bool Client::serverClientMapsHasEntity(EntityID serverEntityID)
|
||||||
{
|
{
|
||||||
return m_ServerIDToClientID.find(serverEntityID) != m_ServerIDToClientID.end();
|
if (m_ServerIDToClientID.find(serverEntityID) != m_ServerIDToClientID.end()) {
|
||||||
|
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
|
||||||
|
if (m_World->ValidEntity(localEntityID)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
deleteFromServerClientMaps(serverEntityID, localEntityID);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID)
|
void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID)
|
||||||
@@ -359,3 +459,9 @@ void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID client
|
|||||||
m_ClientIDToServerID.insert(std::make_pair(clientEntityID, serverEntityID));
|
m_ClientIDToServerID.insert(std::make_pair(clientEntityID, serverEntityID));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID)
|
||||||
|
{
|
||||||
|
m_ServerIDToClientID.erase(serverEntityID);
|
||||||
|
m_ClientIDToServerID.erase(clientEntityID);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#include "Network/Network.h"
|
||||||
|
|
||||||
|
void Network::Update()
|
||||||
|
{
|
||||||
|
updateNetworkData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::saveToFile()
|
||||||
|
{
|
||||||
|
std::ofstream outfile;
|
||||||
|
time_t t = time(0);
|
||||||
|
// get time now
|
||||||
|
struct tm * now = localtime(&t);
|
||||||
|
// Get current time and date
|
||||||
|
std::string dateAndTime = "BandwidthData - " + std::to_string(now->tm_year + 1900) + '-'
|
||||||
|
+ std::to_string(now->tm_mon + 1) + '-'
|
||||||
|
+ std::to_string(now->tm_mday) + '_'
|
||||||
|
+ std::to_string(now->tm_hour) + "h."
|
||||||
|
+ std::to_string(now->tm_min) + "m."
|
||||||
|
+ std::to_string(now->tm_sec) + 's';
|
||||||
|
|
||||||
|
outfile.open(dateAndTime + ".csv");
|
||||||
|
outfile << "Total time," + std::to_string(m_NetworkData.TotalTime) + "\n";
|
||||||
|
outfile << "Total data received," + std::to_string(m_NetworkData.TotalDataReceived) + "\n";
|
||||||
|
outfile << "Total data sent," + std::to_string(m_NetworkData.TotalDataSent) + "\n";
|
||||||
|
outfile << "Total messages received," + std::to_string(m_NetworkData.AmountOfMessagesReceived) + "\n";
|
||||||
|
outfile << "Total messages sent," + std::to_string(m_NetworkData.AmountOfMessagesSent) + "\n";
|
||||||
|
|
||||||
|
float messagesReceivedPerSec = (float)m_NetworkData.AmountOfMessagesReceived / (m_NetworkData.TotalTime / 1000);
|
||||||
|
float messagesSentPerSec = (float)m_NetworkData.AmountOfMessagesSent / (m_NetworkData.TotalTime / 1000);
|
||||||
|
float dataReceivedPerSec = (float)m_NetworkData.TotalDataReceived / (m_NetworkData.TotalTime / 1000);
|
||||||
|
float dataSentPerSec = (float)m_NetworkData.TotalDataSent / (m_NetworkData.TotalTime / 1000);
|
||||||
|
outfile << "Avarage messages received / s: " + std::to_string(messagesReceivedPerSec) + "\n";
|
||||||
|
outfile << "Avarage messages sents / s: " + std::to_string(messagesSentPerSec) + "\n";
|
||||||
|
outfile << "Avarage data received B/s: " + std::to_string(dataReceivedPerSec) + "\n";
|
||||||
|
outfile << "Avarage data sents B/s: " + std::to_string(dataSentPerSec) + "\n";
|
||||||
|
|
||||||
|
outfile << "time, avg receive B, avg send B\n";
|
||||||
|
for (int i = 0; i < m_NetworkData.BandwidthBytes.size(); i++) {
|
||||||
|
outfile << std::to_string(i) + ",";
|
||||||
|
outfile << std::to_string(m_NetworkData.BandwidthBytes[i].first) + ",";
|
||||||
|
outfile << std::to_string(m_NetworkData.BandwidthBytes[i].second) + "\n";
|
||||||
|
}
|
||||||
|
outfile.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::updateNetworkData()
|
||||||
|
{
|
||||||
|
std::clock_t currentTime = std::clock();
|
||||||
|
// Send snapshot
|
||||||
|
if (m_SaveDataIntervalMs < (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC)) {
|
||||||
|
// Set values
|
||||||
|
m_NetworkData.TotalTime += (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC);
|
||||||
|
m_NetworkData.BandwidthBytes.push_back(std::pair<unsigned int, unsigned int>(m_NetworkData.DataReceivedThisInterval, m_NetworkData.DataSentThisInterval));
|
||||||
|
// Reset interval stuff
|
||||||
|
m_SaveDataTimer = std::clock();
|
||||||
|
m_NetworkData.DataSentThisInterval = 0;
|
||||||
|
m_NetworkData.DataReceivedThisInterval = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Network::initialize()
|
||||||
|
{
|
||||||
|
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
|
m_MaxConnections = config->Get<int>("Networking.MaxConnections", 8);
|
||||||
|
m_TimeoutMs = config->Get<int>("Networking.TimeoutMs", 20000);
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "Network/Packet.h"
|
#include "Network/Packet.h"
|
||||||
|
|
||||||
Packet::Packet(MessageType type, unsigned int& packetID)
|
Packet::Packet(MessageType type, unsigned int& packetID, unsigned int lastReceivedPacket, unsigned int ackBitField)
|
||||||
{
|
{
|
||||||
m_Data = new char[m_MaxPacketSize];
|
m_Data = new char[m_MaxPacketSize];
|
||||||
Init(type, packetID);
|
Init(type, packetID, lastReceivedPacket, ackBitField);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create message
|
// Create message
|
||||||
@@ -21,7 +21,9 @@ Packet::Packet(MessageType type)
|
|||||||
{
|
{
|
||||||
m_Data = new char[m_MaxPacketSize];
|
m_Data = new char[m_MaxPacketSize];
|
||||||
unsigned int dummy = 0;
|
unsigned int dummy = 0;
|
||||||
Init(type, dummy);
|
// Dummy allocates memory for later insertion of
|
||||||
|
// correct values
|
||||||
|
Init(type, dummy, dummy, dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
Packet::~Packet()
|
Packet::~Packet()
|
||||||
@@ -29,16 +31,19 @@ Packet::~Packet()
|
|||||||
delete[] m_Data;
|
delete[] m_Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packet::Init(MessageType type, unsigned int & packetID)
|
void Packet::Init(MessageType type, unsigned int & packetID, unsigned int lastReceivedPacket, unsigned int ackBitField)
|
||||||
{
|
{
|
||||||
m_ReturnDataOffset = 0;
|
m_ReturnDataOffset = 0;
|
||||||
m_Offset = 0;
|
m_Offset = 0;
|
||||||
// Create message header
|
// Create message header
|
||||||
// Add message type
|
// Add message type
|
||||||
int messageType = static_cast<int>(type);
|
int messageType = static_cast<int>(type);
|
||||||
Packet::WritePrimitive<int>(messageType);
|
WritePrimitive<int>(messageType);
|
||||||
Packet::WritePrimitive<int>(packetID);
|
WritePrimitive<unsigned int>(packetID);
|
||||||
|
WritePrimitive<unsigned int>(lastReceivedPacket);
|
||||||
|
WritePrimitive<unsigned int>(ackBitField);
|
||||||
packetID++;
|
packetID++;
|
||||||
|
m_HeaderSize = m_Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packet::WriteString(const std::string& str)
|
void Packet::WriteString(const std::string& str)
|
||||||
@@ -86,16 +91,31 @@ char * Packet::ReadData(int SizeOfData)
|
|||||||
return (m_Data + oldReturnDataOffset);
|
return (m_Data + oldReturnDataOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packet::ChangePacketID(unsigned int & packetID)
|
//void Packet::ChangePacketID(unsigned int & packetID)
|
||||||
|
//{
|
||||||
|
// packetID = packetID + 1;
|
||||||
|
// // Overwrite old PacketID
|
||||||
|
// memcpy(m_Data + sizeof(int), &packetID, sizeof(int));
|
||||||
|
//}
|
||||||
|
|
||||||
|
void Packet::ChangeHeaderInfo(unsigned int& packetID, unsigned int lastReceivedPacket, unsigned int ackBitField)
|
||||||
{
|
{
|
||||||
packetID = packetID + 1;
|
packetID = packetID + 1;
|
||||||
|
// Start at sizeOf(int) cause of MessageType
|
||||||
|
int offset = sizeof(int);
|
||||||
// Overwrite old PacketID
|
// Overwrite old PacketID
|
||||||
memcpy(m_Data + sizeof(int), &packetID, sizeof(int));
|
memcpy(m_Data + sizeof(unsigned int), &packetID, offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
// Overwrite old LastReceivedPacket
|
||||||
|
memcpy(m_Data + sizeof(unsigned int), &lastReceivedPacket, offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
// Overwrite old ackBitField
|
||||||
|
memcpy(m_Data + sizeof(unsigned int), &ackBitField, offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Packet::resizeData()
|
void Packet::resizeData()
|
||||||
{
|
{
|
||||||
|
|
||||||
// Allocate memory to store our data in
|
// Allocate memory to store our data in
|
||||||
char* holdData = new char[m_MaxPacketSize];
|
char* holdData = new char[m_MaxPacketSize];
|
||||||
// Copy our data to the newly allocated memory
|
// Copy our data to the newly allocated memory
|
||||||
|
|||||||
+237
-146
@@ -1,7 +1,13 @@
|
|||||||
#include "Network/Server.h"
|
#include "Network/Server.h"
|
||||||
|
|
||||||
Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13))
|
Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666))
|
||||||
{ }
|
{
|
||||||
|
Network::initialize();
|
||||||
|
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
|
snapshotInterval = 1000 * config->Get<float>("Networking.SnapshotInterval", 0.05);
|
||||||
|
pingIntervalMs = config->Get<float>("Networking.PingIntervalMs", 1000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Server::~Server()
|
Server::~Server()
|
||||||
{
|
{
|
||||||
@@ -14,9 +20,9 @@ void Server::Start(World* world, EventBroker* eventBroker)
|
|||||||
m_EventBroker = eventBroker;
|
m_EventBroker = eventBroker;
|
||||||
// Subscribe to events
|
// Subscribe to events
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
|
||||||
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned);
|
||||||
m_PlayerDefinitions[i].StopTime = std::clock();
|
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted);
|
||||||
}
|
EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
|
||||||
LOG_INFO("I am Server. BIP BOP\n");
|
LOG_INFO("I am Server. BIP BOP\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,14 +30,27 @@ void Server::Update()
|
|||||||
{
|
{
|
||||||
readFromClients();
|
readFromClients();
|
||||||
m_EventBroker->Process<Server>();
|
m_EventBroker->Process<Server>();
|
||||||
}
|
if (isReadingData) {
|
||||||
|
Network::Update();
|
||||||
|
// Test bit patterns
|
||||||
|
//std::bitset<32> bitPattern;
|
||||||
|
//bitPattern[0].flip();
|
||||||
|
//bitPattern[15].flip();
|
||||||
|
//bitPattern[31].flip();
|
||||||
|
//std::cout << "bitPattern: " << bitPattern << '\n';
|
||||||
|
//unsigned int bitPatternInt = static_cast<unsigned int>(bitPattern.to_ulong());
|
||||||
|
//std::cout << "Int pattern: " << bitPatternInt << '\n';
|
||||||
|
//std::bitset<32> bitPatternRev(bitPatternInt);
|
||||||
|
//std::cout << "bitPatternReverted: " << bitPatternRev << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Server::readFromClients()
|
void Server::readFromClients()
|
||||||
{
|
{
|
||||||
while (m_Socket.available()) {
|
while (m_Socket.available()) {
|
||||||
try {
|
try {
|
||||||
bytesRead = receive(readBuffer, INPUTSIZE);
|
bytesRead = receive(readBuffer);
|
||||||
Packet packet(readBuffer, bytesRead);
|
Packet packet(readBuffer, bytesRead);
|
||||||
parseMessageType(packet);
|
parseMessageType(packet);
|
||||||
} catch (const std::exception& err) {
|
} catch (const std::exception& err) {
|
||||||
@@ -46,9 +65,9 @@ void Server::readFromClients()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send pings each
|
// Send pings each
|
||||||
if (intervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) {
|
if (pingIntervalMs < (1000 * (currentTime - previousPingMessage) / (double)CLOCKS_PER_SEC)) {
|
||||||
sendPing();
|
sendPing();
|
||||||
previousePingMessage = currentTime;
|
previousPingMessage = currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time out logic
|
// Time out logic
|
||||||
@@ -60,21 +79,22 @@ void Server::readFromClients()
|
|||||||
|
|
||||||
void Server::parseMessageType(Packet& packet)
|
void Server::parseMessageType(Packet& packet)
|
||||||
{
|
{
|
||||||
int messageType = packet.ReadPrimitive<int>(); // Read what type off message was sent from server
|
PlayerID playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
|
||||||
|
|
||||||
|
int messageType = packet.ReadPrimitive<int>(); // Read what type off message was sent from server
|
||||||
// Read packet ID
|
// Read packet ID
|
||||||
m_PreviousPacketID = m_PacketID; // Set previous packet id
|
if (playerID != -1) {
|
||||||
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
|
// TODO: Bit pattern stuff!"#!"#
|
||||||
|
m_ConnectedPlayers[playerID].LastPacketReceivedID = packet.ReadPrimitive<PacketID>();
|
||||||
|
}
|
||||||
|
|
||||||
//identifyPacketLoss();
|
//identifyPacketLoss();
|
||||||
switch (static_cast<MessageType>(messageType)) {
|
switch (static_cast<MessageType>(messageType)) {
|
||||||
case MessageType::Connect:
|
case MessageType::Connect:
|
||||||
parseConnect(packet);
|
parseConnect(packet, playerID);
|
||||||
break;
|
break;
|
||||||
case MessageType::ClientPing:
|
case MessageType::Ping:
|
||||||
//parseClientPing();
|
parsePing();
|
||||||
break;
|
|
||||||
case MessageType::ServerPing:
|
|
||||||
parseServerPing();
|
|
||||||
break;
|
break;
|
||||||
case MessageType::Message:
|
case MessageType::Message:
|
||||||
break;
|
break;
|
||||||
@@ -89,29 +109,46 @@ void Server::parseMessageType(Packet& packet)
|
|||||||
case MessageType::OnPlayerDamage:
|
case MessageType::OnPlayerDamage:
|
||||||
parseOnPlayerDamage(packet);
|
parseOnPlayerDamage(packet);
|
||||||
break;
|
break;
|
||||||
case MessageType::BecomePlayer:
|
case MessageType::PlayerTransform:
|
||||||
createPlayer();
|
parsePlayerTransform(packet);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int Server::receive(char * data, size_t length)
|
int Server::receive(char * data)
|
||||||
{
|
{
|
||||||
length = m_Socket.receive_from(
|
unsigned int length = m_Socket.receive_from(
|
||||||
boost::asio::buffer((void*)data
|
boost::asio::buffer((void*)data
|
||||||
, length)
|
, INPUTSIZE)
|
||||||
, m_ReceiverEndpoint, 0);
|
, m_ReceiverEndpoint, 0);
|
||||||
|
// Network Debug data
|
||||||
|
if (isReadingData) {
|
||||||
|
m_NetworkData.TotalDataReceived += length;
|
||||||
|
m_NetworkData.DataReceivedThisInterval += length;
|
||||||
|
m_NetworkData.AmountOfMessagesReceived++;
|
||||||
|
}
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::send(Packet& packet, int userID)
|
void Server::send(PlayerID playerID, Packet& packet)
|
||||||
{
|
{
|
||||||
int bytesSent = m_Socket.send_to(
|
try {
|
||||||
boost::asio::buffer(packet.Data(), packet.Size()),
|
int bytesSent = m_Socket.send_to(
|
||||||
m_ConnectedUsers[userID].Endpoint,
|
boost::asio::buffer(packet.Data(), packet.Size()),
|
||||||
0);
|
m_ConnectedPlayers[playerID].Endpoint,
|
||||||
|
0);
|
||||||
|
// Network Debug data
|
||||||
|
if (isReadingData) {
|
||||||
|
m_NetworkData.TotalDataSent += packet.Size();
|
||||||
|
m_NetworkData.DataSentThisInterval += packet.Size();
|
||||||
|
m_NetworkData.AmountOfMessagesSent++;
|
||||||
|
}
|
||||||
|
} catch (const boost::system::system_error& e) {
|
||||||
|
// TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
|
||||||
|
m_ConnectedPlayers[playerID].Endpoint = boost::asio::ip::udp::endpoint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::send(Packet & packet)
|
void Server::send(Packet & packet)
|
||||||
@@ -122,59 +159,87 @@ void Server::send(Packet & packet)
|
|||||||
packet.Size()),
|
packet.Size()),
|
||||||
m_ReceiverEndpoint,
|
m_ReceiverEndpoint,
|
||||||
0);
|
0);
|
||||||
|
if (isReadingData) {
|
||||||
|
// Network Debug data
|
||||||
|
m_NetworkData.TotalDataSent += packet.Size();
|
||||||
|
m_NetworkData.DataSentThisInterval += packet.Size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::broadcast(Packet& packet)
|
void Server::broadcast(Packet& packet)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
|
packet.ChangeHeaderInfo(
|
||||||
packet.ChangePacketID(m_ConnectedUsers[i].PacketID);
|
kv.second.PacketID,
|
||||||
send(packet, i);
|
kv.second.LastPacketReceivedID,
|
||||||
}
|
kv.second.AckBitField
|
||||||
|
);
|
||||||
|
send(kv.first, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send snapshot fields
|
// Send snapshot fields
|
||||||
void Server::sendSnapshot()
|
void Server::sendSnapshot()
|
||||||
{
|
{
|
||||||
// Should time this
|
Packet packet(MessageType::Snapshot);
|
||||||
|
addChildrenToPacket(packet, EntityID_Invalid);
|
||||||
|
broadcast(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
|
||||||
|
{
|
||||||
|
auto itPair = m_World->GetChildren(entityID);
|
||||||
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
|
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
|
||||||
for (auto& it : worldComponentPools) {
|
// Loop through every child
|
||||||
Packet packet(MessageType::Snapshot);
|
for (auto it = itPair.first; it != itPair.second; it++) {
|
||||||
ComponentPool* componentPool = it.second;
|
EntityID childEntityID = it->second;
|
||||||
ComponentInfo componentInfo = componentPool->ComponentInfo();
|
// Write EntityID and parentsID and Entity name
|
||||||
// Component Type
|
packet.WritePrimitive(childEntityID);
|
||||||
packet.WriteString(componentInfo.Name);
|
packet.WritePrimitive(entityID);
|
||||||
for (auto& componentWrapper : *componentPool) {
|
packet.WriteString(m_World->GetName(childEntityID));
|
||||||
// Components EntityID
|
// Write components to child
|
||||||
packet.WritePrimitive(componentWrapper.EntityID);
|
int numberOfComponents = 0;
|
||||||
// Parents EntityID
|
for (auto& i : worldComponentPools) {
|
||||||
packet.WritePrimitive(m_World->GetParent(componentWrapper.EntityID));
|
if (i.second->KnowsEntity(childEntityID)) {
|
||||||
for (auto& componentField : componentWrapper.Info.FieldsInOrder) {
|
numberOfComponents++;
|
||||||
ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(componentField);
|
}
|
||||||
if (fieldInfo.Type == "string") {
|
}
|
||||||
std::string& value = componentWrapper[componentField];
|
// Write how many components should be read
|
||||||
packet.WriteString(value);
|
packet.WritePrimitive(numberOfComponents);
|
||||||
} else {
|
for (auto& i : worldComponentPools) {
|
||||||
packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride);
|
// If the entity exist in the pool
|
||||||
|
if (i.second->KnowsEntity(childEntityID)) {
|
||||||
|
ComponentWrapper componentWrapper = i.second->GetByEntity(childEntityID);
|
||||||
|
// ComponentType
|
||||||
|
packet.WriteString(componentWrapper.Info.Name);
|
||||||
|
// Loop through fields
|
||||||
|
for (auto& componentField : componentWrapper.Info.FieldsInOrder) {
|
||||||
|
ComponentInfo::Field_t fieldInfo = componentWrapper.Info.Fields.at(componentField);
|
||||||
|
if (fieldInfo.Type == "string") {
|
||||||
|
std::string& value = componentWrapper[componentField];
|
||||||
|
packet.WriteString(value);
|
||||||
|
} else {
|
||||||
|
packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
broadcast(packet);
|
// Go to to your children
|
||||||
|
addChildrenToPacket(packet, childEntityID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::sendPing()
|
void Server::sendPing()
|
||||||
{
|
{
|
||||||
// Prints connected players ping
|
// Prints connected players ping
|
||||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
//for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
|
||||||
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
|
// if (m_ConnectedPlayers[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||||
int ping = 1000 * (m_ConnectedUsers[i].StopTime - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
|
// int ping = 1000 * (m_ConnectedPlayers[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));
|
// LOG_INFO("Last packetID received %i: User %i's ping: %i", m_ConnectedPlayers[i].PacketID, i, std::abs(ping));
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
// Create ping message
|
// Create ping message
|
||||||
Packet packet(MessageType::ServerPing);
|
Packet packet(MessageType::Ping);
|
||||||
packet.WriteString("Ping from server");
|
packet.WriteString("Ping from server");
|
||||||
// Time message
|
// Time message
|
||||||
m_StartPingTime = std::clock();
|
m_StartPingTime = std::clock();
|
||||||
@@ -187,11 +252,11 @@ void Server::checkForTimeOuts()
|
|||||||
int startPing = 1000 * m_StartPingTime
|
int startPing = 1000 * m_StartPingTime
|
||||||
/ static_cast<double>(CLOCKS_PER_SEC);
|
/ static_cast<double>(CLOCKS_PER_SEC);
|
||||||
|
|
||||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
|
||||||
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
|
if (m_ConnectedPlayers[i].Endpoint.address() != boost::asio::ip::address()) {
|
||||||
int stopPing = 1000 * m_ConnectedUsers[i].StopTime /
|
int stopPing = 1000 * m_ConnectedPlayers[i].StopTime /
|
||||||
static_cast<double>(CLOCKS_PER_SEC);
|
static_cast<double>(CLOCKS_PER_SEC);
|
||||||
if (startPing > stopPing + TIMEOUTMS) {
|
if (startPing > stopPing + m_TimeoutMs) {
|
||||||
LOG_INFO("User %i timed out!", i);
|
LOG_INFO("User %i timed out!", i);
|
||||||
disconnect(i);
|
disconnect(i);
|
||||||
}
|
}
|
||||||
@@ -199,35 +264,29 @@ void Server::checkForTimeOuts()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::disconnect(int i)
|
void Server::disconnect(PlayerID playerID)
|
||||||
{
|
{
|
||||||
//broadcast("A player disconnected");
|
//broadcast("A player disconnected");
|
||||||
LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[i].Name.c_str());
|
LOG_INFO("User %s disconnected/timed out", m_ConnectedPlayers[playerID].Name.c_str());
|
||||||
// Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have)
|
// 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();
|
Events::PlayerDisconnected e;
|
||||||
m_PlayerDefinitions[i].EntityID = -1;
|
e.Entity = m_ConnectedPlayers[playerID].EntityID;
|
||||||
m_PlayerDefinitions[i].Name = "";
|
e.PlayerID = playerID;
|
||||||
m_PlayerDefinitions[i].PacketID = 0;
|
m_EventBroker->Publish(e);
|
||||||
m_ConnectedUsers.erase(m_ConnectedUsers.begin() + i);
|
|
||||||
|
m_ConnectedPlayers.erase(playerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::parseOnInputCommand(Packet& packet)
|
void Server::parseOnInputCommand(Packet& packet)
|
||||||
{
|
{
|
||||||
int playerID = -1;
|
PlayerID player = -1;
|
||||||
// Check which player it was who sent the message
|
// Check which player it was who sent the message
|
||||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
|
||||||
// if the player is connected set playerID to the correct PlayerID
|
if (player != -1) {
|
||||||
if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()
|
|
||||||
&& m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) {
|
|
||||||
playerID = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (playerID != -1) {
|
|
||||||
while (packet.DataReadSize() < packet.Size()) {
|
while (packet.DataReadSize() < packet.Size()) {
|
||||||
Events::InputCommand e;
|
Events::InputCommand e;
|
||||||
e.Command = packet.ReadString();
|
e.Command = packet.ReadString();
|
||||||
e.PlayerID = playerID; // Set correct player id
|
e.PlayerID = player; // Set correct player id
|
||||||
e.Value = packet.ReadPrimitive<float>();
|
e.Value = packet.ReadPrimitive<float>();
|
||||||
m_EventBroker->Publish(e);
|
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);
|
//LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||||
@@ -238,26 +297,19 @@ void Server::parseOnInputCommand(Packet& packet)
|
|||||||
void Server::parseOnPlayerDamage(Packet & packet)
|
void Server::parseOnPlayerDamage(Packet & packet)
|
||||||
{
|
{
|
||||||
Events::PlayerDamage e;
|
Events::PlayerDamage e;
|
||||||
e.DamageAmount = packet.ReadPrimitive<double>();
|
e.Damage = packet.ReadPrimitive<double>();
|
||||||
e.PlayerDamagedID = packet.ReadPrimitive<EntityID>();
|
e.Player = EntityWrapper(m_World, packet.ReadPrimitive<EntityID>());
|
||||||
m_EventBroker->Publish(e);
|
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());
|
//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)
|
void Server::parseConnect(Packet& packet, PlayerID playerID)
|
||||||
{
|
{
|
||||||
LOG_INFO("Parsing connections");
|
LOG_INFO("Parsing connections");
|
||||||
// Check if player is already connected
|
// Check if player is already connected
|
||||||
if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) {
|
if (playerID != -1) {
|
||||||
return;
|
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
|
// Create a new player
|
||||||
PlayerDefinition pd;
|
PlayerDefinition pd;
|
||||||
pd.EntityID = 0; // Overlook this
|
pd.EntityID = 0; // Overlook this
|
||||||
@@ -265,11 +317,11 @@ void Server::parseConnect(Packet& packet)
|
|||||||
pd.Name = packet.ReadString();
|
pd.Name = packet.ReadString();
|
||||||
pd.PacketID = 0;
|
pd.PacketID = 0;
|
||||||
pd.StopTime = std::clock();
|
pd.StopTime = std::clock();
|
||||||
m_ConnectedUsers.push_back(pd);
|
Packet connnectPacket(MessageType::Connect, pd.PacketID, pd.LastPacketReceivedID, pd.AckBitField);
|
||||||
|
m_ConnectedPlayers[m_NextPlayerID++] = pd;
|
||||||
LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str());
|
LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str());
|
||||||
|
|
||||||
// Send a message to the player that connected
|
// Send a message to the player that connected
|
||||||
Packet connnectPacket(MessageType::Connect, m_ConnectedUsers[m_ConnectedUsers.size() - 1].PacketID);
|
|
||||||
send(connnectPacket);
|
send(connnectPacket);
|
||||||
|
|
||||||
// Send notification that a player has connected
|
// Send notification that a player has connected
|
||||||
@@ -281,32 +333,36 @@ void Server::parseDisconnect()
|
|||||||
{
|
{
|
||||||
LOG_INFO("%i: Parsing disconnect", m_PacketID);
|
LOG_INFO("%i: Parsing disconnect", m_PacketID);
|
||||||
|
|
||||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() &&
|
||||||
disconnect(i);
|
kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) {
|
||||||
|
disconnect(kv.first);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::parseClientPing()
|
void Server::parseClientPing(PlayerID player)
|
||||||
{
|
{
|
||||||
LOG_INFO("%i: Parsing ping", m_PacketID);
|
if (player == -1) {
|
||||||
int playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
|
|
||||||
if (playerID == -1) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Return ping
|
// Return ping
|
||||||
Packet packet(MessageType::ClientPing, m_PlayerDefinitions[playerID].PacketID);
|
Packet packet(
|
||||||
|
MessageType::Ping,
|
||||||
|
m_ConnectedPlayers[player].PacketID,
|
||||||
|
m_ConnectedPlayers[player].LastPacketReceivedID,
|
||||||
|
m_ConnectedPlayers[player].AckBitField
|
||||||
|
);
|
||||||
packet.WriteString("Ping received");
|
packet.WriteString("Ping received");
|
||||||
send(packet);
|
send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::parseServerPing()
|
void Server::parsePing()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
|
for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
|
||||||
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
if (m_ConnectedPlayers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
|
||||||
m_ConnectedUsers[i].StopTime = std::clock();
|
m_ConnectedPlayers[i].StopTime = std::clock();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -321,49 +377,19 @@ void Server::identifyPacketLoss()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::createPlayer()
|
void Server::kick(PlayerID player)
|
||||||
{
|
{
|
||||||
if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) {
|
disconnect(player);
|
||||||
// Already connected as player
|
Packet packet = Packet(MessageType::Kick);
|
||||||
LOG_WARNING("Already connected!");
|
send(packet);
|
||||||
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)
|
PlayerID Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MAXCONNECTIONS; i++) {
|
for (auto& kv : m_ConnectedPlayers) {
|
||||||
if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() &&
|
if (kv.second.Endpoint.address() == endpoint.address() &&
|
||||||
m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) {
|
kv.second.Endpoint.port() == endpoint.port()) {
|
||||||
return i;
|
return kv.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@@ -372,5 +398,70 @@ int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
|
|||||||
bool Server::OnInputCommand(const Events::InputCommand & e)
|
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);
|
//LOG_DEBUG("Server::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
|
||||||
|
if (e.Command == "LogNetworkBandwidth" && e.Value > 0) {
|
||||||
|
if (isReadingData) {
|
||||||
|
saveToFile();
|
||||||
|
}
|
||||||
|
isReadingData = !isReadingData;
|
||||||
|
m_SaveDataTimer = std::clock();
|
||||||
|
}
|
||||||
|
if (e.Command == "KickPlayer" && e.Value > 0) {
|
||||||
|
kick(0);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e)
|
||||||
|
{
|
||||||
|
m_ConnectedPlayers[e.PlayerID].EntityID = e.Player.ID;
|
||||||
|
|
||||||
|
Packet packet = Packet(MessageType::OnPlayerSpawned);
|
||||||
|
packet.WritePrimitive<EntityID>(e.Player.ID);
|
||||||
|
packet.WritePrimitive<EntityID>(e.Spawner.ID);
|
||||||
|
// We don't send PlayerID here because it will always be set to -1
|
||||||
|
packet.WriteString(m_ConnectedPlayers[e.PlayerID].Name);
|
||||||
|
send(e.PlayerID, packet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Server::OnEntityDeleted(const Events::EntityDeleted & e)
|
||||||
|
{
|
||||||
|
if (!e.Cascaded) {
|
||||||
|
Packet packet = Packet(MessageType::EntityDeleted);
|
||||||
|
packet.WritePrimitive<EntityID>(e.DeletedEntity);
|
||||||
|
broadcast(packet);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Server::OnComponentDeleted(const Events::ComponentDeleted & e)
|
||||||
|
{
|
||||||
|
if (!e.Cascaded) {
|
||||||
|
Packet packet = Packet(MessageType::ComponentDeleted);
|
||||||
|
packet.WritePrimitive<EntityID>(e.Entity);
|
||||||
|
packet.WriteString(e.ComponentType);
|
||||||
|
broadcast(packet);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Server::parsePlayerTransform(Packet& packet)
|
||||||
|
{
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec3 orientation;
|
||||||
|
position.x = packet.ReadPrimitive<float>();
|
||||||
|
position.y = packet.ReadPrimitive<float>();
|
||||||
|
position.z = packet.ReadPrimitive<float>();
|
||||||
|
orientation.x = packet.ReadPrimitive<float>();
|
||||||
|
orientation.y = packet.ReadPrimitive<float>();
|
||||||
|
orientation.z = packet.ReadPrimitive<float>();
|
||||||
|
|
||||||
|
PlayerID playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
|
||||||
|
EntityWrapper player(m_World, m_ConnectedPlayers.at(playerID).EntityID);
|
||||||
|
|
||||||
|
if (player.Valid()) {
|
||||||
|
player["Transform"]["Position"] = position;
|
||||||
|
player["Transform"]["Orientation"] = orientation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ DrawBloomPass::DrawBloomPass(IRenderer* renderer)
|
|||||||
{
|
{
|
||||||
m_Renderer = renderer;
|
m_Renderer = renderer;
|
||||||
|
|
||||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
|
||||||
|
|
||||||
InitializeTextures();
|
InitializeTextures();
|
||||||
InitializeBuffers();
|
InitializeBuffers();
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ DrawColorCorrectionPass::DrawColorCorrectionPass(IRenderer* renderer)
|
|||||||
{
|
{
|
||||||
m_Renderer = renderer;
|
m_Renderer = renderer;
|
||||||
|
|
||||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
|
||||||
m_Exposure = 1; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting.
|
m_Exposure = 0.4; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting.
|
||||||
|
|
||||||
InitializeShaderPrograms();
|
InitializeShaderPrograms();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ void DrawFinalPass::Draw(RenderScene& scene)
|
|||||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
|
||||||
glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
|
||||||
|
|
||||||
|
|
||||||
//TODO: Render: Add code for more jobs than modeljobs.
|
//TODO: Render: Add code for more jobs than modeljobs.
|
||||||
for (auto &job : scene.ForwardJobs) {
|
for (auto &job : scene.ForwardJobs) {
|
||||||
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
|
||||||
@@ -72,6 +73,7 @@ void DrawFinalPass::Draw(RenderScene& scene)
|
|||||||
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
|
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
|
||||||
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
|
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
|
||||||
|
glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(modelJob->DiffuseColor));
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
if(modelJob->DiffuseTexture != nullptr) {
|
if(modelJob->DiffuseTexture != nullptr) {
|
||||||
@@ -80,22 +82,35 @@ void DrawFinalPass::Draw(RenderScene& scene)
|
|||||||
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
|
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
|
||||||
}
|
}
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
if (modelJob->IncandescenceTexture != nullptr) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, modelJob->IncandescenceTexture->m_Texture);
|
||||||
/*if(modelJob->GlowMap != nullptr) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture);
|
|
||||||
} else {
|
} else {
|
||||||
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if(modelJob->GlowMap != nullptr) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture);
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
//TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :)
|
||||||
|
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
|
||||||
|
auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("running");
|
||||||
|
if (animation != nullptr) {
|
||||||
|
std::vector<glm::mat4> frameBones = modelJob->Model->m_RawModel->m_Skeleton->GetFrameBones(
|
||||||
|
*animation,
|
||||||
|
0.0f
|
||||||
|
);
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glBindVertexArray(modelJob->Model->VAO);
|
glBindVertexArray(modelJob->Model->VAO);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
|
||||||
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex);
|
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_FinalPassFrameBuffer.Unbind();
|
|
||||||
GLERROR("DrawFinalPass::Draw: END");
|
GLERROR("DrawFinalPass::Draw: END");
|
||||||
delete state;
|
delete state;
|
||||||
}
|
}
|
||||||
@@ -133,4 +148,4 @@ void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm:
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
GLERROR("MipMap Texture initialization failed");
|
GLERROR("MipMap Texture initialization failed");
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ DrawScreenQuadPass::DrawScreenQuadPass(IRenderer* renderer)
|
|||||||
{
|
{
|
||||||
m_Renderer = renderer;
|
m_Renderer = renderer;
|
||||||
|
|
||||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
|
||||||
|
|
||||||
InitializeShaderPrograms();
|
InitializeShaderPrograms();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ Model::Model(std::string fileName)
|
|||||||
if (!group.SpecularMapPath.empty()) {
|
if (!group.SpecularMapPath.empty()) {
|
||||||
group.SpecularMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.SpecularMapPath));
|
group.SpecularMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.SpecularMapPath));
|
||||||
}
|
}
|
||||||
|
if (!group.IncandescenceMapPath.empty()) {
|
||||||
|
group.IncandescenceMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.IncandescenceMapPath));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate GL buffers
|
// Generate GL buffers
|
||||||
@@ -32,7 +35,7 @@ Model::Model(std::string fileName)
|
|||||||
GLERROR("GLEW: BufferFail4");
|
GLERROR("GLEW: BufferFail4");
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||||
std::vector<int> structSizes = { 3, 3, 3, 3, 2, 4, 4, 4, 4, 4, 4 };
|
std::vector<int> structSizes = { 3, 3, 3, 3, 2, 4, 4 };
|
||||||
int stride = 0;
|
int stride = 0;
|
||||||
for (int size : structSizes) {
|
for (int size : structSizes) {
|
||||||
stride += size;
|
stride += size;
|
||||||
@@ -48,10 +51,6 @@ Model::Model(std::string fileName)
|
|||||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
||||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
|
||||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
|
||||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
|
||||||
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
|
|
||||||
}
|
}
|
||||||
GLERROR("GLEW: BufferFail5");
|
GLERROR("GLEW: BufferFail5");
|
||||||
|
|
||||||
@@ -62,10 +61,6 @@ Model::Model(std::string fileName)
|
|||||||
glEnableVertexAttribArray(4);
|
glEnableVertexAttribArray(4);
|
||||||
glEnableVertexAttribArray(5);
|
glEnableVertexAttribArray(5);
|
||||||
glEnableVertexAttribArray(6);
|
glEnableVertexAttribArray(6);
|
||||||
glEnableVertexAttribArray(7);
|
|
||||||
glEnableVertexAttribArray(8);
|
|
||||||
glEnableVertexAttribArray(9);
|
|
||||||
glEnableVertexAttribArray(10);
|
|
||||||
GLERROR("GLEW: BufferFail5");
|
GLERROR("GLEW: BufferFail5");
|
||||||
|
|
||||||
//CreateBuffers();
|
//CreateBuffers();
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "Rendering/RawModel.h"
|
#include "Rendering/RawModelAssimp.h"
|
||||||
|
|
||||||
RawModel::RawModel(std::string fileName)
|
#ifdef USING_ASSIMP_AS_IMPORTER
|
||||||
|
|
||||||
|
RawModelAssimp::RawModelAssimp(std::string fileName)
|
||||||
{
|
{
|
||||||
Assimp::Importer importer;
|
Assimp::Importer importer;
|
||||||
const aiScene* scene = importer.ReadFile(fileName, aiProcess_CalcTangentSpace | aiProcess_Triangulate);
|
const aiScene* scene = importer.ReadFile(fileName, aiProcess_CalcTangentSpace | aiProcess_Triangulate);
|
||||||
@@ -38,7 +40,7 @@ RawModel::RawModel(std::string fileName)
|
|||||||
//LOG_DEBUG("Index count %i", numIndices);
|
//LOG_DEBUG("Index count %i", numIndices);
|
||||||
|
|
||||||
//LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures);
|
//LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures);
|
||||||
|
|
||||||
std::vector<std::tuple<std::string, glm::mat4>> boneInfo;
|
std::vector<std::tuple<std::string, glm::mat4>> boneInfo;
|
||||||
std::map<std::string, int> boneNameMapping;
|
std::map<std::string, int> boneNameMapping;
|
||||||
|
|
||||||
@@ -74,21 +76,7 @@ RawModel::RawModel(std::string fileName)
|
|||||||
auto uv = mesh->mTextureCoords[0][vertexIndex];
|
auto uv = mesh->mTextureCoords[0][vertexIndex];
|
||||||
desc.TextureCoords = glm::vec2(uv.x, uv.y);
|
desc.TextureCoords = glm::vec2(uv.x, uv.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material diffuse color
|
|
||||||
aiColor3D diffuse;
|
|
||||||
material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
|
|
||||||
float opacity;
|
|
||||||
material->Get(AI_MATKEY_OPACITY, opacity);
|
|
||||||
desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity);
|
|
||||||
|
|
||||||
desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity);
|
|
||||||
|
|
||||||
// Material specular color
|
|
||||||
aiColor3D specular;
|
|
||||||
material->Get(AI_MATKEY_COLOR_SPECULAR, specular);
|
|
||||||
desc.SpecularVertexColor = glm::vec4(specular.r, specular.g, specular.b, 1.f);
|
|
||||||
|
|
||||||
m_Vertices.push_back(desc);
|
m_Vertices.push_back(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +116,7 @@ RawModel::RawModel(std::string fileName)
|
|||||||
}
|
}
|
||||||
for (auto& vertex : m_Vertices) {
|
for (auto& vertex : m_Vertices) {
|
||||||
vertex.Tangent = glm::normalize(vertex.Tangent);
|
vertex.Tangent = glm::normalize(vertex.Tangent);
|
||||||
vertex.BiTangent = glm::normalize(glm::cross(vertex.Tangent, glm::normalize(vertex.Normal)));
|
vertex.BiNormal = glm::normalize(glm::cross(vertex.Tangent, glm::normalize(vertex.Normal)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Material info
|
// Material info
|
||||||
@@ -201,10 +189,7 @@ RawModel::RawModel(std::string fileName)
|
|||||||
LOG_WARNING("Vertex weights (%i) greater than max weights per vertex (%i)", weights.size(), maxWeights);
|
LOG_WARNING("Vertex weights (%i) greater than max weights per vertex (%i)", weights.size(), maxWeights);
|
||||||
}
|
}
|
||||||
for (int weightIndex = 0; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 4; ++weightIndex) {
|
for (int weightIndex = 0; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 4; ++weightIndex) {
|
||||||
std::tie(desc.BoneIndices1[weightIndex], desc.BoneWeights1[weightIndex]) = weights[weightIndex];
|
std::tie(desc.BoneIndices[weightIndex], desc.BoneWeights[weightIndex]) = weights[weightIndex];
|
||||||
}
|
|
||||||
for (int weightIndex = 4; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 8; ++weightIndex) {
|
|
||||||
std::tie(desc.BoneIndices2[weightIndex - 4], desc.BoneWeights2[weightIndex - 4]) = weights[weightIndex];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,14 +275,14 @@ RawModel::RawModel(std::string fileName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RawModel::~RawModel()
|
RawModelAssimp::~RawModelAssimp()
|
||||||
{
|
{
|
||||||
if (m_Skeleton) {
|
if (m_Skeleton) {
|
||||||
delete m_Skeleton;
|
delete m_Skeleton;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawModel::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID)
|
void RawModelAssimp::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID)
|
||||||
{
|
{
|
||||||
std::string nodeName = node->mName.C_Str();
|
std::string nodeName = node->mName.C_Str();
|
||||||
|
|
||||||
@@ -317,3 +302,5 @@ void RawModel::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &b
|
|||||||
CreateSkeleton(boneInfo, boneNameMapping, child, parentID);
|
CreateSkeleton(boneInfo, boneNameMapping, child, parentID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,381 @@
|
|||||||
|
#include "Rendering/RawModelCustom.h"
|
||||||
|
|
||||||
|
#ifndef USING_ASSIMP_AS_IMPORTER
|
||||||
|
|
||||||
|
RawModelCustom::RawModelCustom(std::string fileName)
|
||||||
|
{
|
||||||
|
if(fileName.substr(fileName.find_last_of(".")).compare(".mesh") != 0) {
|
||||||
|
throw Resource::FailedLoadingException("Unknown model file format. Please use \".mesh\" files.");
|
||||||
|
}
|
||||||
|
fileName = fileName.erase(fileName.find_last_of("."), fileName.find_last_of(".") - fileName.size());
|
||||||
|
ReadMeshFile(fileName);
|
||||||
|
ReadMaterialFile(fileName);
|
||||||
|
ReadAnimationFile(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadMeshFile(std::string filePath)
|
||||||
|
{
|
||||||
|
char* fileData;
|
||||||
|
filePath += ".mesh";
|
||||||
|
std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate);
|
||||||
|
|
||||||
|
if (!in.is_open()) {
|
||||||
|
throw Resource::FailedLoadingException("Open mesh file failed");
|
||||||
|
}
|
||||||
|
unsigned int fileByteSize = in.tellg();
|
||||||
|
in.seekg(0, std::ios_base::beg);
|
||||||
|
|
||||||
|
fileData = new char[fileByteSize];
|
||||||
|
in.read(fileData, fileByteSize);
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
unsigned int offset = 0;
|
||||||
|
if (fileByteSize > 0) {
|
||||||
|
ReadMeshFileHeader(offset, fileData, fileByteSize);
|
||||||
|
ReadMesh(offset, fileData, fileByteSize);
|
||||||
|
}
|
||||||
|
delete fileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
|
||||||
|
{
|
||||||
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
m_Vertices.resize(*(unsigned int*)(fileData + offset));
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
m_Indices.resize(*(unsigned int*)(fileData + offset));
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
|
||||||
|
{
|
||||||
|
ReadVertices(offset, fileData, fileByteSize);
|
||||||
|
ReadIndices(offset, fileData, fileByteSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
|
||||||
|
{
|
||||||
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading vertices failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&m_Vertices[0], fileData + offset, m_Vertices.size() * sizeof(Vertex));
|
||||||
|
offset += m_Vertices.size() * sizeof(Vertex);
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
|
||||||
|
{
|
||||||
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
if (offset + m_Indices.size() * sizeof(unsigned int) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading indices failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&m_Indices[0], fileData + offset, m_Indices.size() * sizeof(unsigned int));
|
||||||
|
offset += m_Indices.size() * sizeof(unsigned int);
|
||||||
|
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadMaterialFile(std::string filePath)
|
||||||
|
{
|
||||||
|
char* fileData;
|
||||||
|
filePath += ".mtrl";
|
||||||
|
std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate);
|
||||||
|
|
||||||
|
if (!in.is_open()) {
|
||||||
|
throw Resource::FailedLoadingException("Open material file failed");
|
||||||
|
}
|
||||||
|
unsigned int fileByteSize = in.tellg();
|
||||||
|
in.seekg(0, std::ios_base::beg);
|
||||||
|
|
||||||
|
fileData = new char[fileByteSize];
|
||||||
|
in.read(fileData, fileByteSize);
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
unsigned int offset = 0;
|
||||||
|
if (fileByteSize > 0) {
|
||||||
|
ReadMaterials(offset, fileData, fileByteSize);
|
||||||
|
}
|
||||||
|
delete fileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadMaterials(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
|
||||||
|
{
|
||||||
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
unsigned int* numMaterials = (unsigned int*)(fileData);
|
||||||
|
MaterialGroups.reserve(*numMaterials);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
|
||||||
|
for (int i = 0; i < *numMaterials; i++) {
|
||||||
|
ReadMaterialSingle(offset, fileData, fileByteSize);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize)
|
||||||
|
{
|
||||||
|
MaterialGroup newMaterial;
|
||||||
|
|
||||||
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
if (offset + sizeof(unsigned int) * 4 > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Material texture names length failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int* nameLengths = (unsigned int*)(fileData + offset);
|
||||||
|
offset += sizeof(unsigned int) * 4;
|
||||||
|
|
||||||
|
if (offset + sizeof(float) * 11 + sizeof(unsigned int) * 2 > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Material specular, reflection, color and start and end index values failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
newMaterial.SpecularExponent = *(float*)(fileData + offset);
|
||||||
|
offset += sizeof(float);
|
||||||
|
newMaterial.ReflectionFactor = *(float*)(fileData + offset);
|
||||||
|
offset += sizeof(float);
|
||||||
|
|
||||||
|
memcpy(&newMaterial.DiffuseColor[0], fileData + offset, sizeof(float) * 3);
|
||||||
|
offset += sizeof(float) * 3;
|
||||||
|
memcpy(&newMaterial.SpecularColor[0], fileData + offset, sizeof(float) * 3);
|
||||||
|
offset += sizeof(float) * 3;
|
||||||
|
memcpy(&newMaterial.IncandescenceColor[0], fileData + offset, sizeof(float) * 3);
|
||||||
|
offset += sizeof(float) * 3;
|
||||||
|
|
||||||
|
newMaterial.StartIndex = *(unsigned int*)(fileData + offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
newMaterial.EndIndex = *(unsigned int*)(fileData + offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
|
||||||
|
if (nameLengths[0] > 0) {
|
||||||
|
if (offset + nameLengths[0] > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Material texture path failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
newMaterial.TexturePath = "Textures/";
|
||||||
|
newMaterial.TexturePath += (fileData + offset);
|
||||||
|
newMaterial.TexturePath += ".png";
|
||||||
|
offset += nameLengths[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nameLengths[1] > 0) {
|
||||||
|
if (offset + nameLengths[1] > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Material NormalMap path failed");
|
||||||
|
}
|
||||||
|
newMaterial.NormalMapPath = "Textures/";
|
||||||
|
newMaterial.NormalMapPath += (fileData + offset);
|
||||||
|
newMaterial.NormalMapPath += ".png";
|
||||||
|
offset += nameLengths[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nameLengths[2] > 0) {
|
||||||
|
if (offset + nameLengths[2] > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Material SpecularMap path failed");
|
||||||
|
}
|
||||||
|
newMaterial.SpecularMapPath = "Textures/";
|
||||||
|
newMaterial.SpecularMapPath += (fileData + offset);
|
||||||
|
newMaterial.SpecularMapPath += ".png";
|
||||||
|
offset += nameLengths[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nameLengths[3] > 0) {
|
||||||
|
if (offset + nameLengths[3] > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Material IncandescenceMap path failed");
|
||||||
|
}
|
||||||
|
newMaterial.IncandescenceMapPath = "Textures/";
|
||||||
|
newMaterial.IncandescenceMapPath += (fileData + offset);
|
||||||
|
newMaterial.IncandescenceMapPath += ".png";
|
||||||
|
offset += nameLengths[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
MaterialGroups.push_back(newMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadAnimationFile(std::string filePath)
|
||||||
|
{
|
||||||
|
char* fileData;
|
||||||
|
filePath += ".anim";
|
||||||
|
std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate);
|
||||||
|
|
||||||
|
if (!in.is_open()) {
|
||||||
|
//throw Resource::FailedLoadingException("Open animation file failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int fileByteSize = in.tellg();
|
||||||
|
in.seekg(0, std::ios_base::beg);
|
||||||
|
|
||||||
|
fileData = new char[fileByteSize];
|
||||||
|
in.read(fileData, fileByteSize);
|
||||||
|
in.close();
|
||||||
|
|
||||||
|
unsigned int offset = 0;
|
||||||
|
if (fileByteSize > 0) {
|
||||||
|
m_Skeleton = new Skeleton();
|
||||||
|
|
||||||
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
unsigned int numBindPoses = *(unsigned int*)(fileData);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
unsigned int numAnimations = *(unsigned int*)(fileData + offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ReadAnimationBindPoses(offset, fileData, fileByteSize);
|
||||||
|
ReadAnimationClips(offset, fileData, fileByteSize, numAnimations);
|
||||||
|
}
|
||||||
|
delete fileData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize)
|
||||||
|
{
|
||||||
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
unsigned int* numBones = (unsigned int*)(fileData + offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < *numBones; i++) {
|
||||||
|
ReadAnimationJoint(offset, fileData, fileByteSize);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize)
|
||||||
|
{
|
||||||
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
if (offset + sizeof(unsigned int) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Joint name length failed");
|
||||||
|
}
|
||||||
|
unsigned int jointNameLength = *(unsigned int*)(fileData + offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
|
||||||
|
if (offset + jointNameLength > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Joint name failed");
|
||||||
|
}
|
||||||
|
std::string jointName = (fileData + offset);
|
||||||
|
offset += jointNameLength;
|
||||||
|
|
||||||
|
if (offset + sizeof(float) * 4 * 4 > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Joint offset matrix failed");
|
||||||
|
}
|
||||||
|
glm::mat4 offsetMatrix;
|
||||||
|
memcpy(&offsetMatrix, fileData + offset, sizeof(float) * 4 * 4);
|
||||||
|
offset += sizeof(float) * 4 * 4;
|
||||||
|
|
||||||
|
if (offset + sizeof(int) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Joint ID failed");
|
||||||
|
}
|
||||||
|
int jointID = *(int*)(fileData + offset);
|
||||||
|
offset += sizeof(int);
|
||||||
|
|
||||||
|
if (offset + sizeof(int) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading Joint Parent ID failed");
|
||||||
|
}
|
||||||
|
int jointParentID = *(int*)(fileData + offset);
|
||||||
|
offset += sizeof(int);
|
||||||
|
|
||||||
|
// Adding joint to the Skeleton
|
||||||
|
m_Skeleton->CreateBone(jointID, jointParentID, jointName, offsetMatrix);
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < numberOfClips; i++) {
|
||||||
|
ReadAnimationClipSingle(offset, fileData, fileByteSize, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex)
|
||||||
|
{
|
||||||
|
#ifdef BOOST_LITTLE_ENDIAN
|
||||||
|
Skeleton::Animation newAnimation;
|
||||||
|
|
||||||
|
if (offset + sizeof(unsigned int) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading AnimationClip name length failed");
|
||||||
|
}
|
||||||
|
unsigned int clipNameLength = *(unsigned int*)(fileData + offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
|
||||||
|
if (offset + clipNameLength > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading AnimationClip name failed");
|
||||||
|
}
|
||||||
|
newAnimation.Name = (fileData + offset);
|
||||||
|
offset += clipNameLength;
|
||||||
|
|
||||||
|
if (offset + sizeof(float) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading AnimationClip duration failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
newAnimation.Duration = *(float*)(fileData + offset);
|
||||||
|
offset += sizeof(float);
|
||||||
|
|
||||||
|
if (offset + sizeof(unsigned int) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading AnimationClip NrOfKeyframes failed");
|
||||||
|
}
|
||||||
|
unsigned int nrOfKeyframes = *(unsigned int*)(fileData + offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
|
||||||
|
if (offset + sizeof(unsigned int) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading AnimationClip NrOfJoints failed");
|
||||||
|
}
|
||||||
|
unsigned int nrOfJoints = *(unsigned int*)(fileData + offset);
|
||||||
|
offset += sizeof(unsigned int);
|
||||||
|
|
||||||
|
newAnimation.Keyframes.reserve(nrOfKeyframes);
|
||||||
|
for (unsigned int i = 0; i < nrOfKeyframes; i++) {
|
||||||
|
ReadAnimationKeyFrame(offset, fileData, fileByteSize, nrOfJoints, newAnimation);
|
||||||
|
}
|
||||||
|
m_Skeleton->Animations[newAnimation.Name] = newAnimation;
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int nrOfJoints, Skeleton::Animation& animation)
|
||||||
|
{
|
||||||
|
Skeleton::Animation::Keyframe newKeyFrame;
|
||||||
|
|
||||||
|
if (offset + sizeof(int) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading AnimationKeyFrame index failed");
|
||||||
|
}
|
||||||
|
newKeyFrame.Index = *(int*)(fileData + offset);
|
||||||
|
offset += sizeof(int);
|
||||||
|
|
||||||
|
if (offset + sizeof(float) > fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading AnimationKeyFrame time failed");
|
||||||
|
}
|
||||||
|
newKeyFrame.Time = *(float*)(fileData + offset);
|
||||||
|
offset += sizeof(float);
|
||||||
|
|
||||||
|
if (offset + sizeof(Skeleton::Animation::Keyframe::BoneProperty) * nrOfJoints> fileByteSize) {
|
||||||
|
throw Resource::FailedLoadingException("Reading AnimationKeyFrame joints failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
Skeleton::Animation::Keyframe::BoneProperty newBone;
|
||||||
|
for (unsigned int i = 0; i < nrOfJoints; i++) {
|
||||||
|
memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty));
|
||||||
|
offset += sizeof(Skeleton::Animation::Keyframe::BoneProperty);
|
||||||
|
newKeyFrame.BoneProperties[newBone.ID] = newBone;
|
||||||
|
}
|
||||||
|
animation.Keyframes.push_back(newKeyFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
RawModelCustom::~RawModelCustom()
|
||||||
|
{
|
||||||
|
if (m_Skeleton != nullptr) {
|
||||||
|
delete m_Skeleton;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -7,6 +7,7 @@ RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRender
|
|||||||
{
|
{
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
|
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &RenderSystem::OnPlayerSpawned);
|
||||||
|
|
||||||
m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f);
|
m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f);
|
||||||
}
|
}
|
||||||
@@ -46,15 +47,22 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntityWrapper entity(m_World, modelComponent.EntityID);
|
||||||
|
|
||||||
|
// Don't render the local player
|
||||||
|
if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Model* model;
|
Model* model;
|
||||||
try {
|
try {
|
||||||
model = ResourceManager::Load<::Model, true>(resource);
|
model = ResourceManager::Load<::Model, true>(resource);
|
||||||
} catch (const Resource::StillLoadingException&) {
|
} catch (const Resource::StillLoadingException&) {
|
||||||
//continue;
|
//continue;
|
||||||
model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.obj");
|
model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.mesh");
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
try {
|
try {
|
||||||
model = ResourceManager::Load<::Model>("Models/Core/Error.obj");
|
model = ResourceManager::Load<::Model>("Models/Core/Error.mesh");
|
||||||
} catch (const std::exception&) {
|
} catch (const std::exception&) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -68,6 +76,14 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RenderSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||||
|
{
|
||||||
|
if (e.PlayerID == -1) {
|
||||||
|
m_LocalPlayer = e.Player;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderSystem::fillPointLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
|
void RenderSystem::fillPointLights(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
|
||||||
{
|
{
|
||||||
auto pointLights = m_World->GetComponents("PointLight");
|
auto pointLights = m_World->GetComponents("PointLight");
|
||||||
@@ -155,11 +171,12 @@ void RenderSystem::Update(double dt)
|
|||||||
{
|
{
|
||||||
m_EventBroker->Process<RenderSystem>();
|
m_EventBroker->Process<RenderSystem>();
|
||||||
|
|
||||||
if (m_CurrentCamera) {
|
// Update the current camera used for rendering
|
||||||
ComponentWrapper cameraTransform = m_CurrentCamera["Transform"];
|
if (m_CurrentCamera.Valid()) {
|
||||||
m_Camera->SetPosition(cameraTransform["Position"]);
|
m_Camera->SetPosition(Transform::AbsolutePosition(m_CurrentCamera));
|
||||||
m_Camera->SetOrientation(glm::quat((const glm::vec3&)cameraTransform["Orientation"]));
|
m_Camera->SetOrientation(Transform::AbsoluteOrientation(m_CurrentCamera));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Only supports opaque geometry atm
|
//Only supports opaque geometry atm
|
||||||
|
|
||||||
RenderScene scene;
|
RenderScene scene;
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ void Renderer::Initialize()
|
|||||||
m_TextPass->Initialize();
|
m_TextPass->Initialize();
|
||||||
|
|
||||||
|
|
||||||
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
/* m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
|
||||||
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
|
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
|
||||||
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");
|
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");*/
|
||||||
|
|
||||||
m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker);
|
m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ std::vector<glm::mat4> Skeleton::GetFrameBones(const Animation& animation, doubl
|
|||||||
|
|
||||||
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe ¤tFrame, const Animation::Keyframe &nextFrame, float progress, std::map<int, glm::mat4> &boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe ¤tFrame, const Animation::Keyframe &nextFrame, float progress, std::map<int, glm::mat4> &boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
|
||||||
{
|
{
|
||||||
glm::mat4 boneMatrix;
|
glm::mat4 boneMatrix;
|
||||||
|
|
||||||
if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() || nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) {
|
if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() || nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) {
|
||||||
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties.at(bone->ID);
|
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties.at(bone->ID);
|
||||||
@@ -84,10 +84,13 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf
|
|||||||
positionInterp.z = 0;
|
positionInterp.z = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp));
|
boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp));
|
||||||
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
|
||||||
} else {
|
} else {
|
||||||
boneMatrix = parentMatrix * bone->Parent->OffsetMatrix; // * glm::inverse(bone->OffsetMatrix);
|
if (bone->Parent) {
|
||||||
|
boneMatrix = parentMatrix; // * glm::inverse(bone->OffsetMatrix);
|
||||||
|
}
|
||||||
boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix;
|
boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +98,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf
|
|||||||
std::string name = child->Name;
|
std::string name = child->Name;
|
||||||
AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, progress, boneMatrices, child, boneMatrix);
|
AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, progress, boneMatrices, child, boneMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Skeleton::GetBoneID(std::string name)
|
int Skeleton::GetBoneID(std::string name)
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e)
|
|||||||
(float&)(double)emitter["RollOffFactor"] = e.RollOffFactor;
|
(float&)(double)emitter["RollOffFactor"] = e.RollOffFactor;
|
||||||
(float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance;
|
(float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance;
|
||||||
auto model = m_World->AttachComponent(emitterID, "Model");
|
auto model = m_World->AttachComponent(emitterID, "Model");
|
||||||
(std::string&)model["Resource"] = "Models/Core/UnitCube.obj";
|
(std::string&)model["Resource"] = "Models/Core/UnitCube.mesh"; // 360NoScope UnitCube
|
||||||
source->Type = SoundType::SFX;
|
source->Type = SoundType::SFX;
|
||||||
m_Sources[emitterID] = source;
|
m_Sources[emitterID] = source;
|
||||||
playSound(source);
|
playSound(source);
|
||||||
|
|||||||
+2
-2
@@ -57,7 +57,7 @@ Game::Game(int argc, char* argv[])
|
|||||||
m_FrameStack->Height = m_Renderer->Resolution().Height;
|
m_FrameStack->Height = m_Renderer->Resolution().Height;
|
||||||
|
|
||||||
// Create a world
|
// Create a world
|
||||||
m_World = new World();
|
m_World = new World(m_EventBroker);
|
||||||
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
|
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
|
||||||
if (!mapToLoad.empty()) {
|
if (!mapToLoad.empty()) {
|
||||||
auto file = ResourceManager::Load<EntityFile>(mapToLoad);
|
auto file = ResourceManager::Load<EntityFile>(mapToLoad);
|
||||||
@@ -77,7 +77,7 @@ Game::Game(int argc, char* argv[])
|
|||||||
// All systems with orderlevel 0 will be updated first.
|
// All systems with orderlevel 0 will be updated first.
|
||||||
unsigned int updateOrderLevel = 0;
|
unsigned int updateOrderLevel = 0;
|
||||||
m_SystemPipeline->AddSystem<RaptorCopterSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<RaptorCopterSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel);
|
//m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ HealthSystem::HealthSystem(World* m_World, EventBroker* eventBroker)
|
|||||||
void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
void HealthSystem::UpdateComponent(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)
|
//if entityID of health is 9 then the players ID is also 9 (player,health are connected to the same entity)
|
||||||
ComponentWrapper player = m_World->GetComponent(component.EntityID, "Player");
|
|
||||||
double maxHealth = (double)component["MaxHealth"];
|
double maxHealth = (double)component["MaxHealth"];
|
||||||
|
|
||||||
//process the DeltaHealthVector and change the entitys health accordingly
|
//process the DeltaHealthVector and change the entitys health accordingly
|
||||||
@@ -49,7 +48,7 @@ void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& comp
|
|||||||
bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e)
|
bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e)
|
||||||
{
|
{
|
||||||
//save the changed HP to a vector. it will be taken care of in UpdateComponent
|
//save the changed HP to a vector. it will be taken care of in UpdateComponent
|
||||||
m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerDamagedID, -e.DamageAmount));
|
//m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerDamagedID, -e.DamageAmount));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +1,30 @@
|
|||||||
#include "Systems/InterpolationSystem.h"
|
#include "Systems/InterpolationSystem.h"
|
||||||
|
|
||||||
//void InterpolationSystem::UpdateComponent(World * world, ComponentWrapper & transform, double dt)
|
InterpolationSystem::InterpolationSystem(World* world, EventBroker* eventBroker)
|
||||||
//{
|
: System(world, eventBroker)
|
||||||
// if (m_InterpolationPoints[transform.EntityID].size() > 0) {
|
, PureSystem("Transform")
|
||||||
// Transform& sTransform = m_InterpolationPoints[transform.EntityID].front();
|
{
|
||||||
// sTransform.interpolationTime += dt;
|
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
|
||||||
// if (sTransform.interpolationTime > 0.05) {
|
m_SnapshotInterval = config->Get<float>("Networking.SnapshotInterval", 0.05);
|
||||||
// double time = std::fmod(sTransform.interpolationTime, 0.05f);
|
EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate);
|
||||||
// m_InterpolationPoints[transform.EntityID].pop();
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &InterpolationSystem::OnPlayerSpawned);
|
||||||
// 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(EntityWrapper& entity, ComponentWrapper& transform, double dt)
|
void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt)
|
||||||
{
|
{
|
||||||
|
// Don't interpolate entities that might already have been removed
|
||||||
|
if (!entity.Valid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map
|
if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map
|
||||||
m_NextTransform[transform.EntityID].interpolationTime += dt;
|
m_NextTransform[transform.EntityID].interpolationTime += dt;
|
||||||
Transform sTransform = m_NextTransform[transform.EntityID];
|
Transform sTransform = m_NextTransform[transform.EntityID];
|
||||||
double time = sTransform.interpolationTime;
|
double time = sTransform.interpolationTime;
|
||||||
if (time > SNAPSHOTINTERVAL) {
|
if (time > m_SnapshotInterval) {
|
||||||
if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) {
|
if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) {
|
||||||
m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID];
|
m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID];
|
||||||
m_NextTransform[transform.EntityID].interpolationTime = time - SNAPSHOTINTERVAL;
|
m_NextTransform[transform.EntityID].interpolationTime = time - m_SnapshotInterval;
|
||||||
sTransform = m_NextTransform[transform.EntityID];
|
sTransform = m_NextTransform[transform.EntityID];
|
||||||
m_LastReceivedTransform.erase(transform.EntityID);
|
m_LastReceivedTransform.erase(transform.EntityID);
|
||||||
} else {
|
} else {
|
||||||
@@ -37,14 +32,21 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (transform.Info.Name == "Transform") {
|
if (transform.Info.Name == "Transform") {
|
||||||
|
bool isLocalPlayer = entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer);
|
||||||
// Position
|
// Position
|
||||||
glm::vec3 nextPosition = sTransform.Position;
|
glm::vec3 nextPosition = sTransform.Position;
|
||||||
glm::vec3 currentPosition = static_cast<glm::vec3>(transform["Position"]);
|
glm::vec3 currentPosition = static_cast<glm::vec3>(transform["Position"]);
|
||||||
(glm::vec3&)transform["Position"] += vectorInterpolation<glm::vec3>(currentPosition, nextPosition, sTransform.interpolationTime);
|
// HACK: Don't force position for players
|
||||||
|
if (!isLocalPlayer) {
|
||||||
|
(glm::vec3&)transform["Position"] += vectorInterpolation<glm::vec3>(currentPosition, nextPosition, sTransform.interpolationTime);
|
||||||
|
}
|
||||||
// Orientation
|
// Orientation
|
||||||
glm::quat nextOrientation = sTransform.Orientation;
|
// Don't force orientation for players
|
||||||
glm::quat currentOrientation = glm::quat(static_cast<glm::vec3>(transform["Orientation"]));
|
if (!isLocalPlayer) {
|
||||||
(glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp<float>(currentOrientation, nextOrientation, sTransform.interpolationTime / SNAPSHOTINTERVAL));
|
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 / m_SnapshotInterval));
|
||||||
|
}
|
||||||
// Scale
|
// Scale
|
||||||
glm::vec3 nextScale = sTransform.Scale;
|
glm::vec3 nextScale = sTransform.Scale;
|
||||||
glm::vec3 currentScale = static_cast<glm::vec3>(transform["Scale"]);
|
glm::vec3 currentScale = static_cast<glm::vec3>(transform["Scale"]);
|
||||||
@@ -53,6 +55,12 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InterpolationSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||||
|
{
|
||||||
|
m_LocalPlayer = e.Player;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e)
|
bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e)
|
||||||
{
|
{
|
||||||
Transform transform;
|
Transform transform;
|
||||||
@@ -72,15 +80,5 @@ bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e)
|
|||||||
} else { // Did not
|
} else { // Did not
|
||||||
m_NextTransform[e.Entity] = transform;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,132 @@
|
|||||||
#include "Systems/PlayerMovementSystem.h"
|
#include "Systems/PlayerMovementSystem.h"
|
||||||
|
|
||||||
|
PlayerMovementSystem::PlayerMovementSystem(World* world, EventBroker* eventBroker)
|
||||||
|
: System(world, eventBroker)
|
||||||
|
, PureSystem("Player")
|
||||||
|
{
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &PlayerMovementSystem::OnPlayerSpawned);
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerMovementSystem::~PlayerMovementSystem()
|
||||||
|
{
|
||||||
|
for (auto& kv : m_PlayerInputControllers) {
|
||||||
|
delete kv.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerMovementSystem::Update(double dt)
|
||||||
|
{
|
||||||
|
for (auto& kv : m_PlayerInputControllers) {
|
||||||
|
EntityWrapper player = kv.first;
|
||||||
|
auto& controller = kv.second;
|
||||||
|
|
||||||
|
if (!player.Valid()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityWrapper cameraEntity = player.FirstChildByName("Camera");
|
||||||
|
if (cameraEntity.Valid()) {
|
||||||
|
glm::vec3& cameraOrientation = cameraEntity["Transform"]["Orientation"];
|
||||||
|
cameraOrientation.x += controller->Rotation().x;
|
||||||
|
// Limit camera pitch so we don't break our necks
|
||||||
|
cameraOrientation.x = glm::clamp(cameraOrientation.x, -glm::half_pi<float>(), glm::half_pi<float>());
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentWrapper& cTransform = player["Transform"];
|
||||||
|
glm::vec3& ori = cTransform["Orientation"];
|
||||||
|
ori.y += controller->Rotation().y;
|
||||||
|
|
||||||
|
if (player.HasComponent("Physics")) {
|
||||||
|
ComponentWrapper cPhysics = player["Physics"];
|
||||||
|
|
||||||
|
glm::vec3 wishDirection = controller->Movement() * glm::inverse(glm::quat(ori));
|
||||||
|
float wishSpeed;
|
||||||
|
if (controller->Crouching()) {
|
||||||
|
wishSpeed = player["Player"]["CrouchSpeed"];
|
||||||
|
} else {
|
||||||
|
wishSpeed = player["Player"]["MovementSpeed"];
|
||||||
|
}
|
||||||
|
glm::vec3& velocity = cPhysics["Velocity"];
|
||||||
|
ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z);
|
||||||
|
glm::vec3 groundVelocity(0.f, 0.f, 0.f);
|
||||||
|
groundVelocity.x = glm::dot(velocity, glm::vec3(1.f, 0.f, 0.f));
|
||||||
|
groundVelocity.z = glm::dot(velocity, glm::vec3(0.f, 0.f, 1.f));
|
||||||
|
ImGui::Text("groundVelocity: (%f, %f, %f) |%f|", groundVelocity.x, groundVelocity.y, groundVelocity.z, glm::length(wishDirection));
|
||||||
|
ImGui::Text("wishDirection: (%f, %f, %f) |%f|", wishDirection.x, wishDirection.y, wishDirection.z, glm::length(wishDirection));
|
||||||
|
float currentSpeedProj = glm::dot(groundVelocity, wishDirection);
|
||||||
|
float addSpeed = wishSpeed - currentSpeedProj;
|
||||||
|
ImGui::Text("currentSpeedProj: %f", currentSpeedProj);
|
||||||
|
ImGui::Text("wishSpeed: %f", wishSpeed);
|
||||||
|
ImGui::Text("addSpeed: %f", addSpeed);
|
||||||
|
|
||||||
|
if (addSpeed > 0) {
|
||||||
|
static float accel = 15.f;
|
||||||
|
ImGui::InputFloat("accel", &accel);
|
||||||
|
static float airAccel = 0.5f;
|
||||||
|
ImGui::InputFloat("airAccel", &airAccel);
|
||||||
|
float actualAccel = (velocity.y != 0) ? airAccel : accel;
|
||||||
|
static float surfaceFriction = 5.f;
|
||||||
|
ImGui::InputFloat("surfaceFriction", &surfaceFriction);
|
||||||
|
float accelerationSpeed = actualAccel * (float)dt * wishSpeed * surfaceFriction;
|
||||||
|
accelerationSpeed = glm::min(accelerationSpeed, addSpeed);
|
||||||
|
velocity += accelerationSpeed * wishDirection;
|
||||||
|
ImGui::Text("velocity: (%f, %f, %f) |%f|", velocity.x, velocity.y, velocity.z, glm::length(velocity));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (controller->Jumping() && !controller->Crouching() && velocity.y == 0.f) {
|
||||||
|
velocity.y += 4.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (player.HasComponent("AABB")) {
|
||||||
|
// glm::vec3& size = player["AABB"]["Size"];
|
||||||
|
// if (controller->Crouching()) {
|
||||||
|
// size = glm::vec3(1.f, 1.f, 1.f);
|
||||||
|
// } else {
|
||||||
|
// size = glm::vec3(1.f, 1.6f, 1.f);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
controller->Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
void PlayerMovementSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
|
||||||
{
|
{
|
||||||
ComponentWrapper& cTransform = entity["Transform"];
|
ComponentWrapper& cTransform = entity["Transform"];
|
||||||
if (!entity.HasComponent("Physics")) {
|
if (!entity.HasComponent("Physics")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ComponentWrapper& cPhysics = entity["Physics"];
|
|
||||||
|
|
||||||
|
ComponentWrapper& cPhysics = entity["Physics"];
|
||||||
glm::vec3& velocity = cPhysics["Velocity"];
|
glm::vec3& velocity = cPhysics["Velocity"];
|
||||||
|
|
||||||
|
// Ground friction
|
||||||
|
float speed = glm::length(velocity);
|
||||||
|
static float groundFriction = 7.f;
|
||||||
|
ImGui::InputFloat("groundFriction", &groundFriction);
|
||||||
|
static float airFriction = 0.f;
|
||||||
|
ImGui::InputFloat("airFriction", &airFriction);
|
||||||
|
float friction = (velocity.y != 0) ? airFriction : groundFriction;
|
||||||
|
if (speed > 0) {
|
||||||
|
float drop = speed * friction * (float)dt;
|
||||||
|
float multiplier = glm::max(speed - drop, 0.f) / speed;
|
||||||
|
velocity.x *= multiplier;
|
||||||
|
velocity.z *= multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
if (cPhysics["Gravity"]) {
|
if (cPhysics["Gravity"]) {
|
||||||
velocity.y -= 9.82 * dt;
|
velocity.y -= 9.82f * (float)dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3& position = cTransform["Position"];
|
glm::vec3& position = cTransform["Position"];
|
||||||
position += velocity * (float)dt;
|
position += velocity * (float)dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PlayerMovementSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||||
|
{
|
||||||
|
// When a player spawns, create an input controller for them
|
||||||
|
m_PlayerInputControllers[e.Player] = new FirstPersonInputController<PlayerMovementSystem>(m_EventBroker, e.PlayerID);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ PlayerSpawnSystem::PlayerSpawnSystem(World* m_World, EventBroker* eventBroker)
|
|||||||
: System(m_World, eventBroker)
|
: System(m_World, eventBroker)
|
||||||
{
|
{
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand);
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerSpawnerd, &PlayerSpawnSystem::OnPlayerSpawned);
|
||||||
|
m_NetworkEnabled = ResourceManager::Load<ConfigFile>("Config.ini")->Get("Networking.StartNetwork", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerSpawnSystem::Update(double dt)
|
void PlayerSpawnSystem::Update(double dt)
|
||||||
@@ -13,7 +15,7 @@ void PlayerSpawnSystem::Update(double dt)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& team : m_SpawnRequests) {
|
for (auto& req : m_SpawnRequests) {
|
||||||
for (auto& cPlayerSpawn : *playerSpawns) {
|
for (auto& cPlayerSpawn : *playerSpawns) {
|
||||||
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
|
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
|
||||||
if (!spawner.HasComponent("Spawner")) {
|
if (!spawner.HasComponent("Spawner")) {
|
||||||
@@ -22,7 +24,7 @@ void PlayerSpawnSystem::Update(double dt)
|
|||||||
|
|
||||||
// If the spawner has a team affiliation, check it
|
// If the spawner has a team affiliation, check it
|
||||||
if (spawner.HasComponent("Team")) {
|
if (spawner.HasComponent("Team")) {
|
||||||
if ((int)spawner["Team"]["Team"] != team) {
|
if ((int)spawner["Team"]["Team"] != req.Team) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,7 +32,15 @@ void PlayerSpawnSystem::Update(double dt)
|
|||||||
// Spawn the player!
|
// Spawn the player!
|
||||||
EntityWrapper player = SpawnerSystem::Spawn(spawner);
|
EntityWrapper player = SpawnerSystem::Spawn(spawner);
|
||||||
// Set the player team affiliation
|
// Set the player team affiliation
|
||||||
player["Team"]["Team"] = team;
|
player["Team"]["Team"] = req.Team;
|
||||||
|
|
||||||
|
// Publish a PlayerSpawned event
|
||||||
|
Events::PlayerSpawned e;
|
||||||
|
e.PlayerID = req.PlayerID;
|
||||||
|
e.Player = player;
|
||||||
|
e.Spawner = spawner;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_SpawnRequests.clear();
|
m_SpawnRequests.clear();
|
||||||
@@ -42,10 +52,60 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Team picks should be processed ONLY server-side!
|
||||||
|
// Don't make a spawn request if PlayerID is -1, i.e. we're the client.
|
||||||
|
if (e.PlayerID == -1 && m_NetworkEnabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.Value != 0) {
|
if (e.Value != 0) {
|
||||||
m_SpawnRequests.push_back((int)e.Value);
|
SpawnRequest req;
|
||||||
|
req.PlayerID = e.PlayerID;
|
||||||
|
req.Team = (ComponentInfo::EnumType)e.Value;
|
||||||
|
m_SpawnRequests.push_back(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||||
|
{
|
||||||
|
// When a player is actually spawned (since the actual spawning is handled on the server)
|
||||||
|
|
||||||
|
// Check if a player already exists
|
||||||
|
if (m_PlayerEntities.count(e.PlayerID) != 0) {
|
||||||
|
// TODO: Disallow infinite respawning here
|
||||||
|
m_World->DeleteEntity(m_PlayerEntities[e.PlayerID].ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the player for future reference
|
||||||
|
m_PlayerEntities[e.PlayerID] = e.Player;
|
||||||
|
|
||||||
|
// Set the camera to the correct entity
|
||||||
|
EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera");
|
||||||
|
if (cameraEntity.Valid()) {
|
||||||
|
Events::SetCamera e;
|
||||||
|
e.CameraEntity = cameraEntity;
|
||||||
|
m_EventBroker->Publish(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// HACK: Set the player model color to team color
|
||||||
|
EntityWrapper playerModel = e.Player.FirstChildByName("PlayerModel");
|
||||||
|
if (playerModel.Valid() && e.Player.HasComponent("Team")) {
|
||||||
|
ComponentWrapper cTeam = e.Player["Team"];
|
||||||
|
ComponentWrapper cModel = playerModel["Model"];
|
||||||
|
if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Red")) {
|
||||||
|
cModel["Color"] = glm::vec3(1.f, 0.f, 0.f);
|
||||||
|
} else if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Blue")) {
|
||||||
|
cModel["Color"] = glm::vec3(0.f, 0.25f, 1.f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Set the player name to whatever
|
||||||
|
//EntityWrapper playerName = e.Player.FirstChildByName("PlayerName");
|
||||||
|
//if (playerName.Valid()) {
|
||||||
|
// playerName["Text"]["Content"] = ???;
|
||||||
|
//}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -5,49 +5,80 @@ WeaponSystem::WeaponSystem(World* world, EventBroker* eventBroker, IRenderer* re
|
|||||||
, ImpureSystem()
|
, ImpureSystem()
|
||||||
, m_Renderer(renderer)
|
, m_Renderer(renderer)
|
||||||
{
|
{
|
||||||
|
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &WeaponSystem::OnPlayerSpawned);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot);
|
EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeaponSystem::Update(double dt)
|
void WeaponSystem::Update(double dt)
|
||||||
{
|
{
|
||||||
for (int i = m_EShootVector.size(); i > 0; i--)
|
|
||||||
{
|
|
||||||
//TODO: check if player has enough ammo and if weapon has a cooldown or not
|
|
||||||
|
|
||||||
//pick the object
|
}
|
||||||
PickData pickDataFromShot = m_Renderer->Pick(std::get<1>(m_EShootVector[i - 1]));
|
|
||||||
if (pickDataFromShot.Entity == EntityID_Invalid) {
|
bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e)
|
||||||
m_EShootVector.erase(m_EShootVector.begin() + i - 1);
|
{
|
||||||
continue;
|
if (e.PlayerID == -1) {
|
||||||
}
|
m_LocalPlayer = e.Player;
|
||||||
//if its a player, do PlayerDamage event
|
|
||||||
const bool hasPlayerComponent = m_World->HasComponent(pickDataFromShot.Entity, "Player");
|
|
||||||
if (hasPlayerComponent) {
|
|
||||||
Events::PlayerDamage ePlayerDamage;
|
|
||||||
//TODO: damage based on weapontype/class?
|
|
||||||
//TODO: multiple shots at the same time? (shotgunner)
|
|
||||||
ePlayerDamage.DamageAmount = 25;
|
|
||||||
ePlayerDamage.PlayerDamagedID = pickDataFromShot.Entity;
|
|
||||||
m_EventBroker->Publish(ePlayerDamage);
|
|
||||||
}
|
|
||||||
m_EShootVector.erase(m_EShootVector.begin() + i - 1);
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e)
|
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e)
|
||||||
{
|
{
|
||||||
|
// Only shoot client-side!
|
||||||
|
if (e.PlayerID != -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only shoot if the player is alive
|
||||||
|
if (!m_LocalPlayer.Valid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (e.Command == "PrimaryFire" && e.Value > 0) {
|
if (e.Command == "PrimaryFire" && e.Value > 0) {
|
||||||
Events::Shoot eShoot;
|
Events::Shoot eShoot;
|
||||||
eShoot.shooter = e.PlayerID;
|
eShoot.Player = m_LocalPlayer;
|
||||||
m_EventBroker->Publish(eShoot);
|
m_EventBroker->Publish(eShoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool WeaponSystem::OnShoot(const Events::Shoot& e) {
|
|
||||||
//screen center, based on current resolution!
|
bool WeaponSystem::OnShoot(const Events::Shoot& eShoot) {
|
||||||
|
// Screen center, based on current resolution!
|
||||||
|
//TODO: check if player has enough ammo and if weapon has a cooldown or not
|
||||||
Rectangle screenResolution = m_Renderer->Resolution();
|
Rectangle screenResolution = m_Renderer->Resolution();
|
||||||
glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2);
|
glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2);
|
||||||
m_EShootVector.push_back(std::make_pair(e.shooter, centerScreen));
|
|
||||||
|
// TODO: check if player has enough ammo and if weapon has a cooldown or not
|
||||||
|
|
||||||
|
// Pick middle of screen
|
||||||
|
PickData pickData = m_Renderer->Pick(centerScreen);
|
||||||
|
if (pickData.Entity == EntityID_Invalid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityWrapper player(m_World, pickData.Entity);
|
||||||
|
|
||||||
|
// Only care about players being hit
|
||||||
|
if (!player.HasComponent("Player")) {
|
||||||
|
player = player.FirstParentWithComponent("Player");
|
||||||
|
}
|
||||||
|
if (!player.Valid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for friendly fire
|
||||||
|
EntityWrapper shooter = eShoot.Player;
|
||||||
|
if ((ComponentInfo::EnumType)player["Team"]["Team"] == (ComponentInfo::EnumType)shooter["Team"]["Team"]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Weapon damage calculations etc
|
||||||
|
Events::PlayerDamage ePlayerDamage;
|
||||||
|
ePlayerDamage.Player = player;
|
||||||
|
ePlayerDamage.Damage = 100;
|
||||||
|
m_EventBroker->Publish(ePlayerDamage);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ using boost::unit_test_framework::test_case;
|
|||||||
void RayTest(std::string fileName) {
|
void RayTest(std::string fileName) {
|
||||||
//simple box test
|
//simple box test
|
||||||
Ray ray(glm::vec3(-50, 0, 0), glm::vec3(1, 0, 0));
|
Ray ray(glm::vec3(-50, 0, 0), glm::vec3(1, 0, 0));
|
||||||
//using a rawmodel here, else we have to init the renderingsystem
|
//using a
|
||||||
|
|
||||||
|
//here, else we have to init the renderingsystem
|
||||||
ResourceManager::RegisterType<RawModel>("RawModel");
|
ResourceManager::RegisterType<RawModel>("RawModel");
|
||||||
auto unitBox = ResourceManager::Load<RawModel>(fileName);
|
auto unitBox = ResourceManager::Load<RawModel>(fileName);
|
||||||
BOOST_REQUIRE(unitBox != nullptr);
|
BOOST_REQUIRE(unitBox != nullptr);
|
||||||
@@ -106,7 +108,7 @@ BOOST_AUTO_TEST_CASE(collisionTest2)
|
|||||||
BOOST_AUTO_TEST_CASE(rayVsModelTest)
|
BOOST_AUTO_TEST_CASE(rayVsModelTest)
|
||||||
{
|
{
|
||||||
//simple box test
|
//simple box test
|
||||||
RayTest("Models/Core/UnitCube.obj");
|
RayTest("Models/Core/UnitCube.mesh"); // 360NoScope Unitcube
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
||||||
@@ -128,7 +130,7 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
|||||||
someAABB = AABB(minPos, maxPos);
|
someAABB = AABB(minPos, maxPos);
|
||||||
//using a rawmodel here, else we have to init the renderingsystem
|
//using a rawmodel here, else we have to init the renderingsystem
|
||||||
ResourceManager::RegisterType<RawModel>("RawModel");
|
ResourceManager::RegisterType<RawModel>("RawModel");
|
||||||
auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitCube.obj");
|
auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitCube.mesh"); // 360NoScope unitcube
|
||||||
BOOST_CHECK(unitBox != nullptr);
|
BOOST_CHECK(unitBox != nullptr);
|
||||||
|
|
||||||
for (size_t i = 0; i < 1000000; i++)
|
for (size_t i = 0; i < 1000000; i++)
|
||||||
@@ -187,19 +189,19 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
|
|||||||
BOOST_AUTO_TEST_CASE(rayVsModelTest3)
|
BOOST_AUTO_TEST_CASE(rayVsModelTest3)
|
||||||
{
|
{
|
||||||
//simple test
|
//simple test
|
||||||
RayTest("Models/Core/UnitSphere.obj");
|
RayTest("Models/Core/UnitSphere.mesh"); // 360NoScope unitSphere
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rayVsModelTest4)
|
BOOST_AUTO_TEST_CASE(rayVsModelTest4)
|
||||||
{
|
{
|
||||||
//simple test
|
//simple test
|
||||||
RayTest("Models/Core/UnitCylinder.obj");
|
RayTest("Models/Core/UnitCylinder.mesh"); // 360NoScope unitCylinder
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(rayVsModelTest5)
|
BOOST_AUTO_TEST_CASE(rayVsModelTest5)
|
||||||
{
|
{
|
||||||
//simple test
|
//simple test
|
||||||
RayTest("Models/Core/UnitRaptor.obj");
|
RayTest("Models/Core/UnitRaptor.mesh"); // 360NoScope unitRaptor
|
||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_CASE(octTest)
|
BOOST_AUTO_TEST_CASE(octTest)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ GameHealthSystemTest::GameHealthSystemTest()
|
|||||||
EntityID playerID = m_World->CreateEntity();
|
EntityID playerID = m_World->CreateEntity();
|
||||||
ComponentWrapper transform = m_World->AttachComponent(playerID, "Transform");
|
ComponentWrapper transform = m_World->AttachComponent(playerID, "Transform");
|
||||||
ComponentWrapper model = m_World->AttachComponent(playerID, "Model");
|
ComponentWrapper model = m_World->AttachComponent(playerID, "Model");
|
||||||
model["Resource"] = "Models/Core/UnitSphere.obj";
|
model["Resource"] = "Models/Core/UnitSphere.mesh"; // 360NoScope UnitSphere
|
||||||
ComponentWrapper player = m_World->AttachComponent(playerID, "Player");
|
ComponentWrapper player = m_World->AttachComponent(playerID, "Player");
|
||||||
ComponentWrapper health = m_World->AttachComponent(playerID, "Health");
|
ComponentWrapper health = m_World->AttachComponent(playerID, "Health");
|
||||||
healthsID = playerID;
|
healthsID = playerID;
|
||||||
@@ -69,8 +69,8 @@ GameHealthSystemTest::GameHealthSystemTest()
|
|||||||
m_EventBroker->Publish(e3);
|
m_EventBroker->Publish(e3);
|
||||||
//damage player with 50
|
//damage player with 50
|
||||||
Events::PlayerDamage e;
|
Events::PlayerDamage e;
|
||||||
e.DamageAmount = 50.0f;
|
e.Damage = 50.0f;
|
||||||
e.PlayerDamagedID = healthsID;
|
//e.Player = healthsID;
|
||||||
m_EventBroker->Publish(e);
|
m_EventBroker->Publish(e);
|
||||||
//heal some other player with 40
|
//heal some other player with 40
|
||||||
Events::PlayerHealthPickup e2;
|
Events::PlayerHealthPickup e2;
|
||||||
@@ -81,7 +81,7 @@ GameHealthSystemTest::GameHealthSystemTest()
|
|||||||
EntityID playerID2 = m_World->CreateEntity();
|
EntityID playerID2 = m_World->CreateEntity();
|
||||||
ComponentWrapper transform2 = m_World->AttachComponent(playerID2, "Transform");
|
ComponentWrapper transform2 = m_World->AttachComponent(playerID2, "Transform");
|
||||||
ComponentWrapper model2 = m_World->AttachComponent(playerID2, "Model");
|
ComponentWrapper model2 = m_World->AttachComponent(playerID2, "Model");
|
||||||
model2["Resource"] = "Models/Core/UnitSphere.obj";
|
model2["Resource"] = "Models/Core/UnitSphere.mesh"; // 360NoScope UnitSphere
|
||||||
ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player");
|
ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player");
|
||||||
ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health");
|
ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health");
|
||||||
//END TEST
|
//END TEST
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user