Compare commits

...

88 Commits

Author SHA1 Message Date
Jocke ac0c6ff952 WIP started on reliable messages 2016-01-27 18:22:28 +01:00
stiffly 06f64f8fbf Added a player name to the PlayerSpawned event. When a player has spawned the server sends the name to the client which publishes the event. 2016-01-24 22:00:38 +01:00
Jace 0c56a05144 Merge branch 'master' of github.com:teamfisk/TacticalZ
# Conflicts:
#	resources/Schema/Entities/Player.xml
#	src/Engine/Network/Server.cpp
2016-01-24 21:21:51 +01:00
Jace 382eff169f Server refactoring to remove player dependency and lots of fixes. 2016-01-24 21:20:43 +01:00
Tleety d4797b0808 Some entity files 2016-01-24 21:08:01 +01:00
Jace 25890c8d6c Merge remote-tracking branch 'origin/Networking' 2016-01-24 19:01:15 +01:00
Jace 0fb1dbcae1 Client now has authority over its own absolute position and orientation until we have reliable input messaging 2016-01-24 19:00:50 +01:00
Jace 9f3d887ac4 Networking bugfixes 2016-01-24 18:37:36 +01:00
Jace b4081b3e45 Merge remote-tracking branch 'origin/Networking'
# Conflicts:
#	src/Engine/Network/Client.cpp
#	src/Game/Systems/WeaponSystem.cpp
2016-01-24 18:36:37 +01:00
stiffly 8d61632c26 No longer spawns a f**king sphere. 2016-01-24 17:40:43 +01:00
stiffly 2eaad2aa00 Client now responds to deleted entity and component in server 2016-01-24 17:16:26 +01:00
Jace 235b26ad61 WIP shoot 2016-01-24 17:16:18 +01:00
Viktor Ljung f80fb5eda8 Merge pull request #52 from teamfisk/Importer
Importer
2016-01-24 17:05:02 +01:00
antc13 aa115befa9 UnitRaptor is now displayed while models are being loaded in. 2016-01-24 17:04:12 +01:00
antc13 aa20b48188 Merge remote-tracking branch 'origin/master' into Importer
# Conflicts:
#	resources/Schema/Entities/MovementTest.xml
#	resources/Schema/Entities/Player.xml
2016-01-24 16:22:22 +01:00
antc13 96a735c542 Changed .obj to .mesh for all meshes. 2016-01-24 16:12:31 +01:00
Jace 3261e21d96 Coloring players depending on team and created a blue spawn in MovementTest 2016-01-24 15:46:01 +01:00
antc13 666f1fd878 Removed temp variables & the "forced" animation in DrawFinalPass 2016-01-24 15:30:20 +01:00
Jace 373bb33cf0 Player jumping taking air acceleration into account 2016-01-24 15:20:34 +01:00
antc13 4c5d17b203 Merge remote-tracking branch 'origin/master' into Importer
# Conflicts:
#	resources/Schema/Entities/RenderingWorld.xml
#	resources/Shaders/ForwardPlus.frag.glsl
#	src/Engine/Editor/EditorSystem.cpp
#	src/Engine/Network/Server.cpp
#	src/Engine/Rendering/DrawFinalPass.cpp
#	src/Tests/OctTreeTestGameClass.cpp
#	src/Tests/OctTreeTestHardCodedTestWorld.h
#	src/Tests/ResourceManagerTest.cpp
2016-01-24 14:40:52 +01:00
antc13 8286d052b3 Changed color values from floats to glm::vec4 2016-01-24 14:38:17 +01:00
Jace aaa11d2109 Merge remote-tracking branch 'origin/master' into PlayerMovement 2016-01-24 14:18:23 +01:00
Jace 67477ff3ae EEntityDeleted and EComponentDeleted events published by World 2016-01-24 13:49:45 +01:00
antc13 b5b1140f5c Custom Animations should now work. We also save color values if there's no texture. 2016-01-24 13:28:40 +01:00
Jocke 7567f47a68 Weapon system now searches parents for health component (stops at first health component). 2016-01-24 11:56:46 +01:00
Jocke 97d70f8e32 Fixed in client for shoot event. Weapon system now damages health on any target not only players. 2016-01-24 11:36:01 +01:00
antc13 3baa988ad4 Changed .obj files to our own format. DummyScene.mesh may be broken. 2016-01-23 20:35:58 +01:00
Jace 1ce9128da8 Source-like movement 2016-01-23 19:45:23 +01:00
stiffly a28748b35d Merge remote-tracking branch 'origin/master' into Networking 2016-01-23 18:42:16 +01:00
Viktor Ljung 132de88d28 Merge pull request #50 from teamfisk/Forward+
Forward+
2016-01-23 18:23:16 +01:00
antc13 f1835fd89c Animations PROBABLY works fine if all joints got keyframes. 2016-01-23 18:02:42 +01:00
stiffly ecdb5ed07d Merge remote-tracking branch 'origin/master' into Networking 2016-01-23 17:51:06 +01:00
Jocke 6d2c656a04 Merge remote-tracking branch 'origin/Networking' into Networking 2016-01-23 16:41:42 +01:00
Jocke 2bf0434bcb Remade Snapshot logic from component based to entity based. 2016-01-23 16:40:38 +01:00
Jace 666ef6589e Crouching! 2016-01-23 15:06:47 +01:00
Jace b83d773627 Infinite respawning for now 2016-01-23 15:06:41 +01:00
Jace 482689fd48 fixup! Moved FirstPersonInputController implementation out of header 2016-01-23 12:16:40 +01:00
Jace 32f73201c5 Basic jumping! 2016-01-23 12:15:33 +01:00
Jace 3aeeb3cad5 Moved FirstPersonInputController implementation out of header 2016-01-23 12:15:32 +01:00
Jace 4d5cbb6057 fixup! Added EntityWrapper::IsChildOf and made snapshot interpolation and rendering exceptions for player less hacky 2016-01-23 12:14:29 +01:00
Jace db0e67b9bd Added EntityWrapper::IsChildOf and made snapshot interpolation and rendering exceptions for player less hacky 2016-01-23 11:44:16 +01:00
Jace 31e7340daf Ignoring interpolation and rendering for local player entities! 2016-01-23 00:40:37 +01:00
Jace 3ac3311c0c "inline" caused missing symbol when compiling in Release for some reason 2016-01-23 00:38:11 +01:00
Jace 90867b094a Merge remote-tracking branch 'origin/TextRendering' into Networking
# Conflicts:
#	include/Engine/Rendering/RenderSystem.h
#	src/Engine/Rendering/RenderSystem.cpp
2016-01-22 22:08:56 +01:00
Jace 55ee2bb3bf Player input properly separated from editor input and server 2016-01-22 21:35:31 +01:00
stiffly 406b730ef3 Sends entity names. Temporarily 2016-01-22 19:07:20 +01:00
stiffly b37b20b7d8 Didn't bulid lol. Fixed. 2016-01-22 17:57:31 +01:00
stiffly 750442d224 Merge remote-tracking branch 'origin/Networking' into Networking 2016-01-22 17:49:56 +01:00
stiffly 389e057611 EPlayerSpawned special logic added to server and client. 2016-01-22 17:49:21 +01:00
Jace 74d9bae896 Added conditional spawning based on whether the running instance is a server or not 2016-01-22 17:34:57 +01:00
stiffly 74c95089ea Merge remote-tracking branch 'origin/PlayerMovement' into Networking 2016-01-22 16:19:35 +01:00
Jace ca2aab449e Basic movement and camera management between players and editor 2016-01-22 16:12:51 +01:00
stiffly 08c476e9e3 Added kick logic to the server. Also typedefed. 2016-01-22 15:42:36 +01:00
stiffly 10c3b475bf Merge remote-tracking branch 'origin/Networking' into Networking
# Conflicts:
#	src/Engine/Network/Client.cpp
#	src/Engine/Network/Server.cpp
2016-01-22 13:19:51 +01:00
stiffly 08fcdb382b Used config for a lot of things 2016-01-22 13:18:53 +01:00
stiffly b1ea5429ce Used config for a lot of things 2016-01-22 11:53:04 +01:00
stiffly fcc9d64e7a Now publishes an EPlayerDisconnected event 2016-01-22 10:58:10 +01:00
stiffly 7a95880e10 Merge remote-tracking branch 'origin/master' into Networking 2016-01-22 10:36:11 +01:00
Jocke 6cd073c3c8 Added network metrics logging and reactored code. 2016-01-22 10:32:54 +01:00
Jace 1e3fc1ae2d Created EPlayerSpawned that gets published when a player spawns 2016-01-22 10:16:35 +01:00
antc13 c984f76b2f Importing & Reading Custom animation data. TODO: Shaders. 2016-01-20 18:36:03 +01:00
antc13 84b7cf165c Reduced the chance of crashing in Export. 2016-01-20 11:46:32 +01:00
antc13 386e76f642 Puyshing 2016-01-20 09:49:54 +01:00
antc13 a47317bb32 Merge branch 'master' of https://github.com/teamfisk/TacticalZ into Importer
# Conflicts:
#	include/Engine/Collision/Collision.h
#	resources/Shaders/ForwardPlus.frag.glsl
#	resources/Shaders/ForwardPlus.vert.glsl
2016-01-19 18:26:45 +01:00
antc13 e643581971 Commit in order to pull from Master. 2016-01-19 18:21:27 +01:00
antc13 3826142e94 Now supporting multiple material per mesh. Simon changed glDrawElementsBaseVertex to glDrawElements in DrawFinalPass.cpp Hallelulijah! 2016-01-19 17:40:34 +01:00
antc13 2a3009212a Importing custom mesh without material. 2016-01-18 19:37:55 +01:00
antc13 16c39df439 Merge branch 'master' of https://github.com/teamfisk/TacticalZ into Importer
# Conflicts:
#	include/Engine/Collision/Collision.h
#	src/Engine/Rendering/Model.cpp
#	src/Engine/Rendering/RawModelAssimp.cpp
2016-01-15 18:00:30 +01:00
antc13 8437b9c734 Commit for Pull 2016-01-15 17:58:26 +01:00
antc13 6317a6092d Merge branch 'MayaExporter' of https://github.com/teamfisk/TacticalZ into Importer 2016-01-15 16:51:10 +01:00
antc13 4e70439653 Merge branch 'Importer' of https://github.com/teamfisk/TacticalZ into Importer 2016-01-15 09:48:42 +01:00
antc13 24486c314d Reworked the Exporter. 2016-01-13 14:03:58 +01:00
antc13 7b62dc19bf Spitting out Meshes & Animation Data to file. 2016-01-12 15:39:29 +01:00
antc13 0e90382fd1 Merge branch 'master' of https://github.com/teamfisk/TacticalZ into MayaExporter 2016-01-11 13:09:09 +01:00
antc13 1667358e0c We now export animations. 2016-01-08 16:47:04 +01:00
FakeShemp eb5fca898f Fix small bug with push_back order
Commited directly from GitHub. Blame it if something explodes.
2015-12-21 12:55:25 +01:00
antc13 c9db46564f Spitting out files WIP 2015-12-18 16:21:07 +01:00
Teejoon 509a989d3b Merge branch 'MayaExporter' of github.com:teamfisk/TacticalZ into MayaExporter
Conflicts:
	tools/MayaExporter/MayaExporter/Menu.cpp
2015-12-18 10:07:44 +01:00
Teejoon bc4cc5db54 Changed how we get skeletons. Made so that we could get the bind pose for each skeleton in the scene 2015-12-18 10:03:00 +01:00
antc13 73708ec706 You can now add/remove animation clips. 2015-12-17 14:58:46 +01:00
antc13 67017fcaf4 Stepping through the timeline. 2015-12-16 11:33:42 +01:00
antc13 498afb3a5e Merge branch 'MayaExporter' of https://github.com/teamfisk/TacticalZ into MayaExporter
# Conflicts:
#	tools/MayaExporter/MayaExporter/Menu.h
2015-12-15 15:41:18 +01:00
antc13 4e535c1102 File Writer WIP. Rework soon™ 2015-12-15 15:24:46 +01:00
FakeShemp 1689370356 Export the skeletons
Not really tested though
2015-12-15 11:49:59 +01:00
antc13 60b3ce89b2 Skeleton/Joints WIP 2015-12-14 12:59:54 +01:00
antc13 a22d086e60 Tested some of the Material Code. Seems to work. The project should now be following the code standard properly (hopefully). 2015-12-10 11:18:34 +01:00
FakeShemp 74c1beed20 gitignore 2015-12-09 12:03:01 +01:00
FakeShemp c8cb0ee939 Grab all materials 2015-12-09 11:58:49 +01:00
119 changed files with 4993 additions and 1058 deletions
+8
View File
@@ -4,3 +4,11 @@ bin/
lib/
# Because apparently nobody has any self control
*.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
+2 -1
View File
@@ -10,7 +10,8 @@
#include "../Core/Ray.h"
#include "../Core/AABB.h"
#include "../Rendering/RawModel.h"
#include "Rendering/RawModelCustom.h"
//#include "Rendering/RawModelAssimp.h"
#include "../Core/Transform.h"
#include "../Core/Entity.h"
#include "../Core/EntityWrapper.h"
+21
View File
@@ -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
+19
View File
@@ -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
+3 -3
View File
@@ -2,15 +2,15 @@
#define EPlayerDamage_h__
#include "EventBroker.h"
#include "../Core/Entity.h"
#include "../Core/EntityWrapper.h"
namespace Events
{
struct PlayerDamage : Event
{
double DamageAmount;
EntityID PlayerDamagedID;
EntityWrapper Player;
double Damage;
};
}
+20
View File
@@ -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 -4
View File
@@ -2,16 +2,14 @@
#define EShoot_h__
#include "EventBroker.h"
#include "../Core/Entity.h"
#include "Engine/GLM.h"
#include "../Core/EntityWrapper.h"
namespace Events
{
struct Shoot : Event
{
//ID for who made the shot
EntityID shooter;
EntityWrapper Player;
};
}
+4 -1
View File
@@ -23,8 +23,11 @@ struct EntityWrapper
static const EntityWrapper Invalid;
bool HasComponent(const std::string& componentName);
bool HasComponent(const std::string& componentType);
EntityWrapper Parent();
EntityWrapper FirstChildByName(const std::string& name);
EntityWrapper FirstParentWithComponent(const std::string& componentType);
bool IsChildOf(EntityWrapper potentialParent);
bool Valid();
ComponentWrapper operator[](const char* componentName);
+1 -1
View File
@@ -111,7 +111,7 @@ struct Child
std::vector<ContainedObject>& m_StaticObjectsRef;
std::vector<ContainedObject>& m_DynamicObjectsRef;
inline bool hasChildren() const;
bool hasChildren() const;
int childIndexContainingPoint(const glm::vec3& point) const;
std::vector<int> childIndicesContainingBox(const AABB& box) const;
};
+4 -4
View File
@@ -32,10 +32,10 @@ public:
};
struct FailedLoadingException : public std::exception
{
virtual const char* what() const throw()
{
return "Resource is failed to load.";
}
FailedLoadingException(char const* const _Message)
: std::exception(_Message)
{ }
FailedLoadingException() :std::exception("Resource failed to load.") { };
};
// Pretend that this is a pure virtual function that you have to implement
+5
View File
@@ -3,13 +3,18 @@
#include "../GLM.h"
#include "World.h"
#include "EntityWrapper.h"
namespace Transform
{
glm::vec3 AbsolutePosition(EntityWrapper entity);
glm::vec3 AbsolutePosition(World* world, EntityID entity);
glm::quat AbsoluteOrientation(EntityWrapper entity);
glm::quat AbsoluteOrientation(World* world, EntityID entity);
glm::vec3 AbsoluteScale(EntityWrapper entity);
glm::vec3 AbsoluteScale(World* world, EntityID entity);
glm::mat4 ModelMatrix(EntityWrapper entity);
glm::mat4 ModelMatrix(EntityID entity, World* world);
}
+6
View File
@@ -5,11 +5,15 @@
#include "Entity.h"
#include "ObjectPool.h"
#include "ComponentPool.h"
#include "EventBroker.h"
class World
{
public:
World() = default;
World(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ }
~World();
// Create empty entity
@@ -46,6 +50,7 @@ public:
std::string GetName(EntityID entity) const;
private:
EventBroker* m_EventBroker = nullptr;
EntityID m_CurrentEntityID = 0;
std::unordered_map<EntityID, EntityID> m_EntityParents;
@@ -55,6 +60,7 @@ private:
std::unordered_map<EntityID, std::string> m_EntityNames;
EntityID generateEntityID();
void deleteEntityRecursive(EntityID entity, bool cascaded = false);
};
#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
+15 -4
View File
@@ -1,7 +1,6 @@
#include "../Core/System.h"
#include "../Rendering/IRenderer.h"
#include "../Rendering/Camera.h"
#include "../Rendering/DebugCameraInputController.h"
#include "../Rendering/ESetCamera.h"
#include "../Core/World.h"
#include "../Core/SystemPipeline.h"
@@ -10,8 +9,10 @@
#include "../Core/EntityFileParser.h"
#include "../Core/EntityFileWriter.h"
#include "../Core/EMousePress.h"
#include "../Input/EInputCommand.h"
#include "EditorGUI.h"
#include "EditorStats.h"
#include "EditorCameraInputController.h"
class EditorSystem : public ImpureSystem
{
@@ -21,18 +22,24 @@ public:
void Update(double dt);
void Enable();
void Disable();
private:
IRenderer* m_Renderer;
RenderFrame* m_RenderFrame;
World* m_EditorWorld;
SystemPipeline* m_EditorWorldSystemPipeline;
Camera* m_EditorCamera;
EntityWrapper m_Camera = EntityWrapper::Invalid;
DebugCameraInputController<EditorSystem>* m_DebugCameraInputController;
//Camera* m_EditorCamera;
EntityWrapper m_EditorCamera = EntityWrapper::Invalid;
EntityWrapper m_ActualCamera = EntityWrapper::Invalid;
EditorCameraInputController<EditorSystem>* m_EditorCameraInputController;
EditorGUI* m_EditorGUI;
EditorStats* m_EditorStats;
// State
double m_LastTime = 0.f;
bool m_Enabled = true;
EditorGUI::WidgetMode m_WidgetMode = EditorGUI::WidgetMode::Translate;
EntityWrapper m_Widget = EntityWrapper::Invalid;
EntityWrapper m_CurrentSelection = EntityWrapper::Invalid;
@@ -56,4 +63,8 @@ private:
bool OnMousePress(const Events::MousePress& e);
EventRelay<EditorSystem, Events::WidgetDelta> m_EWidgetDelta;
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);
};
+1 -1
View File
@@ -9,7 +9,7 @@ namespace Events
struct InputCommand : Event
{
/** Numerical ID of the player. */
unsigned int PlayerID;
int PlayerID;
/** The command that was sent. */
std::string Command;
/** The value of the command. */
+104 -47
View File
@@ -9,62 +9,119 @@ template <typename EventContext>
class FirstPersonInputController : public InputController<EventContext>
{
public:
FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID)
: InputController(eventBroker)
, m_PlayerID(playerID)
{
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse);
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse);
}
FirstPersonInputController(EventBroker* eventBroker, int playerID);
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()
{
Events::LockMouse e;
m_EventBroker->Publish(e);
m_MouseLocked = true;
}
void LockMouse();
void UnlockMouse();
virtual bool OnCommand(const Events::InputCommand& e) override;
virtual void Reset();
void UnlockMouse()
{
Events::UnlockMouse e;
m_EventBroker->Publish(e);
m_MouseLocked = false;
}
protected:
const int m_PlayerID;
bool m_MouseLocked = false;
glm::vec3 m_Rotation;
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
{
if (m_PlayerID != e.PlayerID) {
return false;
}
template <typename EventContext>
FirstPersonInputController<EventContext>::FirstPersonInputController(EventBroker* eventBroker, int playerID)
: InputController(eventBroker)
, m_PlayerID(playerID)
{
EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse);
EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse);
}
if (m_MouseLocked) {
if (e.Command == "Pitch") {
float val = glm::radians(e.Value);
m_Orientation = m_Orientation * glm::angleAxis<float>(-val, glm::vec3(1, 0, 0));
return true;
}
template <typename EventContext>
void FirstPersonInputController<EventContext>::Reset()
{
m_Rotation = glm::vec3(0.f, 0.f, 0.f);
m_Jumping = false;
}
if (e.Command == "Yaw") {
float val = glm::radians(e.Value);
m_Orientation = glm::angleAxis<float>(-val, glm::vec3(0, 1, 0)) * m_Orientation;
return true;
}
}
template <typename EventContext>
void FirstPersonInputController<EventContext>::LockMouse()
{
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;
}
protected:
const unsigned int m_PlayerID;
glm::quat m_Orientation;
bool m_MouseLocked = false;
EventRelay<EventContext, Events::LockMouse> m_ELockMouse;
bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; }
EventRelay<EventContext, Events::UnlockMouse> m_EUnlockMouse;
bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; }
};
if (e.Command == "Pitch") {
float val = glm::radians(e.Value);
m_Rotation.x += -val;
//m_Rotation.x = glm::clamp(m_Rotation.x, -glm::half_pi<float>(), glm::half_pi<float>());
}
if (e.Command == "Yaw") {
float val = glm::radians(e.Value);
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
+20 -9
View File
@@ -20,6 +20,7 @@
#include "Input/EInputCommand.h"
#include "Core/EPlayerDamage.h"
#include "Network/EInterpolate.h"
#include "Core/EPlayerSpawned.h"
class Client : public Network
{
@@ -39,16 +40,18 @@ private:
char readBuf[INPUTSIZE] = { 0 };
// Packet loss logic
unsigned int m_PacketID = 0;
unsigned int m_PreviousPacketID = 0;
unsigned int m_SendPacketID = 0;
PacketID m_PacketID = 0;
PacketID m_PreviousPacketID = 0;
PacketID m_SendPacketID = 0;
AckBitPattern ackBitField = 0;
// Game logic
World* m_World;
std::string m_PlayerName;
int m_PlayerID = -1;
PlayerID m_PlayerID = -1;
EntityID m_ServerEntityID = std::numeric_limits<EntityID>::max();
bool m_IsConnected = false;
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
// Server Client Lookup map
// Assumes that root node for client and server is EntityID 0.
@@ -57,31 +60,36 @@ private:
std::unordered_map<EntityID, EntityID> m_ClientIDToServerID;
// Network logic
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
PlayerDefinition m_PlayerDefinitions[8];
SnapshotDefinitions m_NextSnapshot;
double m_DurationOfPingTime;
std::clock_t m_StartPingTime;
std::clock_t m_TimeSinceSentInputs;
unsigned int m_SendInputIntervalMs;
std::vector<Events::InputCommand> m_InputCommandBuffer;
// Private member functions
void readFromServer();
int receive(char* data, size_t length);
int receive(char* data);
void send(Packet& packet);
void connect();
void disconnect();
void ping();
void parseMessageType(Packet& packet);
void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType);
void parseConnect(Packet& packet);
void parsePlayerConnected(Packet& packet);
void parsePing();
void parseServerPing();
void 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 parseSnapshot(Packet& packet);
void identifyPacketLoss();
bool hasServerTimedOut();
EntityID createPlayer();
void sendInputCommands();
void sendLocalPlayerTransform();
void becomePlayer();
// Mapping Logic
// Returns if local EntityID exist in map
@@ -89,13 +97,16 @@ private:
// Returns if server EntityID exist in map
bool serverClientMapsHasEntity(EntityID serverEntityID);
void insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID);
void deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID);
// Events
EventBroker* m_EventBroker;
EventRelay<Client, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
EventRelay<Client, Events::PlayerDamage> m_EPlayeDamage;
EventRelay<Client, Events::PlayerDamage> m_EPlayerDamage;
bool OnPlayerDamage(const Events::PlayerDamage& e);
EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
};
#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
+11 -7
View File
@@ -5,16 +5,20 @@
// Used to determine what type of message was sent.
enum class MessageType
{
Connect,
Disconnect,
ClientPing,
ServerPing,
Message,
Snapshot,
Connect,
Disconnect,
Ping,
Message,
Snapshot,
OnInputCommand,
OnPlayerDamage,
PlayerConnected,
BecomePlayer
BecomePlayer,
Kick,
OnPlayerSpawned,
EntityDeleted,
ComponentDeleted,
PlayerTransform
};
#endif
+22 -2
View File
@@ -1,13 +1,22 @@
#ifndef Network_h__
#define Network_h__
#include <ctime>
#include "Core/World.h"
#include "Core/EventBroker.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 TIMEOUTMS 15000
typedef unsigned int PlayerID;
typedef unsigned int PacketID;
typedef unsigned int AckBitPattern;
class Network
{
@@ -15,6 +24,17 @@ public:
virtual ~Network() { };
virtual void Start(World* m_world, EventBroker *eventBroker) = 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
+18
View File
@@ -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
+7 -3
View File
@@ -11,12 +11,12 @@ class Packet
public:
// arg1: Type of message (Connect, Disconnect...)
// 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.
Packet(char* data, const int sizeOfPacket);
Packet(MessageType type);
~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...
template<typename T>
@@ -50,17 +50,21 @@ public:
// Pops the first element as if it was a string.
std::string ReadString();
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; };
char* Data() { return m_Data; };
unsigned int DataReadSize() { return m_ReturnDataOffset; }
unsigned int MaxSize() { return m_MaxPacketSize; }
unsigned int HeaderSize() { return m_HeaderSize; }
private:
char* m_Data;
unsigned int m_ReturnDataOffset = 0;
int m_Offset = 0;
unsigned int m_MaxPacketSize = 512;
unsigned int m_HeaderSize = 0;
void resizeData();
};
+8 -1
View File
@@ -1,12 +1,19 @@
#ifndef PlayerDefinition_h__
#define PlayerDefinition_h__
#include <string>
#include "../Core/Entity.h"
struct PlayerDefinition {
int EntityID = -1;
::EntityID EntityID = EntityID_Invalid;
std::string Name = "";
boost::asio::ip::udp::endpoint Endpoint;
// The ID of the last sent packet. (Local sequence number)
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;
};
+33 -20
View File
@@ -14,6 +14,10 @@
#include "../Network/Network.h"
#include "Input/EInputCommand.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
{
@@ -29,18 +33,18 @@ private:
boost::asio::ip::udp::socket m_Socket;
// Sending messages to client logic
PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS];
std::vector<PlayerDefinition> m_ConnectedUsers;
std::map<PlayerID, PlayerDefinition> m_ConnectedPlayers;
char readBuffer[INPUTSIZE] = { 0 };
int bytesRead = 0;
// 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 timOutTimer = std::clock();
// How often we send messages (milliseconds)
int intervalMs = 1000;
int snapshotInterval = 50;
int pingIntervalMs;
int snapshotInterval;
int checkTimeOutInterval = 100;
int m_NextPlayerID = 0;
//Timers
std::clock_t m_StartPingTime;
@@ -50,32 +54,41 @@ private:
EventBroker* m_EventBroker;
// Packet loss logic
unsigned int m_PacketID = 0;
unsigned int m_PreviousPacketID = 0;
PacketID m_PacketID = 0;
PacketID m_PreviousPacketID = 0;
// Private member functions
int receive(char* data, size_t length);
void readFromClients();
void send(Packet& packet, int playerID);
void send(Packet& packet);
void addChildrenToPacket(Packet& packet, EntityID entityID);
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 sendPing();
void checkForTimeOuts();
void disconnect(int i);
void parseClientPing(PlayerID playerID);
void parseConnect(Packet& packet, PlayerID playerID);
void parseDisconnect();
void parseMessageType(Packet& packet);
void parseOnInputCommand(Packet& packet);
void parseOnPlayerDamage(Packet& packet);
void parseConnect(Packet& packet);
void parseDisconnect();
void parseClientPing();
void parseServerPing();
void identifyPacketLoss();
void createPlayer();
int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
void parsePing();
PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
// Debug event
EventRelay<Server, Events::InputCommand> m_EInputCommand;
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
@@ -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
+4 -4
View File
@@ -1,7 +1,8 @@
#ifndef Model_h__
#define Model_h__
#include "RawModel.h"
#include "Rendering/RawModelCustom.h"
//#include "Rendering/RawModelAssimp.h"
#include "../OpenGL.h"
class Model : public ThreadUnsafeResource
@@ -19,12 +20,11 @@ public:
GLuint VAO;
GLuint ElementBuffer;
RawModel* m_RawModel;
private:
RawModel* m_RawModel;
GLuint VertexBuffer;
GLuint DiffuseVertexColorBuffer;
GLuint SpecularVertexColorBuffer;
GLuint NormalBuffer;
GLuint TangentNormalsBuffer;
GLuint BiTangentNormalsBuffer;
+8
View File
@@ -24,6 +24,10 @@ struct ModelJob : RenderJob
DiffuseTexture = matGroup.Texture.get();
NormalTexture = matGroup.NormalMap.get();
SpecularTexture = matGroup.SpecularMap.get();
IncandescenceTexture = matGroup.IncandescenceMap.get();
DiffuseColor = matGroup.DiffuseColor;
SpecularColor = matGroup.SpecularColor;
IncandescenceColor = matGroup.IncandescenceColor;
StartIndex = matGroup.StartIndex;
EndIndex = matGroup.EndIndex;
Matrix = matrix;
@@ -43,9 +47,13 @@ struct ModelJob : RenderJob
const Texture* DiffuseTexture;
const Texture* NormalTexture;
const Texture* SpecularTexture;
const Texture* IncandescenceTexture;
float Shininess = 0.f;
glm::vec4 Color;
const ::Model* Model = nullptr;
glm::vec4 DiffuseColor;
glm::vec4 SpecularColor;
glm::vec4 IncandescenceColor;
unsigned int StartIndex = 0;
unsigned int EndIndex = 0;
World* World;
@@ -1,5 +1,7 @@
#ifndef RawModel_h__
#define RawModel_h__
#ifndef RawModelAssimp_h__
#define RawModelAssimp_h__
#ifdef USING_ASSIMP_AS_IMPORTER
#include <fstream>
#include <iostream>
@@ -18,29 +20,27 @@
#include "Texture.h"
#include "Skeleton.h"
class RawModel : public Resource
#define RawModel RawModelAssimp
class RawModelAssimp : public Resource
{
friend class ResourceManager;
protected:
RawModel(std::string fileName);
RawModelAssimp(std::string fileName);
public:
~RawModel();
~RawModelAssimp();
struct Vertex
{
glm::vec3 Position;
glm::vec3 Normal;
glm::vec3 Tangent;
glm::vec3 BiTangent;
glm::vec3 BiNormal;
glm::vec2 TextureCoords;
glm::vec4 DiffuseVertexColor;
glm::vec4 SpecularVertexColor;
glm::vec4 BoneIndices1;
glm::vec4 BoneIndices2;
glm::vec4 BoneWeights1;
glm::vec4 BoneWeights2;
glm::vec4 BoneIndices;
glm::vec4 BoneWeights;
};
struct MaterialGroup
@@ -68,8 +68,6 @@ private:
std::vector<glm::ivec2> BoneIndices;
std::vector<glm::vec2> BoneWeights;
std::vector<glm::vec3> Normals;
std::vector<glm::vec4> DiffuseVertexColor;
std::vector<glm::vec4> SpecularVertexColor;
std::vector<glm::vec3> TangentNormals;
std::vector<glm::vec3> BiTangentNormals;
std::vector<glm::vec2> TextureCoords;
@@ -78,3 +76,4 @@ private:
};
#endif
#endif
+102
View File
@@ -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
+5 -1
View File
@@ -15,7 +15,7 @@
#include "Renderer.h"
#include "PointLightJob.h"
#include "../Core/Transform.h"
#include "DebugCameraInputController.h"
#include "../Core/EPlayerSpawned.h"
class RenderSystem : public ImpureSystem
{
@@ -30,6 +30,7 @@ private:
RenderFrame* m_RenderFrame;
Camera* m_Camera;
EntityWrapper m_CurrentCamera = EntityWrapper::Invalid;
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
EventRelay<RenderSystem, Events::SetCamera> m_ESetCamera;
bool OnSetCamera(Events::SetCamera &event);
@@ -41,6 +42,9 @@ private:
void fillModels(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
+2 -1
View File
@@ -4,6 +4,7 @@
#include <sstream>
#include "Common.h"
#include "../GLM.h"
#include <glm/gtx/matrix_decompose.hpp>
//struct Bone
//{
@@ -38,9 +39,9 @@ public:
, OffsetMatrix(offsetMatrix)
{ }
int ID;
std::string Name;
glm::mat4 OffsetMatrix;
int ID;
Bone* Parent;
std::vector<Bone*> Children;
+9 -9
View File
@@ -10,11 +10,12 @@
#include "Common.h"
#include "Core/System.h"
#include "Core/EventBroker.h"
#include "Core/ResourceManager.h"
#include "Core/ConfigFile.h"
#include "Core/EPlayerSpawned.h"
#include "Network/EInterpolate.h"
#define SNAPSHOTINTERVAL 0.05f
class InterpolationSystem : public PureSystem
{
struct Transform
@@ -25,29 +26,28 @@ class InterpolationSystem : public PureSystem
double interpolationTime;
};
public:
InterpolationSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("Transform")
{
EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate);
}
InterpolationSystem(World* world, EventBroker* eventBroker);
~InterpolationSystem() { }
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) override;
private:
std::unordered_map<EntityID, Transform> m_NextTransform;
std::unordered_map<EntityID, Transform> m_LastReceivedTransform;
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
//glm::vec3 vectorInterpolation(glm::vec3 prev, glm::vec3 next, double currentTime);
template <typename T>
T vectorInterpolation(T prev, T next, double currentTime)
{
T difference = next - prev;
T vector = (difference / SNAPSHOTINTERVAL) * static_cast<float>(currentTime);
T vector = (difference / m_SnapshotInterval) * static_cast<float>(currentTime);
return vector;
}
float m_SnapshotInterval;
EventRelay<InterpolationSystem, Events::Interpolate> m_EInterpolate;
bool InterpolationSystem::OnInterpolate(const Events::Interpolate& e);
EventRelay<InterpolationSystem, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(Events::PlayerSpawned& e);
};
#endif
+14 -5
View File
@@ -1,14 +1,23 @@
#include "Common.h"
#include "GLM.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:
PlayerMovementSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("Player")
{ }
PlayerMovementSystem(World* world, EventBroker* eventBroker);
~PlayerMovementSystem();
virtual void Update(double dt) override;
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);
};
+15 -2
View File
@@ -2,6 +2,9 @@
#include "Input/EInputCommand.h"
#include "Systems/SpawnerSystem.h"
#include "Events/ESpawnerSpawn.h"
#include "Core/EPlayerSpawned.h"
#include "Rendering/ESetCamera.h"
#include "Core/ConfigFile.h"
class PlayerSpawnSystem : public ImpureSystem
{
@@ -11,8 +14,18 @@ public:
virtual void Update(double dt) override;
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;
bool OnInputCommand(const Events::InputCommand& e);
std::vector<int> m_SpawnRequests;
EventRelay<PlayerSpawnSystem, Events::PlayerSpawned> m_OnPlayerSpawnerd;
bool OnPlayerSpawned(Events::PlayerSpawned& e);
};
+11 -8
View File
@@ -9,6 +9,7 @@
#include "Core/System.h"
#include "Core/EPlayerDamage.h"
#include "Core/EShoot.h"
#include "Core/EPlayerSpawned.h"
#include "Input/EInputCommand.h"
#include <tuple>
@@ -23,16 +24,18 @@ public:
virtual void Update(double dt) override;
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;
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
+8 -1
View File
@@ -1,11 +1,13 @@
[Debug]
LogLevel=1
LoadMap=
EditorEnabled=false
; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
; if false -> Use pool allocation.
DisableMemoryPool=false
[Editor]
CameraSpeed=3
[Video]
Fullscreen=false
VSYNC=false
@@ -19,6 +21,11 @@ IsServer=false
Name=Bob
Address=127.0.0.1
Port=13
MaxConnections=8
SnapshotInterval=0.05
SendInputIntervalMs=33
PingIntervalMs= 1000
TimeoutMs=15000
[Multithreading]
ResourceLoading=true
+2 -1
View File
@@ -21,4 +21,5 @@ F1=ToggleEditor
X=EditorToggleTransformSpace
C=ConnectToServer
N=SwitchToServer
M=SwitchToClient
M=SwitchToClient
P=SwitchToPlayer
+2 -5
View File
@@ -1,8 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Player.xsd">
<Velocity X="0" Y="0" Z="0"/>
<Forward>false</Forward>
<Left>false</Left>
<Back>false</Back>
<Right>false</Right>
<MovementSpeed>3</MovementSpeed>
<CrouchSpeed>1.5</CrouchSpeed>
</Player>
+2 -5
View File
@@ -9,11 +9,8 @@
</xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="Velocity" type="t:Vector" minOccurs="0"/>
<xs:element name="Forward" type="t:bool" 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:element name="MovementSpeed" type="t:float" minOccurs="0"/>
<xs:element name="CrouchSpeed" type="t:float" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
+273
View File
@@ -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>
+7 -7
View File
@@ -9,7 +9,7 @@
<Entity>
<Components>
<c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource>
<Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -41,7 +41,7 @@
<HomePointForTeam>3</HomePointForTeam>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -61,7 +61,7 @@
<CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -81,7 +81,7 @@
<CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -102,7 +102,7 @@
<CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -120,7 +120,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -138,7 +138,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -9,7 +9,7 @@
<Entity>
<Components>
<c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource>
<Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -42,7 +42,7 @@
<CaptureTimer>6.9158446328696002</CaptureTimer>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -63,7 +63,7 @@
<CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -83,7 +83,7 @@
<CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -104,7 +104,7 @@
<CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -122,7 +122,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -140,7 +140,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -9,7 +9,7 @@
<Entity>
<Components>
<c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource>
<Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -41,7 +41,7 @@
<HomePointForTeam>3</HomePointForTeam>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -61,7 +61,7 @@
<CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team/>
@@ -79,7 +79,7 @@
<CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team/>
@@ -98,7 +98,7 @@
<CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -116,7 +116,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -134,7 +134,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
+10 -10
View File
@@ -9,7 +9,7 @@
<Entity>
<Components>
<c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource>
<Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -41,7 +41,7 @@
<HomePointForTeam>3</HomePointForTeam>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -61,7 +61,7 @@
<CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -81,7 +81,7 @@
<CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -101,7 +101,7 @@
<CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -122,7 +122,7 @@
<CapturePointNumber>4</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -140,7 +140,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -158,7 +158,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -176,7 +176,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -194,7 +194,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
+10 -10
View File
@@ -9,7 +9,7 @@
<Entity>
<Components>
<c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource>
<Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -41,7 +41,7 @@
<HomePointForTeam>3</HomePointForTeam>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -61,7 +61,7 @@
<CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team/>
@@ -79,7 +79,7 @@
<CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint>
<c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
</c:Model>
<c:Team/>
<c:Transform>
@@ -96,7 +96,7 @@
<CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team/>
@@ -115,7 +115,7 @@
<CapturePointNumber>4</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -133,7 +133,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -151,7 +151,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -169,7 +169,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -187,7 +187,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<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>
+1 -1
View File
@@ -24,7 +24,7 @@
<Static>false</Static>
</c:Collidable>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0" G="1" R="0"/>
</c:Model>
<c:Transform>
@@ -6,7 +6,7 @@
<Orientation X="0" Y="0" Z="0"/>
</c:Transform>
<c:Model>
<Resource>Models/DummyScene.obj</Resource>
<Resource>Models/DummyScene.mesh</Resource>
</c:Model>
</Components>
<Children>
@@ -17,7 +17,7 @@
<Scale X="1" Y="1" Z="1"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Resource>Models/Core/UnitSphere.mesh</Resource>
</c:Model>
</Components>
</Entity>
@@ -28,7 +28,7 @@
<Scale X="2" Y="2" Z="2"/>
</c:Transform>
<c:Model>
<Resource>Models/RotationWidgetX.obj</Resource>
<Resource>Models/RotationWidgetX.mesh</Resource>
</c:Model>
<c:Trigger>
</c:Trigger>
@@ -43,7 +43,7 @@
<Position X="2.5"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model>
<c:AABB>
</c:AABB>
@@ -69,7 +69,7 @@
<Orientation X="0.0" Y="0" Z="1.0"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitRaptor.obj</Resource>
<Resource>Models/Core/UnitRaptor.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/>
</c:Model>
</Components>
@@ -94,7 +94,7 @@
<Orientation X="0" Y="0" Z="0"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/>
</c:Model>
</Components>
@@ -107,7 +107,7 @@
<Orientation X="0" Y="1.57" Z="0"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/>
</c:Model>
</Components>
@@ -9,7 +9,7 @@
<Entity>
<Components>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model>
<c:Transform>
<Scale X="100" Y="1" Z="100"/>
@@ -58,7 +58,7 @@
<Components>
<c:DirectionalLight/>
<c:Model>
<Resource>Models/DirectionalLightWidget.obj</Resource>
<Resource>Models/DirectionalLightWidget.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="2.1529963" Y="6.59221172" Z="0.169116676"/>
@@ -70,7 +70,7 @@
<Entity>
<Components>
<c:Model>
<Resource>Models/Assault.obj</Resource>
<Resource>Models/Assault.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-2.00568962" Y="0.527161121" Z="0"/>
@@ -94,7 +94,7 @@
<Entity>
<Components>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Resource>Models/Core/UnitSphere.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="3.70000029" Z="0"/>
@@ -18,7 +18,7 @@
<Axis X="1" Y="0" Z="0"/>
</c:EditorWidget>
<c:Model>
<Resource>Models/RotationWidgetX.obj</Resource>
<Resource>Models/RotationWidgetX.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -33,7 +33,7 @@
<Axis X="0" Y="1" Z="0"/>
</c:EditorWidget>
<c:Model>
<Resource>Models/RotationWidgetY.obj</Resource>
<Resource>Models/RotationWidgetY.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -48,7 +48,7 @@
<Axis X="0" Y="0" Z="1"/>
</c:EditorWidget>
<c:Model>
<Resource>Models/RotationWidgetZ.obj</Resource>
<Resource>Models/RotationWidgetZ.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -3,7 +3,7 @@
<Components>
<c:Model>
<Resource>Models/ScaleWidgetOrigin.obj</Resource>
<Resource>Models/ScaleWidgetOrigin.mesh</Resource>
</c:Model>
<c:Transform/>
<c:UniformScale>
@@ -20,7 +20,7 @@
</Type>
</c:EditorWidget>
<c:Model>
<Resource>Models/ScaleWidgetX.obj</Resource>
<Resource>Models/ScaleWidgetX.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -34,7 +34,7 @@
</Type>
</c:EditorWidget>
<c:Model>
<Resource>Models/ScaleWidgetY.obj</Resource>
<Resource>Models/ScaleWidgetY.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -48,7 +48,7 @@
</Type>
</c:EditorWidget>
<c:Model>
<Resource>Models/ScaleWidgetZ.obj</Resource>
<Resource>Models/ScaleWidgetZ.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -3,7 +3,7 @@
<Components>
<c:Model>
<Resource>Models/TranslationWidgetOrigin.obj</Resource>
<Resource>Models/TranslationWidgetOrigin.mesh</Resource>
</c:Model>
<c:Transform/>
<c:UniformScale>
@@ -18,7 +18,7 @@
<Axis X="1" Y="0" Z="0"/>
</c:EditorWidget>
<c:Model>
<Resource>Models/TranslationWidgetX.obj</Resource>
<Resource>Models/TranslationWidgetX.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -30,7 +30,7 @@
<Axis X="0" Y="1" Z="0"/>
</c:EditorWidget>
<c:Model>
<Resource>Models/TranslationWidgetY.obj</Resource>
<Resource>Models/TranslationWidgetY.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -42,7 +42,7 @@
<Axis X="0" Y="0" Z="1"/>
</c:EditorWidget>
<c:Model>
<Resource>Models/TranslationWidgetZ.obj</Resource>
<Resource>Models/TranslationWidgetZ.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -54,7 +54,7 @@
<Axis X="0" Y="1" Z="1"/>
</c:EditorWidget>
<c:Model>
<Resource>Models/WidgetPlaneX.obj</Resource>
<Resource>Models/WidgetPlaneX.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -66,7 +66,7 @@
<Axis X="1" Y="0" Z="1"/>
</c:EditorWidget>
<c:Model>
<Resource>Models/WidgetPlaneY.obj</Resource>
<Resource>Models/WidgetPlaneY.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -78,7 +78,7 @@
<Axis X="1" Y="1" Z="0"/>
</c:EditorWidget>
<c:Model>
<Resource>Models/WidgetPlaneZ.obj</Resource>
<Resource>Models/WidgetPlaneZ.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
+11 -1
View File
@@ -5,6 +5,16 @@
<c:Transform/>
</Components>
<Children/>
<Children>
<Entity>
<Components>
<c:Model>
<Resource></Resource>
</c:Model>
<c:Transform/>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+128
View File
@@ -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>
+30
View File
@@ -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>
+147 -35
View File
@@ -6,66 +6,178 @@
</Components>
<Children>
<Entity>
<Entity name="Ground">
<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/>
</Components>
<Children/>
</Entity>
<Entity>
<Entity name="ObstacleCoursePlayerBox">
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="1" B="0.513725519" G="0" R="1"/>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="0" Y="2" Z="0"/>
<Scale X="5" Y="1" Z="5"/>
<Position X="6.32800007" Y="0.807000041" Z="-2.2750001"/>
<Scale X="1" Y="1.60000002" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="Player">
<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>
<Entity name="ObstacleCourse1uHigh">
<Components>
<c:AABB/>
<c:Collidable/>
<c:Physics>
<Velocity X="0" Y="-0.0934068039" Z="0"/>
</c:Physics>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Color A="1" B="0" G="1" R="1"/>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Visible>false</Visible>
</c:Model>
<c:Player/>
<c:Transform>
<Position X="0" Y="4.15580511" Z="0"/>
<Scale X="0.704558551" Y="0.115156889" Z="1"/>
<Position X="9.11900043" Y="0.5" Z="-2.10900021"/>
<Scale X="1" Y="1" Z="8.1960001"/>
</c:Transform>
</Components>
<Children/>
</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>
</Entity>
+3 -3
View File
@@ -11,7 +11,7 @@
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="0" R="0"/>
</c:Model>
<c:Transform>
@@ -27,7 +27,7 @@
<Static>false</Static>
</c:Collidable>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0" G="0" R="1"/>
</c:Model>
<c:Transform>
@@ -42,7 +42,7 @@
<Static>false</Static>
</c:Collidable>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0" G="1" R="0"/>
</c:Model>
<c:Transform>
+110 -9
View File
@@ -2,17 +2,118 @@
<Entity name="Player" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:AABB/>
<c:Physics/>
<c:AABB>
<Origin X="0" Y="0.772000015" Z="0"/>
<Size X="1" Y="1.60000002" Z="1"/>
</c:AABB>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="1" G="0" R="0"/>
</c:Model>
<c:Player/>
<c:Transform/>
<c:Model/>
<c:Physics/>
<c:Player>
<MovementSpeed>5</MovementSpeed>
</c:Player>
<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>
<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>
+16
View File
@@ -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>
+4 -4
View File
@@ -7,7 +7,7 @@
<Orientation X="0.0" Y="0" Z="0.0"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitRaptor.obj</Resource>
<Resource>Models/Core/UnitRaptor.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/>
</c:Model>
</Components>
@@ -31,7 +31,7 @@
<Scale X="0.1" Y="0.4" Z="0.1"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCylinder.obj</Resource>
<Resource>Models/Core/UnitCylinder.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/>
</c:Model>
</Components>
@@ -44,7 +44,7 @@
<Orientation X="0" Y="0" Z="0"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/>
</c:Model>
</Components>
@@ -57,7 +57,7 @@
<Orientation X="0" Y="1.57" Z="0"/>
</c:Transform>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/>
</c:Model>
</Components>
+7 -7
View File
@@ -12,7 +12,7 @@
<Name>ActionCamera</Name>
</c:Camera>
<c:Model>
<Resource>Models/Camera.obj</Resource>
<Resource>Models/Camera.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-0.504807115" Y="6.00582743" Z="9.68687439"/>
@@ -39,7 +39,7 @@
<Entity>
<Components>
<c:Model>
<Resource>Models/Core/UnitPlane.obj</Resource>
<Resource>Models/Core/UnitPlane.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="-1" Z="0.600000024"/>
@@ -51,7 +51,7 @@
<Entity>
<Components>
<c:Model>
<Resource>Models/Assault.obj</Resource>
<Resource>Models/Assault.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-2.5" Y="0" Z="1"/>
@@ -190,7 +190,7 @@
<Entity>
<Components>
<c:Model>
<Resource>Models/Assault.obj</Resource>
<Resource>Models/Assault.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="2.5" Y="0" Z="1"/>
@@ -205,7 +205,7 @@
</c:Camera>
<c:Listener/>
<c:Model>
<Resource>Models/Camera.obj</Resource>
<Resource>Models/Camera.mesh</Resource>
<Visible>false</Visible>
</c:Model>
<c:Transform>
@@ -237,7 +237,7 @@
<Intensity>0.80000001192092896</Intensity>
</c:DirectionalLight>
<c:Model>
<Resource>Models/DirectionalLightWidget.obj</Resource>
<Resource>Models/DirectionalLightWidget.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-0.0013256073" Y="1.89540339" Z="6.53467274"/>
@@ -249,7 +249,7 @@
<Entity>
<Components>
<c:Model>
<Resource>Models/Core/UnitCube.obj</Resource>
<Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-5.4082036" Y="0" Z="-1.84950542"/>
+10 -10
View File
@@ -9,7 +9,7 @@
<Entity>
<Components>
<c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource>
<Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
@@ -41,7 +41,7 @@
<HomePointForTeam>3</HomePointForTeam>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -61,7 +61,7 @@
<CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team/>
@@ -79,7 +79,7 @@
<CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint>
<c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource>
<Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
</c:Model>
<c:Team/>
<c:Transform>
@@ -96,7 +96,7 @@
<CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team/>
@@ -115,7 +115,7 @@
<CapturePointNumber>4</CapturePointNumber>
</c:CapturePoint>
<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"/>
</c:Model>
<c:Team>
@@ -133,7 +133,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -151,7 +151,7 @@
<c:Health/>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -171,7 +171,7 @@
</c:Health>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
@@ -191,7 +191,7 @@
</c:Health>
<c:AABB/>
<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"/>
</c:Model>
<c:Player/>
+1 -1
View File
@@ -12,7 +12,7 @@
<FilePath></FilePath>
</c:SoundEmitter>
<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"/>
</c:Model>
<c:Transform/>
+2 -2
View File
@@ -24,7 +24,7 @@
<Components>
<c:SpawnPoint/>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Resource>Models/Core/UnitSphere.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="0" Z="1.26689196"/>
@@ -37,7 +37,7 @@
<Components>
<c:SpawnPoint/>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Resource>Models/Core/UnitSphere.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="0" Z="-1.14786315"/>
+2 -2
View File
@@ -6,7 +6,7 @@
<Orientation X="0" Y="0" Z="0"/>
</c:Transform>
<c:Model>
<Resource>Models/DummyScene.obj</Resource>
<Resource>Models/DummyScene.mesh</Resource>
</c:Model>
</Components>
<Children>
@@ -19,7 +19,7 @@
<c:Camera>
</c:Camera>
<c:Model>
<Resource>Models/Camera.obj</Resource>
<Resource>Models/Camera.mesh</Resource>
</c:Model>
</Components>
</Entity>
+3
View File
@@ -16,6 +16,9 @@
<xs:simpleType name="double">
<xs:restriction base="xs:decimal"></xs:restriction>
</xs:simpleType>
<xs:simpleType name="float">
<xs:restriction base="xs:decimal"></xs:restriction>
</xs:simpleType>
<xs:simpleType name="string">
<xs:restriction base="xs:string"></xs:restriction>
</xs:simpleType>
+3 -8
View File
@@ -9,18 +9,14 @@ layout(location = 1) in vec3 Normal;
layout(location = 2) in vec3 Tangent;
layout(location = 3) in vec3 BiTangent;
layout(location = 4) in vec2 TextureCoords;
layout(location = 5) in vec4 DiffuseVertexColor;
layout(location = 6) in vec4 SpecularVertexColor;
layout(location = 7) in vec4 BoneIndices1;
layout(location = 8) in vec4 BoneIndices2;
layout(location = 9) in vec4 BoneWeights1;
layout(location = 10) in vec4 BoneWeights2;
layout(location = 5) in vec4 BoneIndices;
layout(location = 6) in vec4 BoneWeights;
out VertexData{
vec3 Position;
vec3 Normal;
vec2 TextureCoordinate;
vec4 DiffuseColor;
}Output;
void main()
@@ -30,5 +26,4 @@ void main()
Output.Position = Position;
Output.TextureCoordinate = TextureCoords;
Output.Normal = Normal;
Output.DiffuseColor = DiffuseVertexColor;
}
+2 -2
View File
@@ -4,6 +4,7 @@ uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform vec4 Color;
uniform vec4 DiffuseColor;
uniform vec2 ScreenDimensions;
layout (binding = 0) uniform sampler2D DiffuseTexture;
layout (binding = 1) uniform sampler2D GlowMap;
@@ -46,7 +47,6 @@ in VertexData{
vec3 Position;
vec3 Normal;
vec2 TextureCoordinate;
vec4 DiffuseColor;
}Input;
out vec4 sceneColor;
@@ -135,7 +135,7 @@ void main()
}
//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);
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
//These if statements should be removed if they are slow.
+15 -10
View File
@@ -3,32 +3,37 @@
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform mat4 Bones[100];
layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal;
layout(location = 2) in vec3 Tangent;
layout(location = 3) in vec3 BiTangent;
layout(location = 4) in vec2 TextureCoords;
layout(location = 5) in vec4 DiffuseVertexColor;
layout(location = 6) in vec4 SpecularVertexColor;
layout(location = 7) in vec4 BoneIndices1;
layout(location = 8) in vec4 BoneIndices2;
layout(location = 9) in vec4 BoneWeights1;
layout(location = 10) in vec4 BoneWeights2;
layout(location = 5) in vec4 BoneIndices;
layout(location = 6) in vec4 BoneWeights;
out VertexData{
vec3 Position;
vec3 Normal;
vec2 TextureCoordinate;
vec4 DiffuseColor;
}Output;
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.Normal = vec3(M * vec4(Normal, 0.0));
Output.DiffuseColor = DiffuseVertexColor;
}
+1 -1
View File
@@ -31,7 +31,7 @@ void CollisionSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& c
}
if (Collision::AABBVsAABB(boxA, boxB, resolutionVector)) {
(glm::vec3&)cTransform["Position"] += resolutionVector;
cPhysics["Velocity"] = glm::vec3(0, 0, 0);
((glm::vec3&)cPhysics["Velocity"]).y = 0.f;
}
}
+43
View File
@@ -5,6 +5,9 @@ const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Inv
bool EntityWrapper::HasComponent(const std::string& componentName)
{
if (!Valid()) {
return false;
}
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()
{
if (this->World == nullptr) {
+1 -1
View File
@@ -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;
}
+20
View File
@@ -1,5 +1,10 @@
#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 position;
@@ -14,6 +19,11 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
return position;
}
glm::quat Transform::AbsoluteOrientation(EntityWrapper entity)
{
return AbsoluteOrientation(entity.World, entity.ID);
}
glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity)
{
glm::quat orientation;
@@ -27,6 +37,11 @@ glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity)
return orientation;
}
glm::vec3 Transform::AbsoluteScale(EntityWrapper entity)
{
return AbsoluteScale(entity.World, entity.ID);
}
glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
{
glm::vec3 scale(1.f);
@@ -40,6 +55,11 @@ glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity)
return scale;
}
glm::mat4 Transform::ModelMatrix(EntityWrapper entity)
{
return ModelMatrix(entity.ID, entity.World);
}
glm::mat4 Transform::ModelMatrix(EntityID entity, World* world)
{
glm::vec3 position = Transform::AbsolutePosition(world, entity);
+66 -32
View File
@@ -1,4 +1,6 @@
#include "Core/World.h"
#include "Core/EEntityDeleted.h"
#include "Core/EComponentDeleted.h"
World::~World()
{
@@ -21,37 +23,7 @@ EntityID World::CreateEntity(EntityID parent /*= 0*/)
void World::DeleteEntity(EntityID entity)
{
// Delete components
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);
deleteEntityRecursive(entity, false);
}
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);
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)
@@ -155,3 +135,57 @@ EntityID World::generateEntityID()
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);
}
+1 -1
View File
@@ -39,7 +39,7 @@ void EditorRenderSystem::Update(double dt)
continue;
} catch (const std::exception&) {
try {
model = ResourceManager::Load<::Model>("Models/Core/Error.obj");
model = ResourceManager::Load<::Model>("Models/Core/Error.mesh");
} catch (const std::exception&) {
continue;
}
+77 -17
View File
@@ -14,10 +14,11 @@ EditorSystem::EditorSystem(World* world, EventBroker* eventBroker, IRenderer* re
m_EditorWorldSystemPipeline->AddSystem<EditorWidgetSystem>(0, m_Renderer);
m_EditorWorldSystemPipeline->AddSystem<EditorRenderSystem>(1, m_Renderer, m_RenderFrame);
m_Camera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
m_EditorWorld->AttachComponent(m_Camera.ID, "Transform");
m_EditorWorld->AttachComponent(m_Camera.ID, "Camera");
m_DebugCameraInputController = new DebugCameraInputController<EditorSystem>(m_EventBroker, -1);
m_EditorCamera = importEntity(EntityWrapper(m_EditorWorld, EntityID_Invalid), "Schema/Entities/Empty.xml");
m_ActualCamera = m_EditorCamera;
m_EditorWorld->AttachComponent(m_EditorCamera.ID, "Transform");
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->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_EWidgetDelta, &EditorSystem::OnWidgetDelta);
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &EditorSystem::OnSetCamera);
m_EditorStats = new EditorStats();
Events::SetCamera e;
e.CameraEntity = m_Camera;
m_EventBroker->Publish(e);
if (m_Enabled) {
Enable();
}
}
EditorSystem::~EditorSystem()
{
delete m_EditorStats;
delete m_EditorGUI;
delete m_DebugCameraInputController;
delete m_EditorCameraInputController;
delete m_EditorWorldSystemPipeline;
delete m_EditorWorld;
}
void EditorSystem::Update(double dt)
{
m_EventBroker->Process<EditorGUI>();
m_EditorGUI->Draw();
m_EditorStats->Draw(dt);
double now = glfwGetTime();
double actualDelta = now - m_LastTime;
m_LastTime = now;
if (m_CurrentSelection.Valid() && m_Widget.Valid()) {
(glm::vec3&)m_Widget["Transform"]["Position"] = Transform::AbsolutePosition(m_CurrentSelection.World, m_CurrentSelection.ID);
if (m_Enabled) {
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);
m_Camera["Transform"]["Position"] = m_DebugCameraInputController->Position();
m_Camera["Transform"]["Orientation"] = glm::eulerAngles(m_DebugCameraInputController->Orientation());
void EditorSystem::Disable()
{
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)
@@ -148,6 +181,33 @@ bool EditorSystem::OnWidgetDelta(const Events::WidgetDelta& e)
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)
{
if (parent.World == nullptr) {
+194 -88
View File
@@ -5,14 +5,20 @@ using namespace boost::asio::ip;
Client::Client(ConfigFile* config) : m_Socket(m_IOService)
{
// Asumes root node is EntityID 0
insertIntoServerClientMaps(0, 0);
Network::initialize();
// Asumes root node is EntityID_Invalid
insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid);
// Init timer
m_TimeSinceSentInputs = std::clock();
// Default is local host
std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1");
int port = config->Get<int>("Networking.Port", 13);
int port = config->Get<int>("Networking.Port", 27666);
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
// Set up network stream
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
m_SendInputIntervalMs = config->Get<int>("Networking.SendInputIntervalMs", 33);
}
Client::~Client()
@@ -25,7 +31,8 @@ void Client::Start(World* world, EventBroker* eventBroker)
// Subscribe to events
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);
LOG_INFO("I am client. BIP BOP");
@@ -37,19 +44,25 @@ void Client::Update()
readFromServer();
if (m_IsConnected) {
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()
{
while (m_Socket.available()) {
bytesRead = receive(readBuf, INPUTSIZE);
bytesRead = receive(readBuf);
if (bytesRead > 0) {
Packet packet(readBuf, bytesRead);
parseMessageType(packet);
}
}
sendInputCommands();
}
void Client::parseMessageType(Packet& packet)
@@ -66,12 +79,9 @@ void Client::parseMessageType(Packet& packet)
case MessageType::Connect:
parseConnect(packet);
break;
case MessageType::ClientPing:
case MessageType::Ping:
parsePing();
break;
case MessageType::ServerPing:
parseServerPing();
break;
case MessageType::Message:
break;
case MessageType::Snapshot:
@@ -81,6 +91,19 @@ void Client::parseMessageType(Packet& packet)
break;
case MessageType::PlayerConnected:
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:
break;
}
@@ -99,11 +122,6 @@ void Client::parsePlayerConnected(Packet & packet)
}
void Client::parsePing()
{
}
void Client::parseServerPing()
{
// Might miss connect message so set it here instead.
m_IsConnected = true;
@@ -112,11 +130,49 @@ void Client::parseServerPing()
LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime);
m_StartPingTime = std::clock();
Packet packet(MessageType::ServerPing, m_SendPacketID);
Packet packet(MessageType::Ping, m_SendPacketID, m_PacketID, ackBitField);
packet.WriteString("Ping recieved");
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
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)
{
std::string componentType = packet.ReadString();
while (packet.DataReadSize() < packet.Size()) {
// Components EntityID
EntityID receivedEntityID = packet.ReadPrimitive<EntityID>();
// Parents EntityID
EntityID receivedParentEntityID = packet.ReadPrimitive<EntityID>();
ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
// Check if the received EntityID is mapped to one of our local EntityIDs
if (serverClientMapsHasEntity(receivedEntityID)) {
// Get the local EntityID
EntityID entityID = m_ServerIDToClientID.at(receivedEntityID);
// Check if the component exists
if (m_World->HasComponent(entityID, componentType)) {
// If the entity and the component exists update it
if (componentType == "Transform") {
InterpolateFields(packet, componentInfo, entityID, componentType);
EntityID serverEntityID = packet.ReadPrimitive<EntityID>();
EntityID serverParentID = packet.ReadPrimitive<EntityID>();
std::string serverEntityName = packet.ReadString();
int ammountOfComponents = packet.ReadPrimitive<int>();
for (int i = 0; i < ammountOfComponents; i++) {
std::string componentType = packet.ReadString();
ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
if (serverClientMapsHasEntity(serverEntityID)) {
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
// Update entity
if (m_World->HasComponent(localEntityID, componentType)) {
// Update component
if (componentType == "Transform") {
// 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 {
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 {
// Create component
m_World->AttachComponent(entityID, componentType);
// Copy data to newly created component
updateFields(packet, componentInfo, entityID, componentType);
// Create Entity and component
EntityID newLocalEntityID;
if (serverParentID == EntityID_Invalid) {
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
// Don't need to check if receivedEntityID is mapped. (It should have been set)
if (receivedParentEntityID != std::numeric_limits<EntityID>::max()) {
if (serverClientMapsHasEntity(receivedParentEntityID)) {
m_World->SetParent(m_ServerIDToClientID.at(receivedEntityID), m_ServerIDToClientID.at(receivedParentEntityID));
// If Parent dosen't exist create one and map receivedParentEntityID to it.
} else {
// Create the new parent and add it to map
EntityID newParentEntityID = m_World->CreateEntity();
insertIntoServerClientMaps(receivedParentEntityID, newParentEntityID);
// Set the newly created Entity as parent.
m_World->SetParent(m_ServerIDToClientID.at(receivedEntityID), newParentEntityID);
}
// Parent logic
// This should be enough beacause we know that the entities arives in pre-order (there will always be a parent)
if (serverParentID != EntityID_Invalid) {
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID));
}
}
}
int Client::receive(char* data, size_t length)
int Client::receive(char* data)
{
boost::system::error_code error;
int bytesReceived = m_Socket.receive_from(boost
::asio::buffer((void*)data, length),
::asio::buffer((void*)data, INPUTSIZE),
m_ReceiverEndpoint,
0, error);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataReceived += bytesReceived;
m_NetworkData.DataReceivedThisInterval += bytesReceived;
m_NetworkData.AmountOfMessagesReceived++;
}
if (error) {
//LOG_ERROR("receive: %s", error.message().c_str());
}
@@ -232,11 +284,17 @@ void Client::send(Packet& packet)
packet.Data(),
packet.Size()),
m_ReceiverEndpoint, 0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
m_NetworkData.AmountOfMessagesSent++;
}
}
void Client::connect()
{
Packet packet(MessageType::Connect, m_SendPacketID);
Packet packet(MessageType::Connect, m_SendPacketID, m_PacketID, ackBitField);
packet.WriteString(m_PlayerName);
m_StartPingTime = std::clock();
send(packet);
@@ -246,18 +304,10 @@ void Client::disconnect()
{
m_PreviousPacketID = 0;
m_PacketID = 0;
Packet packet(MessageType::Disconnect, m_SendPacketID);
Packet packet(MessageType::Disconnect, m_SendPacketID, m_PacketID, ackBitField);
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)
{
if (e.Command == "ConnectToServer") { // Connect for now
@@ -275,6 +325,15 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
if (e.Value > 0) {
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 {
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);
@@ -285,13 +344,40 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
bool Client::OnPlayerDamage(const Events::PlayerDamage & e)
{
Packet packet(MessageType::OnInputCommand, m_SendPacketID);
packet.WritePrimitive(e.DamageAmount);
packet.WritePrimitive(e.PlayerDamagedID);
Packet packet(MessageType::OnPlayerDamage, m_SendPacketID, m_PacketID, ackBitField);
packet.WritePrimitive(e.Damage);
packet.WritePrimitive(e.Player.ID);
send(packet);
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()
{
// if no packets lost, difference should be equal to 1
@@ -305,7 +391,7 @@ bool Client::hasServerTimedOut()
{
// Time in ms
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.
LOG_INFO("Server has timed out, returning to menu, Beep Boop.");
m_IsConnected = false;
@@ -319,7 +405,7 @@ EntityID Client::createPlayer()
EntityID entityID = m_World->CreateEntity();
ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform");
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");
return entityID;
}
@@ -327,7 +413,7 @@ EntityID Client::createPlayer()
void Client::sendInputCommands()
{
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++) {
packet.WriteString(m_InputCommandBuffer[i].Command);
packet.WritePrimitive(m_InputCommandBuffer[i].Value);
@@ -339,18 +425,32 @@ void Client::sendInputCommands()
void Client::becomePlayer()
{
Packet packet = Packet(MessageType::BecomePlayer, m_SendPacketID);
Packet packet(MessageType::BecomePlayer, m_SendPacketID, m_PacketID, ackBitField);
send(packet);
}
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)
{
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)
@@ -359,3 +459,9 @@ void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID client
m_ClientIDToServerID.insert(std::make_pair(clientEntityID, serverEntityID));
}
void Client::deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID)
{
m_ServerIDToClientID.erase(serverEntityID);
m_ClientIDToServerID.erase(clientEntityID);
}
+68
View File
@@ -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);
}
+29 -9
View File
@@ -1,9 +1,9 @@
#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];
Init(type, packetID);
Init(type, packetID, lastReceivedPacket, ackBitField);
}
// Create message
@@ -21,7 +21,9 @@ Packet::Packet(MessageType type)
{
m_Data = new char[m_MaxPacketSize];
unsigned int dummy = 0;
Init(type, dummy);
// Dummy allocates memory for later insertion of
// correct values
Init(type, dummy, dummy, dummy);
}
Packet::~Packet()
@@ -29,16 +31,19 @@ Packet::~Packet()
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_Offset = 0;
// Create message header
// Add message type
int messageType = static_cast<int>(type);
Packet::WritePrimitive<int>(messageType);
Packet::WritePrimitive<int>(packetID);
WritePrimitive<int>(messageType);
WritePrimitive<unsigned int>(packetID);
WritePrimitive<unsigned int>(lastReceivedPacket);
WritePrimitive<unsigned int>(ackBitField);
packetID++;
m_HeaderSize = m_Offset;
}
void Packet::WriteString(const std::string& str)
@@ -86,16 +91,31 @@ char * Packet::ReadData(int SizeOfData)
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;
// Start at sizeOf(int) cause of MessageType
int offset = sizeof(int);
// 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()
{
// Allocate memory to store our data in
char* holdData = new char[m_MaxPacketSize];
// Copy our data to the newly allocated memory
+237 -146
View File
@@ -1,7 +1,13 @@
#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()
{
@@ -14,9 +20,9 @@ void Server::Start(World* world, EventBroker* eventBroker)
m_EventBroker = eventBroker;
// Subscribe to events
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
for (size_t i = 0; i < MAXCONNECTIONS; i++) {
m_PlayerDefinitions[i].StopTime = std::clock();
}
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted);
EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
LOG_INFO("I am Server. BIP BOP\n");
}
@@ -24,14 +30,27 @@ void Server::Update()
{
readFromClients();
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()
{
while (m_Socket.available()) {
try {
bytesRead = receive(readBuffer, INPUTSIZE);
bytesRead = receive(readBuffer);
Packet packet(readBuffer, bytesRead);
parseMessageType(packet);
} catch (const std::exception& err) {
@@ -46,9 +65,9 @@ void Server::readFromClients()
}
// Send pings each
if (intervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) {
if (pingIntervalMs < (1000 * (currentTime - previousPingMessage) / (double)CLOCKS_PER_SEC)) {
sendPing();
previousePingMessage = currentTime;
previousPingMessage = currentTime;
}
// Time out logic
@@ -60,21 +79,22 @@ void Server::readFromClients()
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
m_PreviousPacketID = m_PacketID; // Set previous packet id
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id
if (playerID != -1) {
// TODO: Bit pattern stuff!"#!"#
m_ConnectedPlayers[playerID].LastPacketReceivedID = packet.ReadPrimitive<PacketID>();
}
//identifyPacketLoss();
switch (static_cast<MessageType>(messageType)) {
case MessageType::Connect:
parseConnect(packet);
parseConnect(packet, playerID);
break;
case MessageType::ClientPing:
//parseClientPing();
break;
case MessageType::ServerPing:
parseServerPing();
case MessageType::Ping:
parsePing();
break;
case MessageType::Message:
break;
@@ -89,29 +109,46 @@ void Server::parseMessageType(Packet& packet)
case MessageType::OnPlayerDamage:
parseOnPlayerDamage(packet);
break;
case MessageType::BecomePlayer:
createPlayer();
case MessageType::PlayerTransform:
parsePlayerTransform(packet);
break;
default:
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
, length)
, INPUTSIZE)
, m_ReceiverEndpoint, 0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataReceived += length;
m_NetworkData.DataReceivedThisInterval += length;
m_NetworkData.AmountOfMessagesReceived++;
}
return length;
}
void Server::send(Packet& packet, int userID)
void Server::send(PlayerID playerID, Packet& packet)
{
int bytesSent = m_Socket.send_to(
boost::asio::buffer(packet.Data(), packet.Size()),
m_ConnectedUsers[userID].Endpoint,
0);
try {
int bytesSent = m_Socket.send_to(
boost::asio::buffer(packet.Data(), packet.Size()),
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)
@@ -122,59 +159,87 @@ void Server::send(Packet & packet)
packet.Size()),
m_ReceiverEndpoint,
0);
if (isReadingData) {
// Network Debug data
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
}
}
void Server::broadcast(Packet& packet)
{
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
packet.ChangePacketID(m_ConnectedUsers[i].PacketID);
send(packet, i);
}
for (auto& kv : m_ConnectedPlayers) {
packet.ChangeHeaderInfo(
kv.second.PacketID,
kv.second.LastPacketReceivedID,
kv.second.AckBitField
);
send(kv.first, packet);
}
}
// Send snapshot fields
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();
for (auto& it : worldComponentPools) {
Packet packet(MessageType::Snapshot);
ComponentPool* componentPool = it.second;
ComponentInfo componentInfo = componentPool->ComponentInfo();
// Component Type
packet.WriteString(componentInfo.Name);
for (auto& componentWrapper : *componentPool) {
// Components EntityID
packet.WritePrimitive(componentWrapper.EntityID);
// Parents EntityID
packet.WritePrimitive(m_World->GetParent(componentWrapper.EntityID));
for (auto& componentField : componentWrapper.Info.FieldsInOrder) {
ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(componentField);
if (fieldInfo.Type == "string") {
std::string& value = componentWrapper[componentField];
packet.WriteString(value);
} else {
packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride);
// Loop through every child
for (auto it = itPair.first; it != itPair.second; it++) {
EntityID childEntityID = it->second;
// Write EntityID and parentsID and Entity name
packet.WritePrimitive(childEntityID);
packet.WritePrimitive(entityID);
packet.WriteString(m_World->GetName(childEntityID));
// Write components to child
int numberOfComponents = 0;
for (auto& i : worldComponentPools) {
if (i.second->KnowsEntity(childEntityID)) {
numberOfComponents++;
}
}
// Write how many components should be read
packet.WritePrimitive(numberOfComponents);
for (auto& i : worldComponentPools) {
// 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()
{
// Prints connected players ping
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
int ping = 1000 * (m_ConnectedUsers[i].StopTime - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
LOG_INFO("Last packetID received %i: User %i's ping: %i", m_ConnectedUsers[i].PacketID, i, std::abs(ping));
}
}
//for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
// if (m_ConnectedPlayers[i].Endpoint.address() != boost::asio::ip::address()) {
// 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_ConnectedPlayers[i].PacketID, i, std::abs(ping));
// }
//}
// Create ping message
Packet packet(MessageType::ServerPing);
Packet packet(MessageType::Ping);
packet.WriteString("Ping from server");
// Time message
m_StartPingTime = std::clock();
@@ -187,11 +252,11 @@ void Server::checkForTimeOuts()
int startPing = 1000 * m_StartPingTime
/ static_cast<double>(CLOCKS_PER_SEC);
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) {
int stopPing = 1000 * m_ConnectedUsers[i].StopTime /
for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
if (m_ConnectedPlayers[i].Endpoint.address() != boost::asio::ip::address()) {
int stopPing = 1000 * m_ConnectedPlayers[i].StopTime /
static_cast<double>(CLOCKS_PER_SEC);
if (startPing > stopPing + TIMEOUTMS) {
if (startPing > stopPing + m_TimeoutMs) {
LOG_INFO("User %i timed out!", i);
disconnect(i);
}
@@ -199,35 +264,29 @@ void Server::checkForTimeOuts()
}
}
void Server::disconnect(int i)
void Server::disconnect(PlayerID playerID)
{
//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)
m_PlayerDefinitions[i].Endpoint = boost::asio::ip::udp::endpoint();
m_PlayerDefinitions[i].EntityID = -1;
m_PlayerDefinitions[i].Name = "";
m_PlayerDefinitions[i].PacketID = 0;
m_ConnectedUsers.erase(m_ConnectedUsers.begin() + i);
Events::PlayerDisconnected e;
e.Entity = m_ConnectedPlayers[playerID].EntityID;
e.PlayerID = playerID;
m_EventBroker->Publish(e);
m_ConnectedPlayers.erase(playerID);
}
void Server::parseOnInputCommand(Packet& packet)
{
int playerID = -1;
PlayerID player = -1;
// Check which player it was who sent the message
for (int i = 0; i < MAXCONNECTIONS; i++) {
// if the player is connected set playerID to the correct PlayerID
if (m_PlayerDefinitions[i].Endpoint.address() == m_ReceiverEndpoint.address()
&& m_PlayerDefinitions[i].Endpoint.port() == m_ReceiverEndpoint.port()) {
playerID = i;
break;
}
}
if (playerID != -1) {
player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
if (player != -1) {
while (packet.DataReadSize() < packet.Size()) {
Events::InputCommand e;
e.Command = packet.ReadString();
e.PlayerID = playerID; // Set correct player id
e.PlayerID = player; // Set correct player id
e.Value = packet.ReadPrimitive<float>();
m_EventBroker->Publish(e);
//LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
@@ -238,26 +297,19 @@ void Server::parseOnInputCommand(Packet& packet)
void Server::parseOnPlayerDamage(Packet & packet)
{
Events::PlayerDamage e;
e.DamageAmount = packet.ReadPrimitive<double>();
e.PlayerDamagedID = packet.ReadPrimitive<EntityID>();
e.Damage = packet.ReadPrimitive<double>();
e.Player = EntityWrapper(m_World, packet.ReadPrimitive<EntityID>());
m_EventBroker->Publish(e);
//LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str());
}
void Server::parseConnect(Packet& packet)
void Server::parseConnect(Packet& packet, PlayerID playerID)
{
LOG_INFO("Parsing connections");
// Check if player is already connected
if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) {
if (playerID != -1) {
return;
}
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address() &&
m_ConnectedUsers[i].Endpoint.port() == m_ReceiverEndpoint.port()) {
// Already connected
return;
}
}
// Create a new player
PlayerDefinition pd;
pd.EntityID = 0; // Overlook this
@@ -265,11 +317,11 @@ void Server::parseConnect(Packet& packet)
pd.Name = packet.ReadString();
pd.PacketID = 0;
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());
// Send a message to the player that connected
Packet connnectPacket(MessageType::Connect, m_ConnectedUsers[m_ConnectedUsers.size() - 1].PacketID);
send(connnectPacket);
// Send notification that a player has connected
@@ -281,32 +333,36 @@ void Server::parseDisconnect()
{
LOG_INFO("%i: Parsing disconnect", m_PacketID);
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
disconnect(i);
for (auto& kv : m_ConnectedPlayers) {
if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() &&
kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) {
disconnect(kv.first);
break;
}
}
}
void Server::parseClientPing()
void Server::parseClientPing(PlayerID player)
{
LOG_INFO("%i: Parsing ping", m_PacketID);
int playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
if (playerID == -1) {
if (player == -1) {
return;
}
// 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");
send(packet);
}
void Server::parseServerPing()
void Server::parsePing()
{
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
m_ConnectedUsers[i].StopTime = std::clock();
for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
if (m_ConnectedPlayers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
m_ConnectedPlayers[i].StopTime = std::clock();
break;
}
}
@@ -321,49 +377,19 @@ void Server::identifyPacketLoss()
}
}
void Server::createPlayer()
void Server::kick(PlayerID player)
{
if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) {
// Already connected as player
LOG_WARNING("Already connected!");
return;
}
int userIndex;
for (userIndex = 0; userIndex < m_ConnectedUsers.size(); userIndex++) {
if (m_ConnectedUsers[userIndex].Endpoint.address() == m_ReceiverEndpoint.address() &&
m_ConnectedUsers[userIndex].Endpoint.port() == m_ReceiverEndpoint.port()) {
// Found user
break;
}
}
if (userIndex == m_ConnectedUsers.size()) {
LOG_WARNING("Not a recognized user!");
return;
}
for (int playerIndex = 0; playerIndex < MAXCONNECTIONS; playerIndex++) {
if (m_PlayerDefinitions[playerIndex].Endpoint.address() == boost::asio::ip::address()) {
m_PlayerDefinitions[playerIndex] = m_ConnectedUsers[userIndex];
EntityID entityID = m_World->CreateEntity();
ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform");
transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f);
ComponentWrapper model = m_World->AttachComponent(entityID, "Model");
model["Resource"] = "Models/Core/UnitSphere.obj";
model["Color"] = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand() %255 / 255.f, 1.f);
ComponentWrapper player = m_World->AttachComponent(entityID, "Player");
m_PlayerDefinitions[playerIndex].EntityID = entityID;
return;
}
}
LOG_WARNING("Server is full!");
disconnect(player);
Packet packet = Packet(MessageType::Kick);
send(packet);
}
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++) {
if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() &&
m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) {
return i;
for (auto& kv : m_ConnectedPlayers) {
if (kv.second.Endpoint.address() == endpoint.address() &&
kv.second.Endpoint.port() == endpoint.port()) {
return kv.first;
}
}
return -1;
@@ -372,5 +398,70 @@ int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
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);
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;
}
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;
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ DrawBloomPass::DrawBloomPass(IRenderer* renderer)
{
m_Renderer = renderer;
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
InitializeTextures();
InitializeBuffers();
@@ -4,8 +4,8 @@ DrawColorCorrectionPass::DrawColorCorrectionPass(IRenderer* renderer)
{
m_Renderer = renderer;
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
m_Exposure = 1; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting.
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
m_Exposure = 0.4; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting.
InitializeShaderPrograms();
}
+24 -9
View File
@@ -65,6 +65,7 @@ void DrawFinalPass::Draw(RenderScene& scene)
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);
//TODO: Render: Add code for more jobs than modeljobs.
for (auto &job : scene.ForwardJobs) {
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
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, "DiffuseColor"), 1, glm::value_ptr(modelJob->DiffuseColor));
glActiveTexture(GL_TEXTURE0);
if(modelJob->DiffuseTexture != nullptr) {
@@ -80,22 +82,35 @@ void DrawFinalPass::Draw(RenderScene& scene)
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
}
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
/*if(modelJob->GlowMap != nullptr) {
glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture);
if (modelJob->IncandescenceTexture != nullptr) {
glBindTexture(GL_TEXTURE_2D, modelJob->IncandescenceTexture->m_Texture);
} else {
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);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex);
continue;
glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
}
}
m_FinalPassFrameBuffer.Unbind();
GLERROR("DrawFinalPass::Draw: END");
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_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
GLERROR("MipMap Texture initialization failed");
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ DrawScreenQuadPass::DrawScreenQuadPass(IRenderer* renderer)
{
m_Renderer = renderer;
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
InitializeShaderPrograms();
}
+4 -9
View File
@@ -15,6 +15,9 @@ Model::Model(std::string fileName)
if (!group.SpecularMapPath.empty()) {
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
@@ -32,7 +35,7 @@ Model::Model(std::string fileName)
GLERROR("GLEW: BufferFail4");
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;
for (int size : structSizes) {
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++;
}
GLERROR("GLEW: BufferFail5");
@@ -62,10 +61,6 @@ Model::Model(std::string fileName)
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glEnableVertexAttribArray(6);
glEnableVertexAttribArray(7);
glEnableVertexAttribArray(8);
glEnableVertexAttribArray(9);
glEnableVertexAttribArray(10);
GLERROR("GLEW: BufferFail5");
//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;
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("Model has %i embedded textures", scene->mNumTextures);
std::vector<std::tuple<std::string, glm::mat4>> boneInfo;
std::map<std::string, int> boneNameMapping;
@@ -74,21 +76,7 @@ RawModel::RawModel(std::string fileName)
auto uv = mesh->mTextureCoords[0][vertexIndex];
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);
}
@@ -128,7 +116,7 @@ RawModel::RawModel(std::string fileName)
}
for (auto& vertex : m_Vertices) {
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
@@ -201,10 +189,7 @@ RawModel::RawModel(std::string fileName)
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) {
std::tie(desc.BoneIndices1[weightIndex], desc.BoneWeights1[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];
std::tie(desc.BoneIndices[weightIndex], desc.BoneWeights[weightIndex]) = weights[weightIndex];
}
}
@@ -290,14 +275,14 @@ RawModel::RawModel(std::string fileName)
}
}
RawModel::~RawModel()
RawModelAssimp::~RawModelAssimp()
{
if (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();
@@ -317,3 +302,5 @@ void RawModel::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &b
CreateSkeleton(boneInfo, boneNameMapping, child, parentID);
}
}
#endif
+381
View File
@@ -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
+23 -6
View File
@@ -7,6 +7,7 @@ RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRender
{
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
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);
}
@@ -46,15 +47,22 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
continue;
}
EntityWrapper entity(m_World, modelComponent.EntityID);
// Don't render the local player
if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) {
continue;
}
Model* model;
try {
model = ResourceManager::Load<::Model, true>(resource);
} catch (const Resource::StillLoadingException&) {
//continue;
model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.obj");
model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.mesh");
} catch (const std::exception&) {
try {
model = ResourceManager::Load<::Model>("Models/Core/Error.obj");
model = ResourceManager::Load<::Model>("Models/Core/Error.mesh");
} catch (const std::exception&) {
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)
{
auto pointLights = m_World->GetComponents("PointLight");
@@ -155,11 +171,12 @@ void RenderSystem::Update(double dt)
{
m_EventBroker->Process<RenderSystem>();
if (m_CurrentCamera) {
ComponentWrapper cameraTransform = m_CurrentCamera["Transform"];
m_Camera->SetPosition(cameraTransform["Position"]);
m_Camera->SetOrientation(glm::quat((const glm::vec3&)cameraTransform["Orientation"]));
// Update the current camera used for rendering
if (m_CurrentCamera.Valid()) {
m_Camera->SetPosition(Transform::AbsolutePosition(m_CurrentCamera));
m_Camera->SetOrientation(Transform::AbsoluteOrientation(m_CurrentCamera));
}
//Only supports opaque geometry atm
RenderScene scene;
+2 -2
View File
@@ -13,9 +13,9 @@ void Renderer::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_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");*/
m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker);
}
+6 -2
View File
@@ -68,7 +68,7 @@ std::vector<glm::mat4> Skeleton::GetFrameBones(const Animation& animation, doubl
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe &currentFrame, 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()) {
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties.at(bone->ID);
@@ -84,10 +84,13 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf
positionInterp.z = 0;
}
boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp));
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
} 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;
}
@@ -95,6 +98,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf
std::string name = child->Name;
AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, progress, boneMatrices, child, boneMatrix);
}
}
int Skeleton::GetBoneID(std::string name)
+1 -1
View File
@@ -198,7 +198,7 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e)
(float&)(double)emitter["RollOffFactor"] = e.RollOffFactor;
(float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance;
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;
m_Sources[emitterID] = source;
playSound(source);
+2 -2
View File
@@ -57,7 +57,7 @@ Game::Game(int argc, char* argv[])
m_FrameStack->Height = m_Renderer->Resolution().Height;
// Create a world
m_World = new World();
m_World = new World(m_EventBroker);
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
if (!mapToLoad.empty()) {
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.
unsigned int updateOrderLevel = 0;
m_SystemPipeline->AddSystem<RaptorCopterSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel);
//m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
+1 -2
View File
@@ -12,7 +12,6 @@ HealthSystem::HealthSystem(World* m_World, EventBroker* eventBroker)
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)
ComponentWrapper player = m_World->GetComponent(component.EntityID, "Player");
double maxHealth = (double)component["MaxHealth"];
//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)
{
//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;
}
+33 -35
View File
@@ -1,35 +1,30 @@
#include "Systems/InterpolationSystem.h"
//void InterpolationSystem::UpdateComponent(World * world, ComponentWrapper & transform, double dt)
//{
// if (m_InterpolationPoints[transform.EntityID].size() > 0) {
// Transform& sTransform = m_InterpolationPoints[transform.EntityID].front();
// sTransform.interpolationTime += dt;
// if (sTransform.interpolationTime > 0.05) {
// double time = std::fmod(sTransform.interpolationTime, 0.05f);
// m_InterpolationPoints[transform.EntityID].pop();
// if (m_InterpolationPoints[transform.EntityID].size() <= 0) {
// return;
// }
// sTransform = m_InterpolationPoints[transform.EntityID].front();
// sTransform.interpolationTime = time;
// }
// glm::vec3 nextPosition = sTransform.Position;
// glm::vec3 currentPosition = static_cast<glm::vec3>(transform["Position"]);
// transform["Position"] = vectorInterpolation(currentPosition, nextPosition, sTransform.interpolationTime);
// }
//}
InterpolationSystem::InterpolationSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("Transform")
{
ConfigFile* config = ResourceManager::Load<ConfigFile>("Config.ini");
m_SnapshotInterval = config->Get<float>("Networking.SnapshotInterval", 0.05);
EVENT_SUBSCRIBE_MEMBER(m_EInterpolate, &InterpolationSystem::OnInterpolate);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &InterpolationSystem::OnPlayerSpawned);
}
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
m_NextTransform[transform.EntityID].interpolationTime += dt;
Transform sTransform = m_NextTransform[transform.EntityID];
double time = sTransform.interpolationTime;
if (time > SNAPSHOTINTERVAL) {
if (time > m_SnapshotInterval) {
if (m_LastReceivedTransform.find(transform.EntityID) != m_LastReceivedTransform.end()) {
m_NextTransform[transform.EntityID] = m_LastReceivedTransform[transform.EntityID];
m_NextTransform[transform.EntityID].interpolationTime = time - SNAPSHOTINTERVAL;
m_NextTransform[transform.EntityID].interpolationTime = time - m_SnapshotInterval;
sTransform = m_NextTransform[transform.EntityID];
m_LastReceivedTransform.erase(transform.EntityID);
} else {
@@ -37,14 +32,21 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe
}
}
if (transform.Info.Name == "Transform") {
bool isLocalPlayer = entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer);
// Position
glm::vec3 nextPosition = sTransform.Position;
glm::vec3 currentPosition = static_cast<glm::vec3>(transform["Position"]);
(glm::vec3&)transform["Position"] += vectorInterpolation<glm::vec3>(currentPosition, nextPosition, sTransform.interpolationTime);
// HACK: Don't force position for players
if (!isLocalPlayer) {
(glm::vec3&)transform["Position"] += vectorInterpolation<glm::vec3>(currentPosition, nextPosition, sTransform.interpolationTime);
}
// Orientation
glm::quat nextOrientation = sTransform.Orientation;
glm::quat currentOrientation = glm::quat(static_cast<glm::vec3>(transform["Orientation"]));
(glm::vec3&)transform["Orientation"] = glm::eulerAngles(glm::slerp<float>(currentOrientation, nextOrientation, sTransform.interpolationTime / SNAPSHOTINTERVAL));
// Don't force orientation for players
if (!isLocalPlayer) {
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
glm::vec3 nextScale = sTransform.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)
{
Transform transform;
@@ -72,15 +80,5 @@ bool InterpolationSystem::OnInterpolate(const Events::Interpolate & e)
} else { // Did not
m_NextTransform[e.Entity] = transform;
}
// Check if queue already exists
//if (m_InterpolationPoints.find(e.Entity) != m_InterpolationPoints.end()) { // Did exist, push to queue
// m_InterpolationPoints[e.Entity].push(transform);
//}
//else { // Did not exist, create queue
// std::queue<Transform> transformQueue;
// transformQueue.push(transform);
// m_InterpolationPoints[e.Entity] = transformQueue;
//}
return false;
}
+117 -3
View File
@@ -1,18 +1,132 @@
#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)
{
ComponentWrapper& cTransform = entity["Transform"];
if (!entity.HasComponent("Physics")) {
return;
}
ComponentWrapper& cPhysics = entity["Physics"];
ComponentWrapper& cPhysics = entity["Physics"];
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"]) {
velocity.y -= 9.82 * dt;
velocity.y -= 9.82f * (float)dt;
}
glm::vec3& position = cTransform["Position"];
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;
}
+64 -4
View File
@@ -4,6 +4,8 @@ PlayerSpawnSystem::PlayerSpawnSystem(World* m_World, EventBroker* eventBroker)
: System(m_World, eventBroker)
{
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)
@@ -13,7 +15,7 @@ void PlayerSpawnSystem::Update(double dt)
return;
}
for (auto& team : m_SpawnRequests) {
for (auto& req : m_SpawnRequests) {
for (auto& cPlayerSpawn : *playerSpawns) {
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
if (!spawner.HasComponent("Spawner")) {
@@ -22,7 +24,7 @@ void PlayerSpawnSystem::Update(double dt)
// If the spawner has a team affiliation, check it
if (spawner.HasComponent("Team")) {
if ((int)spawner["Team"]["Team"] != team) {
if ((int)spawner["Team"]["Team"] != req.Team) {
continue;
}
}
@@ -30,7 +32,15 @@ void PlayerSpawnSystem::Update(double dt)
// Spawn the player!
EntityWrapper player = SpawnerSystem::Spawn(spawner);
// 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();
@@ -42,10 +52,60 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e)
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) {
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;
}
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;
}
+56 -25
View File
@@ -5,49 +5,80 @@ WeaponSystem::WeaponSystem(World* world, EventBroker* eventBroker, IRenderer* re
, ImpureSystem()
, m_Renderer(renderer)
{
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &WeaponSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot);
}
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) {
m_EShootVector.erase(m_EShootVector.begin() + i - 1);
continue;
}
//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);
}
bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e)
{
if (e.PlayerID == -1) {
m_LocalPlayer = e.Player;
}
return true;
}
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) {
Events::Shoot eShoot;
eShoot.shooter = e.PlayerID;
eShoot.Player = m_LocalPlayer;
m_EventBroker->Publish(eShoot);
}
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();
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;
}
}
+8 -6
View File
@@ -27,7 +27,9 @@ using boost::unit_test_framework::test_case;
void RayTest(std::string fileName) {
//simple box test
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");
auto unitBox = ResourceManager::Load<RawModel>(fileName);
BOOST_REQUIRE(unitBox != nullptr);
@@ -106,7 +108,7 @@ BOOST_AUTO_TEST_CASE(collisionTest2)
BOOST_AUTO_TEST_CASE(rayVsModelTest)
{
//simple box test
RayTest("Models/Core/UnitCube.obj");
RayTest("Models/Core/UnitCube.mesh"); // 360NoScope Unitcube
}
BOOST_AUTO_TEST_CASE(rayVsModelTest2)
@@ -128,7 +130,7 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
someAABB = AABB(minPos, maxPos);
//using a rawmodel here, else we have to init the renderingsystem
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);
for (size_t i = 0; i < 1000000; i++)
@@ -187,19 +189,19 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
BOOST_AUTO_TEST_CASE(rayVsModelTest3)
{
//simple test
RayTest("Models/Core/UnitSphere.obj");
RayTest("Models/Core/UnitSphere.mesh"); // 360NoScope unitSphere
}
BOOST_AUTO_TEST_CASE(rayVsModelTest4)
{
//simple test
RayTest("Models/Core/UnitCylinder.obj");
RayTest("Models/Core/UnitCylinder.mesh"); // 360NoScope unitCylinder
}
BOOST_AUTO_TEST_CASE(rayVsModelTest5)
{
//simple test
RayTest("Models/Core/UnitRaptor.obj");
RayTest("Models/Core/UnitRaptor.mesh"); // 360NoScope unitRaptor
}
BOOST_AUTO_TEST_CASE(octTest)
{
+4 -4
View File
@@ -56,7 +56,7 @@ GameHealthSystemTest::GameHealthSystemTest()
EntityID playerID = m_World->CreateEntity();
ComponentWrapper transform = m_World->AttachComponent(playerID, "Transform");
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 health = m_World->AttachComponent(playerID, "Health");
healthsID = playerID;
@@ -69,8 +69,8 @@ GameHealthSystemTest::GameHealthSystemTest()
m_EventBroker->Publish(e3);
//damage player with 50
Events::PlayerDamage e;
e.DamageAmount = 50.0f;
e.PlayerDamagedID = healthsID;
e.Damage = 50.0f;
//e.Player = healthsID;
m_EventBroker->Publish(e);
//heal some other player with 40
Events::PlayerHealthPickup e2;
@@ -81,7 +81,7 @@ GameHealthSystemTest::GameHealthSystemTest()
EntityID playerID2 = m_World->CreateEntity();
ComponentWrapper transform2 = m_World->AttachComponent(playerID2, "Transform");
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 health2 = m_World->AttachComponent(playerID2, "Health");
//END TEST

Some files were not shown because too many files have changed in this diff Show More