Merge branch 'master' of https://github.com/teamfisk/TacticalZ into Importer

This commit is contained in:
antc13
2016-01-27 09:37:14 +01:00
71 changed files with 1861 additions and 439 deletions
+1 -1
Submodule assets updated: 7577819337...e4dc9529f2
+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__ #define EPlayerDamage_h__
#include "EventBroker.h" #include "EventBroker.h"
#include "../Core/Entity.h" #include "../Core/EntityWrapper.h"
namespace Events namespace Events
{ {
struct PlayerDamage : Event struct PlayerDamage : Event
{ {
double DamageAmount; EntityWrapper Player;
EntityID PlayerDamagedID; double Damage;
}; };
} }
+1
View File
@@ -12,6 +12,7 @@ struct PlayerSpawned : Event
int PlayerID; int PlayerID;
EntityWrapper Player; EntityWrapper Player;
EntityWrapper Spawner; EntityWrapper Spawner;
std::string PlayerName;
}; };
} }
+2 -4
View File
@@ -2,16 +2,14 @@
#define EShoot_h__ #define EShoot_h__
#include "EventBroker.h" #include "EventBroker.h"
#include "../Core/Entity.h" #include "../Core/EntityWrapper.h"
#include "Engine/GLM.h"
namespace Events namespace Events
{ {
struct Shoot : Event struct Shoot : Event
{ {
//ID for who made the shot EntityWrapper Player;
EntityID shooter;
}; };
} }
+6 -1
View File
@@ -23,9 +23,11 @@ struct EntityWrapper
static const EntityWrapper Invalid; static const EntityWrapper Invalid;
bool HasComponent(const std::string& componentName); const std::string Name();
bool HasComponent(const std::string& componentType);
EntityWrapper Parent(); EntityWrapper Parent();
EntityWrapper FirstChildByName(const std::string& name); EntityWrapper FirstChildByName(const std::string& name);
EntityWrapper FirstParentWithComponent(const std::string& componentType);
bool IsChildOf(EntityWrapper potentialParent); bool IsChildOf(EntityWrapper potentialParent);
bool Valid(); bool Valid();
@@ -34,6 +36,9 @@ struct EntityWrapper
bool operator!=(const EntityWrapper& e) const; bool operator!=(const EntityWrapper& e) const;
explicit operator EntityID() const; explicit operator EntityID() const;
operator bool(); operator bool();
private:
EntityWrapper firstChildByNameRecursive(const std::string& name, EntityID parent);
}; };
namespace std namespace std
+2
View File
@@ -8,8 +8,10 @@
namespace Transform namespace Transform
{ {
glm::mat4 AbsoluteTransformation(EntityWrapper entity);
glm::vec3 AbsolutePosition(EntityWrapper entity); glm::vec3 AbsolutePosition(EntityWrapper entity);
glm::vec3 AbsolutePosition(World* world, EntityID entity); glm::vec3 AbsolutePosition(World* world, EntityID entity);
glm::vec3 AbsoluteOrientationEuler(EntityWrapper entity);
glm::quat AbsoluteOrientation(EntityWrapper entity); glm::quat AbsoluteOrientation(EntityWrapper entity);
glm::quat AbsoluteOrientation(World* world, EntityID entity); glm::quat AbsoluteOrientation(World* world, EntityID entity);
glm::vec3 AbsoluteScale(EntityWrapper entity); glm::vec3 AbsoluteScale(EntityWrapper entity);
+6
View File
@@ -5,11 +5,15 @@
#include "Entity.h" #include "Entity.h"
#include "ObjectPool.h" #include "ObjectPool.h"
#include "ComponentPool.h" #include "ComponentPool.h"
#include "EventBroker.h"
class World class World
{ {
public: public:
World() = default; World() = default;
World(EventBroker* eventBroker)
: m_EventBroker(eventBroker)
{ }
~World(); ~World();
// Create empty entity // Create empty entity
@@ -46,6 +50,7 @@ public:
std::string GetName(EntityID entity) const; std::string GetName(EntityID entity) const;
private: private:
EventBroker* m_EventBroker = nullptr;
EntityID m_CurrentEntityID = 0; EntityID m_CurrentEntityID = 0;
std::unordered_map<EntityID, EntityID> m_EntityParents; std::unordered_map<EntityID, EntityID> m_EntityParents;
@@ -55,6 +60,7 @@ private:
std::unordered_map<EntityID, std::string> m_EntityNames; std::unordered_map<EntityID, std::string> m_EntityNames;
EntityID generateEntityID(); EntityID generateEntityID();
void deleteEntityRecursive(EntityID entity, bool cascaded = false);
}; };
#endif #endif
+2
View File
@@ -2,6 +2,7 @@
#define Events_InputCommand_h__ #define Events_InputCommand_h__
#include "Core/EventBroker.h" #include "Core/EventBroker.h"
#include "Core/EntityWrapper.h"
namespace Events namespace Events
{ {
@@ -10,6 +11,7 @@ struct InputCommand : Event
{ {
/** Numerical ID of the player. */ /** Numerical ID of the player. */
int PlayerID; int PlayerID;
EntityWrapper Player;
/** The command that was sent. */ /** The command that was sent. */
std::string Command; std::string Command;
/** The value of the command. */ /** The value of the command. */
+8 -1
View File
@@ -50,6 +50,7 @@ private:
PlayerID m_PlayerID = -1; PlayerID m_PlayerID = -1;
EntityID m_ServerEntityID = std::numeric_limits<EntityID>::max(); EntityID m_ServerEntityID = std::numeric_limits<EntityID>::max();
bool m_IsConnected = false; bool m_IsConnected = false;
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
// Server Client Lookup map // Server Client Lookup map
// Assumes that root node for client and server is EntityID 0. // Assumes that root node for client and server is EntityID 0.
@@ -79,12 +80,15 @@ private:
void parsePing(); void parsePing();
void parseKick(); void parseKick();
void parsePlayersSpawned(Packet& packet); void parsePlayersSpawned(Packet& packet);
void parseEntityDeletion(Packet& packet);
void parseComponentDeletion(Packet& packet);
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
void parseSnapshot(Packet& packet); void parseSnapshot(Packet& packet);
void identifyPacketLoss(); void identifyPacketLoss();
bool hasServerTimedOut(); bool hasServerTimedOut();
EntityID createPlayer(); EntityID createPlayer();
void sendInputCommands(); void sendInputCommands();
void sendLocalPlayerTransform();
void becomePlayer(); void becomePlayer();
// Mapping Logic // Mapping Logic
// Returns if local EntityID exist in map // Returns if local EntityID exist in map
@@ -92,13 +96,16 @@ private:
// Returns if server EntityID exist in map // Returns if server EntityID exist in map
bool serverClientMapsHasEntity(EntityID serverEntityID); bool serverClientMapsHasEntity(EntityID serverEntityID);
void insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID); void insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID);
void deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID);
// Events // Events
EventBroker* m_EventBroker; EventBroker* m_EventBroker;
EventRelay<Client, Events::InputCommand> m_EInputCommand; EventRelay<Client, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e); bool OnInputCommand(const Events::InputCommand& e);
EventRelay<Client, Events::PlayerDamage> m_EPlayeDamage; EventRelay<Client, Events::PlayerDamage> m_EPlayerDamage;
bool OnPlayerDamage(const Events::PlayerDamage& e); bool OnPlayerDamage(const Events::PlayerDamage& e);
EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
}; };
#endif #endif
+4 -1
View File
@@ -15,7 +15,10 @@ enum class MessageType
PlayerConnected, PlayerConnected,
BecomePlayer, BecomePlayer,
Kick, Kick,
OnPlayerSpawned OnPlayerSpawned,
EntityDeleted,
ComponentDeleted,
PlayerTransform
}; };
#endif #endif
+1 -2
View File
@@ -12,10 +12,9 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#define INPUTSIZE 4097 #define INPUTSIZE 32000
typedef unsigned int PlayerID; typedef unsigned int PlayerID;
typedef unsigned int PacketID; typedef unsigned int PacketID;
typedef unsigned int UserID;
class Network class Network
{ {
+2 -1
View File
@@ -1,9 +1,10 @@
#ifndef PlayerDefinition_h__ #ifndef PlayerDefinition_h__
#define PlayerDefinition_h__ #define PlayerDefinition_h__
#include <string> #include <string>
#include "../Core/Entity.h"
struct PlayerDefinition { struct PlayerDefinition {
int EntityID = -1; ::EntityID EntityID = EntityID_Invalid;
std::string Name = ""; std::string Name = "";
boost::asio::ip::udp::endpoint Endpoint; boost::asio::ip::udp::endpoint Endpoint;
unsigned int PacketID; unsigned int PacketID;
+12 -5
View File
@@ -16,6 +16,8 @@
#include "Core/EPlayerDamage.h" #include "Core/EPlayerDamage.h"
#include "Network/EPlayerDisconnected.h" #include "Network/EPlayerDisconnected.h"
#include "Core/EPlayerSpawned.h" #include "Core/EPlayerSpawned.h"
#include "Core/EEntityDeleted.h"
#include "Core/EComponentDeleted.h"
class Server : public Network class Server : public Network
{ {
@@ -31,8 +33,8 @@ private:
boost::asio::ip::udp::socket m_Socket; boost::asio::ip::udp::socket m_Socket;
// Sending messages to client logic // Sending messages to client logic
PlayerDefinition m_PlayerDefinitions[8]; // std::map<PlayerID, PlayerDefinition> m_ConnectedPlayers;
std::vector<PlayerDefinition> m_ConnectedUsers; // HACK: Fix INPUTSIZE
char readBuffer[INPUTSIZE] = { 0 }; char readBuffer[INPUTSIZE] = { 0 };
int bytesRead = 0; int bytesRead = 0;
// time for previouse message // time for previouse message
@@ -43,6 +45,7 @@ private:
int pingIntervalMs; int pingIntervalMs;
int snapshotInterval; int snapshotInterval;
int checkTimeOutInterval = 100; int checkTimeOutInterval = 100;
int m_NextPlayerID = 0;
//Timers //Timers
std::clock_t m_StartPingTime; std::clock_t m_StartPingTime;
@@ -58,14 +61,14 @@ private:
// Private member functions // Private member functions
int receive(char* data); int receive(char* data);
void readFromClients(); void readFromClients();
void send(Packet& packet, UserID user);
void send(PlayerID player, Packet& packet); void send(PlayerID player, Packet& packet);
void send(Packet& packet); void send(Packet& packet);
void broadcast(Packet& packet); void broadcast(Packet& packet);
void sendSnapshot(); void sendSnapshot();
void addChildrenToPacket(Packet& packet, EntityID entityID);
void sendPing(); void sendPing();
void checkForTimeOuts(); void checkForTimeOuts();
void disconnect(UserID user); void disconnect(PlayerID playerID);
void parseMessageType(Packet& packet); void parseMessageType(Packet& packet);
void parseOnInputCommand(Packet& packet); void parseOnInputCommand(Packet& packet);
void parseOnPlayerDamage(Packet& packet); void parseOnPlayerDamage(Packet& packet);
@@ -74,7 +77,6 @@ private:
void parseClientPing(); void parseClientPing();
void parsePing(); void parsePing();
void identifyPacketLoss(); void identifyPacketLoss();
void createPlayer();
void kick(PlayerID player); void kick(PlayerID player);
PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
// Debug event // Debug event
@@ -82,6 +84,11 @@ private:
bool OnInputCommand(const Events::InputCommand& e); bool OnInputCommand(const Events::InputCommand& e);
EventRelay<Server, Events::PlayerSpawned> m_EPlayerSpawned; EventRelay<Server, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(const Events::PlayerSpawned& e); bool OnPlayerSpawned(const Events::PlayerSpawned& e);
EventRelay<Server, Events::EntityDeleted> m_EEntityDeleted;
bool OnEntityDeleted(const Events::EntityDeleted& e);
EventRelay<Server, Events::ComponentDeleted> m_EComponentDeleted;
bool OnComponentDeleted(const Events::ComponentDeleted& e);
void parsePlayerTransform(Packet& packet);
}; };
#endif #endif
@@ -0,0 +1,29 @@
#ifndef AnimationSystem_h__
#define AnimationSystem_h__
#include "GLM.h"
#include "Common.h"
#include "Core/System.h"
#include "Core/ResourceManager.h"
#include "Rendering/Model.h"
#include "Rendering/EAnimationComplete.h"
#include "Rendering/Skeleton.h"
class AnimationSystem : public PureSystem
{
public:
AnimationSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("Animation")
{
}
~AnimationSystem() { }
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& animationComponent, double dt) override;
private:
};
#endif
@@ -0,0 +1,18 @@
#ifndef Events_AnimationComplete_h__
#define Events_AnimationComplete_h__
#include "../Core/EventBroker.h"
#include "../Core/EntityWrapper.h"
namespace Events
{
struct AnimationComplete : Event
{
EntityWrapper Entity;
std::string Name;
};
}
#endif
+21 -1
View File
@@ -13,10 +13,11 @@
#include "Camera.h" #include "Camera.h"
#include "../Core/World.h" #include "../Core/World.h"
#include "../Core/Transform.h" #include "../Core/Transform.h"
#include "Skeleton.h"
struct ModelJob : RenderJob struct ModelJob : RenderJob
{ {
ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialGroup matGroup, ComponentWrapper modelComponent, World* world) ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::RawModel::MaterialGroup matGroup, ComponentWrapper modelComponent, World* world, glm::vec4 fillColor, float fillPercentage)
: RenderJob() : RenderJob()
{ {
Model = model; Model = model;
@@ -37,6 +38,17 @@ struct ModelJob : RenderJob
glm::vec3 worldpos = glm::vec3(camera->ViewMatrix() * glm::vec4(abspos, 1)); glm::vec3 worldpos = glm::vec3(camera->ViewMatrix() * glm::vec4(abspos, 1));
Depth = worldpos.z; Depth = worldpos.z;
World = world; World = world;
FillColor = fillColor;
FillPercentage = fillPercentage;
Skeleton = Model->m_RawModel->m_Skeleton;
if (world->HasComponent(Entity, "Animation") && Skeleton != nullptr) {
auto animationComponent = world->GetComponent(Entity, "Animation");
Animation = model->m_RawModel->m_Skeleton->GetAnimation(animationComponent["Name"]);
AnimationTime = (double)animationComponent["Time"];
}
}; };
unsigned int TextureID; unsigned int TextureID;
@@ -51,6 +63,11 @@ struct ModelJob : RenderJob
float Shininess = 0.f; float Shininess = 0.f;
glm::vec4 Color; glm::vec4 Color;
const ::Model* Model = nullptr; const ::Model* Model = nullptr;
::Skeleton* Skeleton = nullptr;
const ::Skeleton::Animation* Animation = nullptr;
float AnimationTime = 0.f;
glm::vec4 DiffuseColor; glm::vec4 DiffuseColor;
glm::vec4 SpecularColor; glm::vec4 SpecularColor;
glm::vec4 IncandescenceColor; glm::vec4 IncandescenceColor;
@@ -58,6 +75,9 @@ struct ModelJob : RenderJob
unsigned int EndIndex = 0; unsigned int EndIndex = 0;
World* World; World* World;
glm::vec4 FillColor = glm::vec4(0);
float FillPercentage = 0.0;
void CalculateHash() override void CalculateHash() override
{ {
Hash = TextureID; Hash = TextureID;
+1 -4
View File
@@ -1,8 +1,6 @@
#ifndef PickingPass_h__ #ifndef PickingPass_h__
#define PickingPass_h__ #define PickingPass_h__
#include "IRenderer.h" #include "IRenderer.h"
#include "PickingPassState.h" #include "PickingPassState.h"
#include "FrameBuffer.h" #include "FrameBuffer.h"
@@ -10,8 +8,7 @@
#include "Util/UnorderedMapiVec2.h" #include "Util/UnorderedMapiVec2.h"
#include "../Core/EventBroker.h" #include "../Core/EventBroker.h"
#include "../Core/World.h" #include "../Core/World.h"
#include "Rendering/Skeleton.h"
class PickingPass class PickingPass
{ {
+1
View File
@@ -29,6 +29,7 @@ private:
const IRenderer* m_Renderer; const IRenderer* m_Renderer;
RenderFrame* m_RenderFrame; RenderFrame* m_RenderFrame;
Camera* m_Camera; Camera* m_Camera;
World* m_World;
EntityWrapper m_CurrentCamera = EntityWrapper::Invalid; EntityWrapper m_CurrentCamera = EntityWrapper::Invalid;
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid; EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
+1 -1
View File
@@ -24,7 +24,7 @@ public:
private: private:
//methods which will take care of specific events //methods which will take care of specific events
EventRelay<HealthSystem, Events::PlayerDamage> m_EPlayerDamage; EventRelay<HealthSystem, Events::PlayerDamage> m_EPlayerDamage;
bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e); bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e);
EventRelay<HealthSystem, Events::PlayerHealthPickup> m_EPlayerHealthPickup; EventRelay<HealthSystem, Events::PlayerHealthPickup> m_EPlayerHealthPickup;
bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e); bool HealthSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup& e);
+21
View File
@@ -0,0 +1,21 @@
#ifndef LifetimeSystem_h__
#define LifetimeSystem_h__
#include "Core/System.h"
class LifetimeSystem : public ImpureSystem, PureSystem
{
public:
LifetimeSystem(World* world, EventBroker* eventBroker)
: System(world, eventBroker)
, PureSystem("Lifetime")
{ }
virtual void Update(double dt) override;
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cLifetime, double dt) override;
private:
std::vector<EntityWrapper> m_Deletions;
};
#endif
+23
View File
@@ -0,0 +1,23 @@
#ifndef PlayerHUD_h__
#define PlayerHUD_h__
#include "../../Engine/Core/System.h"
#include "../../Engine/GLM.h"
#include "../../Engine/Rendering/ESetCamera.h"
#include <imgui/imgui.h>
class PlayerHUD : public ImpureSystem
{
public:
PlayerHUD(World* world, EventBroker* eventBrokerer);
~PlayerHUD();
virtual void Update(double dt) override;
private:
World* m_World;
EventBroker* m_EventBroker;
};
#endif
+13 -8
View File
@@ -9,7 +9,10 @@
#include "Core/System.h" #include "Core/System.h"
#include "Core/EPlayerDamage.h" #include "Core/EPlayerDamage.h"
#include "Core/EShoot.h" #include "Core/EShoot.h"
#include "Core/EPlayerSpawned.h"
#include "Input/EInputCommand.h" #include "Input/EInputCommand.h"
#include "Core/EntityFile.h"
#include "Core/EntityFileParser.h"
#include <tuple> #include <tuple>
#include <vector> #include <vector>
@@ -23,16 +26,18 @@ public:
virtual void Update(double dt) override; virtual void Update(double dt) override;
private: private:
//methods which will take care of specific events
EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
bool WeaponSystem::OnShoot(const Events::Shoot& e);
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e);
IRenderer* m_Renderer; IRenderer* m_Renderer;
std::vector<std::tuple<EntityID, glm::vec2>> m_EShootVector; // State
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
// Events
EventRelay<WeaponSystem, Events::PlayerSpawned> m_EPlayerSpawned;
bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e);
EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
bool WeaponSystem::OnShoot(Events::Shoot& e);
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e);
}; };
#endif #endif
+2 -1
View File
@@ -21,4 +21,5 @@ F1=ToggleEditor
X=EditorToggleTransformSpace X=EditorToggleTransformSpace
C=ConnectToServer C=ConnectToServer
N=SwitchToServer N=SwitchToServer
M=SwitchToClient M=SwitchToClient
P=SwitchToPlayer
+4
View File
@@ -23,4 +23,8 @@
<xs:include schemaLocation="Components/Team.xsd"/> <xs:include schemaLocation="Components/Team.xsd"/>
<xs:include schemaLocation="Components/UniformScale.xsd"/> <xs:include schemaLocation="Components/UniformScale.xsd"/>
<xs:include schemaLocation="Components/EditorWidget.xsd"/> <xs:include schemaLocation="Components/EditorWidget.xsd"/>
<xs:include schemaLocation="Components/HealthHUD.xsd"/>
<xs:include schemaLocation="Components/Animation.xsd"/>
<xs:include schemaLocation="Components/Fill.xsd"/>
<xs:include schemaLocation="Components/Lifetime.xsd"/>
</xs:schema> </xs:schema>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Animation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Animation.xsd">
<Time>0</Time>
<Speed>0</Speed>
<Loop>true</Loop>
</Animation>
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="Animation">
<xs:complexType>
<xs:all>
<xs:element name="Name" type="t:string" minOccurs="0"/>
<xs:element name="Time" type="t:double" minOccurs="0"/>
<xs:element name="Speed" type="t:double" minOccurs="0"/>
<xs:element name="Loop" type="t:bool" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Fill xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Fill.xsd">
<Percentage>0.0</Percentage>
<Color R="1" G="1" B="1" A="1"/>
</Fill>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="Fill">
<xs:complexType>
<xs:all>
<xs:element name="Percentage" type="t:double" minOccurs="0"/>
<xs:element name="Color" type="t:Color" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Listener xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Listener.xsd"/>
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="HealthHUD">
</xs:element>
</xs:schema>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Lifetime xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Animation.xsd">
<Lifetime>0</Lifetime>
</Animation>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="types">
<xs:import schemaLocation="../Types.xsd" namespace="types"/>
<xs:element name="Lifetime">
<xs:complexType>
<xs:all>
<xs:element name="Lifetime" type="t:double" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
+1 -1
View File
@@ -5,7 +5,7 @@
<c:AABB/> <c:AABB/>
<c:Collidable/> <c:Collidable/>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
+1 -11
View File
@@ -5,16 +5,6 @@
<c:Transform/> <c:Transform/>
</Components> </Components>
<Children> <Children/>
<Entity>
<Components>
<c:Model>
<Resource></Resource>
</c:Model>
<c:Transform/>
</Components>
<Children/>
</Entity>
</Children>
</Entity> </Entity>
+72
View File
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="GotToGoFast" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform>
<Position X="0" Y="-0.00432979874" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Model>
<Resource>Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="39.2156868" R="392.15686"/>
</c:Model>
<c:RaptorCopter>
<Axis X="1.50000012" Y="-2.20000005" Z="2.10000014"/>
</c:RaptorCopter>
<c:Transform>
<Position X="0" Y="2.87819886" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Animation>
<Name>Crouch Walk</Name>
<Time>701.10570384634161</Time>
<Speed>32</Speed>
</c:Animation>
<c:Model>
<Resource>Models/AssaultAnimated.mesh</Resource>
<Color A="1" B="392156.875" G="1" R="1"/>
</c:Model>
<c:Transform>
<Position X="0" Y="0.5" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Text>
<Content>pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew pew </Content>
<Resource>Fonts/DroidSans.ttf,60</Resource>
<Color A="0" B="0.972549021" G="3.92156863" R="39.2156868"/>
<Alignment>
<Left/>
</Alignment>
</c:Text>
<c:Transform>
<Position X="0.245514169" Y="0.817000031" Z="-0.883219421"/>
<Scale X="0.300000012" Y="0.300000012" Z="1"/>
<Orientation X="0" Y="1.52600002" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:DirectionalLight/>
<c:Transform/>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+243
View File
@@ -0,0 +1,243 @@
<?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>
<Entity name="BluSpawn">
<Components>
<c:PlayerSpawn/>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Visible>false</Visible>
</c:Model>
<c:Spawner>
<EntityFile>Schema/Entities/Player.xml</EntityFile>
</c:Spawner>
<c:Team>
<Team>
<Blue/>
</Team>
</c:Team>
<c:Transform>
<Position X="57.7363472" Y="1.18853188" Z="79.5"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:SpawnPoint/>
<c:Transform/>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:SpawnPoint/>
<c:Transform>
<Position X="-2.05988312" Y="0" Z="2.79573512"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="1.85022807" Y="0" Z="-2.08909845"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="2.98651481" Y="0" Z="-4.67667246"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="-5.16323137" Y="0" Z="3.62892342"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity name="RedSpawn">
<Components>
<c:PlayerSpawn/>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Visible>false</Visible>
</c:Model>
<c:Spawner>
<EntityFile>Schema/Entities/Player.xml</EntityFile>
</c:Spawner>
<c:Team>
<Team>
<Red/>
</Team>
</c:Team>
<c:Transform>
<Position X="-60.2567062" Y="1.60000002" Z="-78.1000061"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:SpawnPoint/>
<c:Transform/>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="0" Y="0" Z="2.24403"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="2.20245028" Y="0" Z="-1.97843659"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Transform>
<Position X="4.79769945" Y="0" Z="-5.2088728"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
+117 -1
View File
@@ -146,7 +146,6 @@
</c:Team> </c:Team>
<c:Transform> <c:Transform>
<Position X="0.300000012" Y="0.0270000007" Z="6.67400026"/> <Position X="0.300000012" Y="0.0270000007" Z="6.67400026"/>
<Orientation X="0" Y="3.20700026" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -178,6 +177,123 @@
</Entity> </Entity>
</Children> </Children>
</Entity> </Entity>
<Entity name="Player">
<Components>
<c:AABB>
<Origin X="0" Y="0.772000015" Z="0"/>
<Size X="1" Y="1.60000002" Z="1"/>
</c:AABB>
<c:Collidable/>
<c:Model/>
<c:Physics>
<Gravity>false</Gravity>
</c:Physics>
<c:Player>
<MovementSpeed>5</MovementSpeed>
</c:Player>
<c:Team>
<Team>
<Red/>
</Team>
</c:Team>
<c:Transform>
<Position X="-1.68112314" Y="0.0264999866" Z="3.06287026"/>
<Orientation X="0" Y="2.14675093" Z="0"/>
</c:Transform>
</Components>
<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>
</Children> </Children>
</Entity> </Entity>
+74 -11
View File
@@ -2,14 +2,14 @@
<Entity name="Player" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd"> <Entity name="Player" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components> <Components>
<c:Health/>
<c:AABB> <c:AABB>
<Origin X="0" Y="0.772000015" Z="0"/> <Origin X="0" Y="0.772000015" Z="0"/>
<Size X="1" Y="1.60000002" Z="1"/> <Size X="1" Y="1.60000002" Z="1"/>
</c:AABB> </c:AABB>
<c:Collidable/> <c:Collidable/>
<c:Model/>
<c:Physics> <c:Physics>
<Velocity X="8.33307467e-09" Y="0" Z="9.82836834e-09"/> <Velocity X="2.30999646e-23" Y="0" Z="1.05272533e-23"/>
</c:Physics> </c:Physics>
<c:Player> <c:Player>
<MovementSpeed>5</MovementSpeed> <MovementSpeed>5</MovementSpeed>
@@ -20,8 +20,7 @@
</Team> </Team>
</c:Team> </c:Team>
<c:Transform> <c:Transform>
<Position X="2.84928203" Y="0.0264999866" Z="7.31610918"/> <Orientation X="0" Y="2.24449515" Z="0"/>
<Orientation X="0" Y="2.14675093" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
@@ -31,7 +30,6 @@
<c:Camera/> <c:Camera/>
<c:Transform> <c:Transform>
<Position X="0" Y="1.37700009" Z="0"/> <Position X="0" Y="1.37700009" Z="0"/>
<Orientation X="0.921535373" Y="0" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
@@ -40,10 +38,9 @@
<c:Text> <c:Text>
<Resource>Fonts/DroidSans.ttf,100</Resource> <Resource>Fonts/DroidSans.ttf,100</Resource>
<Color A="1" B="0" G="1" R="0"/> <Color A="1" B="0" G="1" R="0"/>
<Visible>false</Visible>
</c:Text> </c:Text>
<c:Transform> <c:Transform>
<Position X="0" Y="0.247910097" Z="-0.447844714"/> <Position X="0.100000001" Y="0.248000011" Z="-0.248000011"/>
<Scale X="0.100000001" Y="0.113000005" Z="0.5"/> <Scale X="0.100000001" Y="0.113000005" Z="0.5"/>
<Orientation X="0" Y="3.14199996" Z="0"/> <Orientation X="0" Y="3.14199996" Z="0"/>
</c:Transform> </c:Transform>
@@ -54,6 +51,7 @@
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Camera.mesh</Resource> <Resource>Models/Camera.mesh</Resource>
<Visible>false</Visible>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="0" Y="0.0331346765" Z="-0.0792061687"/> <Position X="0" Y="0.0331346765" Z="-0.0792061687"/>
@@ -62,6 +60,67 @@
</Components> </Components>
<Children/> <Children/>
</Entity> </Entity>
<Entity name="HUD">
<Components>
<c:Transform>
<Position X="0" Y="0" Z="-0.5"/>
</c:Transform>
</Components>
<Children>
<Entity name="HealthBar">
<Components>
<c:Fill>
<Percentage>1</Percentage>
<Color A="0" B="1" G="0" R="0"/>
</c:Fill>
<c:HealthHUD/>
<c:Model>
<Resource>Models/Core/UnitHexagon.mesh</Resource>
<Color A="1" B="0.70588237" G="0.70588237" R="0.70588237"/>
</c:Model>
<c:Transform>
<Position X="-0.383000016" Y="-0.185000002" Z="0"/>
<Scale X="0.150000006" Y="0.150000006" Z="0.150000006"/>
<Orientation X="0" Y="0.594000041" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="Crosshair">
<Components>
<c:Model>
<Resource>Models/CrosshairQuad.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="0" Z="0.200000003"/>
<Scale X="0.00600000005" Y="1" Z="0.00600000005"/>
<Orientation X="1.57000005" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="Weapon">
<Components>
<c:Model>
<Resource>Models/AssaultWeapon.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0.180000007" Y="-0.183000013" Z="0"/>
<Orientation X="0" Y="4.64700031" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="WeaponMuzzle">
<Components>
<c:Transform>
<Position X="0.215000004" Y="-0.153000012" Z="-0.266000003"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children> </Children>
</Entity> </Entity>
<Entity name="ThirdPersonCamera"> <Entity name="ThirdPersonCamera">
@@ -80,12 +139,16 @@
</Entity> </Entity>
<Entity name="PlayerModel"> <Entity name="PlayerModel">
<Components> <Components>
<c:Animation>
<Name>Hold Pos</Name>
<Time>0.9779997896222552</Time>
<Speed>1</Speed>
</c:Animation>
<c:Model> <c:Model>
<Resource>Models/AssaultHeadless.mesh</Resource> <Resource>Models/AssaultAnimated.mesh</Resource>
<Color A="1" B="0" G="0" R="1"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform/>
<Orientation X="0" Y="3.14159274" Z="0"/>
</c:Transform>
</Components> </Components>
<Children/> <Children/>
</Entity> </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>
+17
View File
@@ -0,0 +1,17 @@
<?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:Model>
<Resource>Models/Core/UnitCylinder.mesh</Resource>
<Color A="0" B="0" G="0" R="39.2156868"/>
</c:Model>
<c:Transform>
<Scale X="0.0400000028" Y="26.2000008" Z="0.0400000028"/>
<Orientation X="1.57070005" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
+19
View File
@@ -0,0 +1,19 @@
<?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:Lifetime>
<Lifetime>0.25</Lifetime>
</c:Lifetime>
<c:Model>
<Resource>Models/CylinderBullet.mesh</Resource>
<Color A="1" B="39.2156868" G="7.84313726" R="0"/>
</c:Model>
<c:Transform>
<Scale X="0.0109999999" Y="0.0289999992" Z="100"/>
</c:Transform>
</Components>
<Children/>
</Entity>
+17
View File
@@ -0,0 +1,17 @@
<?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:Model>
<Resource>Models/Core/UnitCylinder.mesh</Resource>
<Color A="0" B="0" G="0" R="39.2156868"/>
</c:Model>
<c:Transform>
<Scale X="0.0400000028" Y="26.2000008" Z="0.0400000028"/>
<Orientation X="1.57070005" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
+19
View File
@@ -0,0 +1,19 @@
<?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:Lifetime>
<Lifetime>0.25</Lifetime>
</c:Lifetime>
<c:Model>
<Resource>Models/CylinderBullet.mesh</Resource>
<Color A="1" B="0" G="0.525490224" R="39.2156868"/>
</c:Model>
<c:Transform>
<Scale X="0.0110000009" Y="0.029000001" Z="100"/>
</c:Transform>
</Components>
<Children/>
</Entity>
+154 -65
View File
@@ -6,34 +6,115 @@
</Components> </Components>
<Children> <Children>
<Entity> <Entity name="Player">
<Components> <Components>
<c:Camera> <c:Health>
<Name>ActionCamera</Name> <Health>65.990005493164063</Health>
</c:Camera> </c:Health>
<c:Model> <c:Player/>
<Resource>Models/Camera.mesh</Resource>
</c:Model>
<c:Transform> <c:Transform>
<Position X="-0.504807115" Y="6.00582743" Z="9.68687439"/> <Position X="0" Y="0" Z="2.5"/>
<Orientation X="-0.733036518" Y="0.000105090476" Z="5.12391125e-07"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
<Entity> <Entity name="Model">
<Components> <Components>
<c:Text> <c:Model>
<Content>Camera #2</Content> <Resource>Models/Assault.obj</Resource>
<Resource>Fonts/DroidSans.ttf,64</Resource> <Color A="1" B="3.92156863" G="3.92156863" R="3.92156863"/>
<Alignment>0</Alignment> </c:Model>
</c:Text>
<c:Transform> <c:Transform>
<Position X="0.700063765" Y="0.310270816" Z="-1"/> <Orientation X="0" Y="3.14159203" Z="0"/>
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children/> <Children/>
</Entity> </Entity>
<Entity name="Camera">
<Components>
<c:Camera>
<FOV>80</FOV>
</c:Camera>
<c:Model>
<Resource>Models/Camera.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="1.39121652" Z="-0.043014247"/>
<Orientation X="6.28300047" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity name="HUD">
<Components>
<c:Transform>
<Position X="0" Y="-0.000463247066" Z="-0.744767368"/>
</c:Transform>
</Components>
<Children>
<Entity name="Hexagon">
<Components>
<c:HealthHUD/>
<c:Fill>
<Percentage>0.65990006923675537</Percentage>
<Color A="0" B="0.659900069" G="0" R="0.340099931"/>
</c:Fill>
<c:Model>
<Resource>Models/Core/UnitHexagon.mesh</Resource>
<Color A="0.313725501" B="0.70588237" G="0.70588237" R="0.70588237"/>
</c:Model>
<c:Transform>
<Position X="-0.285538822" Y="-0.282350302" Z="-1.52214652e-05"/>
<Scale X="0.200000003" Y="0.200000003" Z="0.5"/>
<Orientation X="0" Y="0.666000009" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity name="Ammo">
<Components>
<c:Text>
<Content>24</Content>
<Resource>Fonts/DroidSans.ttf,60</Resource>
</c:Text>
<c:Transform>
<Position X="-1.43861985e-06" Y="0.0125972452" Z="0.0100018298"/>
<Scale X="0.349999994" Y="0.349999994" Z="0.200000003"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Text>
<Content>262</Content>
<Resource>Fonts/DroidSans.ttf,60</Resource>
</c:Text>
<c:Transform>
<Position X="-4.27209579e-06" Y="-0.0390000008" Z="5.43686883e-06"/>
<Scale X="0.65200001" Y="0.643000007" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:HealthHUD/>
<c:Text>
<Content>65/100</Content>
<Resource>Fonts/DroidSans.ttf,60</Resource>
<Color A="1" B="0.659900069" G="0" R="0.340099931"/>
</c:Text>
<c:Transform>
<Scale X="0.200000003" Y="0.200000003" Z="0.200000003"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
</Children> </Children>
</Entity> </Entity>
<Entity> <Entity>
@@ -42,7 +123,7 @@
<Resource>Models/Core/UnitPlane.mesh</Resource> <Resource>Models/Core/UnitPlane.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="0" Y="-1" Z="0.600000024"/> <Position X="0" Y="-0.689623177" Z="0.600000024"/>
<Scale X="100" Y="1" Z="100"/> <Scale X="100" Y="1" Z="100"/>
</c:Transform> </c:Transform>
</Components> </Components>
@@ -52,6 +133,7 @@
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Assault.mesh</Resource> <Resource>Models/Assault.mesh</Resource>
<Color A="1" B="3.92156863" G="1" R="1"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="-2.5" Y="0" Z="1"/> <Position X="-2.5" Y="0" Z="1"/>
@@ -64,6 +146,7 @@
<c:Text> <c:Text>
<Content>Welcome!</Content> <Content>Welcome!</Content>
<Resource>Fonts/DroidSans.ttf,1280</Resource> <Resource>Fonts/DroidSans.ttf,1280</Resource>
<Color A="0" B="3.92156863" G="3.92156863" R="3.92156863"/>
</c:Text> </c:Text>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="0.700000048"/> <Position X="0" Y="0" Z="0.700000048"/>
@@ -74,32 +157,40 @@
<Entity> <Entity>
<Components> <Components>
<c:RaptorCopter> <c:RaptorCopter>
<Speed>2</Speed> <Speed>3</Speed>
<Axis X="0" Y="1" Z="0"/> <Axis X="0.200000003" Y="3.4000001" Z="0.5"/>
</c:RaptorCopter> </c:RaptorCopter>
<c:Transform> <c:Transform>
<Position X="0" Y="2.37320328" Z="0"/> <Orientation X="758.058899" Y="20632.8691" Z="1320.68018"/>
<Orientation X="0" Y="8252.15918" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
<Entity> <Entity>
<Components> <Components>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="7.84313726" G="0" R="7.84313726"/>
</c:Model>
<c:PointLight> <c:PointLight>
<Color A="1" B="1" G="0" R="1"/> <Color A="1" B="1" G="0" R="1"/>
<Radius>6</Radius> <Radius>70</Radius>
<Intensity>0.5</Intensity> <Intensity>0.5</Intensity>
</c:PointLight> </c:PointLight>
<c:Transform> <c:Transform>
<Position X="-2.5" Y="0" Z="0"/> <Position X="-2.5" Y="0" Z="0"/>
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
<Entity> <Entity>
<Components> <Components>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="0" G="0" R="7.84313726"/>
</c:Model>
<c:PointLight> <c:PointLight>
<Color A="1" B="0" G="0" R="1"/> <Color A="1" B="0" G="0" R="1"/>
<Radius>8</Radius> <Radius>70</Radius>
</c:PointLight> </c:PointLight>
<c:Transform> <c:Transform>
<Position X="-5" Y="0" Z="0"/> <Position X="-5" Y="0" Z="0"/>
@@ -111,21 +202,30 @@
</Entity> </Entity>
<Entity> <Entity>
<Components> <Components>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="0" G="7.84313726" R="7.84313726"/>
</c:Model>
<c:PointLight> <c:PointLight>
<Color A="1" B="0" G="1" R="1"/> <Color A="1" B="0" G="1" R="1"/>
<Radius>6</Radius> <Radius>70</Radius>
<Intensity>0.5</Intensity> <Intensity>0.5</Intensity>
</c:PointLight> </c:PointLight>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="-2.5"/> <Position X="0" Y="0" Z="-2.5"/>
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
<Entity> <Entity>
<Components> <Components>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="0" G="7.84313726" R="0"/>
</c:Model>
<c:PointLight> <c:PointLight>
<Color A="1" B="0" G="1" R="0"/> <Color A="1" B="0" G="1" R="0"/>
<Radius>8</Radius> <Radius>70</Radius>
</c:PointLight> </c:PointLight>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="-5"/> <Position X="0" Y="0" Z="-5"/>
@@ -137,21 +237,30 @@
</Entity> </Entity>
<Entity> <Entity>
<Components> <Components>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="7.84313726" G="7.84313726" R="0"/>
</c:Model>
<c:PointLight> <c:PointLight>
<Color A="1" B="1" G="1" R="0"/> <Color A="1" B="1" G="1" R="0"/>
<Radius>6</Radius> <Radius>70</Radius>
<Intensity>0.5</Intensity> <Intensity>0.5</Intensity>
</c:PointLight> </c:PointLight>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="2.5"/> <Position X="0" Y="0" Z="2.5"/>
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
<Entity> <Entity>
<Components> <Components>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="7.84313726" G="0" R="0"/>
</c:Model>
<c:PointLight> <c:PointLight>
<Color A="1" B="1" G="0.00784313772" R="0"/> <Color A="1" B="1" G="0" R="0"/>
<Radius>8</Radius> <Radius>70</Radius>
</c:PointLight> </c:PointLight>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="5"/> <Position X="0" Y="0" Z="5"/>
@@ -163,19 +272,28 @@
</Entity> </Entity>
<Entity> <Entity>
<Components> <Components>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="7.84313726" G="7.84313726" R="7.84313726"/>
</c:Model>
<c:PointLight> <c:PointLight>
<Radius>6</Radius> <Radius>70</Radius>
<Intensity>0.5</Intensity> <Intensity>0.5</Intensity>
</c:PointLight> </c:PointLight>
<c:Transform> <c:Transform>
<Position X="2.5" Y="0" Z="0"/> <Position X="2.5" Y="0" Z="0"/>
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children> <Children>
<Entity> <Entity>
<Components> <Components>
<c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource>
<Color A="1" B="7.84313726" G="7.84313726" R="7.84313726"/>
</c:Model>
<c:PointLight> <c:PointLight>
<Radius>8</Radius> <Radius>70</Radius>
</c:PointLight> </c:PointLight>
<c:Transform> <c:Transform>
<Position X="5" Y="0" Z="0"/> <Position X="5" Y="0" Z="0"/>
@@ -191,6 +309,7 @@
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Assault.mesh</Resource> <Resource>Models/Assault.mesh</Resource>
<Color A="1" B="1" G="1" R="3.92156863"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="2.5" Y="0" Z="1"/> <Position X="2.5" Y="0" Z="1"/>
@@ -198,46 +317,15 @@
</Components> </Components>
<Children/> <Children/>
</Entity> </Entity>
<Entity> <Entity name="DirectionalLight">
<Components>
<c:Camera>
<Name>MainCamera</Name>
</c:Camera>
<c:Listener/>
<c:Model>
<Resource>Models/Camera.mesh</Resource>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="-1.27354908" Y="5.18422079" Z="10.6223917"/>
<Orientation X="-0.436328411" Y="-0.0523675606" Z="1.67869363e-08"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:Text>
<Content>Taiwan #1</Content>
<Resource>Fonts/DroidSans.ttf,64</Resource>
<Alignment>0</Alignment>
</c:Text>
<c:Transform>
<Position X="0.716896772" Y="0.296712071" Z="-1"/>
<Scale X="0.100000001" Y="0.100000001" Z="0.100000001"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity>
<Components> <Components>
<c:DirectionalLight> <c:DirectionalLight>
<Color A="1" B="0.996078432" G="1" R="1"/> <Color A="1" B="0.996078432" G="1" R="1"/>
<Intensity>0.80000001192092896</Intensity> <Intensity>0.10000000149011612</Intensity>
</c:DirectionalLight> </c:DirectionalLight>
<c:Model> <c:Model>
<Resource>Models/DirectionalLightWidget.mesh</Resource> <Resource>Models/DirectionalLightWidget.mesh</Resource>
<Color A="1" B="0" G="3.92156863" R="3.92156863"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="-0.0013256073" Y="1.89540339" Z="6.53467274"/> <Position X="-0.0013256073" Y="1.89540339" Z="6.53467274"/>
@@ -250,6 +338,7 @@
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="39.2156868" R="1"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="-5.4082036" Y="0" Z="-1.84950542"/> <Position X="-5.4082036" Y="0" Z="-1.84950542"/>
+32
View File
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="BluSpawn" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:PlayerSpawn/>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model>
<c:Spawner>
<EntityFile>Schema/Entities/Player.xml</EntityFile>
</c:Spawner>
<c:Team>
<Team>
<Blue/>
</Team>
</c:Team>
<c:Transform>
<Position X="57.7363472" Y="1.18853188" Z="79.5"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:SpawnPoint/>
<c:Transform/>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+1
View File
@@ -32,6 +32,7 @@
<xs:element ref="c:DirectionalLight" minOccurs="0"/> <xs:element ref="c:DirectionalLight" minOccurs="0"/>
<xs:element ref="c:UniformScale" minOccurs="0"/> <xs:element ref="c:UniformScale" minOccurs="0"/>
<xs:element ref="c:EditorWidget" minOccurs="0"/> <xs:element ref="c:EditorWidget" minOccurs="0"/>
<xs:element ref="c:Lifetime" minOccurs="0"/>
</xs:all> </xs:all>
</xs:complexType> </xs:complexType>
</xs:element> </xs:element>
+17 -2
View File
@@ -6,9 +6,12 @@ uniform mat4 P;
uniform vec4 Color; uniform vec4 Color;
uniform vec4 DiffuseColor; uniform vec4 DiffuseColor;
uniform vec2 ScreenDimensions; uniform vec2 ScreenDimensions;
uniform vec4 FillColor;
uniform float FillPercentage;
layout (binding = 0) uniform sampler2D DiffuseTexture; layout (binding = 0) uniform sampler2D DiffuseTexture;
layout (binding = 1) uniform sampler2D GlowMap; layout (binding = 1) uniform sampler2D GlowMap;
#define TILE_SIZE 16 #define TILE_SIZE 16
struct LightSource { struct LightSource {
@@ -136,10 +139,21 @@ void main()
//sceneColor += Input.DiffuseColor; //sceneColor += Input.DiffuseColor;
vec4 color_result = DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color; vec4 color_result = DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color;
float pos = ((P * vec4(Input.Position, 1)).y + 1.0)/2.0;
if(pos <= FillPercentage) {
color_result += FillColor;
}
//bloomColor = vec4(0.3, 0.8, 0.6, 1.0); //bloomColor = vec4(0.3, 0.8, 0.6, 1.0);
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
//These if statements should be removed if they are slow. //These if statements should be removed if they are slow.
color_result += glowTexel; color_result += glowTexel;
bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0); bloomColor = vec4(clamp(color_result.xyz - 1.0, 0, 100), 1.0);
/* /*
if(color_result.x > 1 || color_result.y > 1 || color_result.z > 1) { if(color_result.x > 1 || color_result.y > 1 || color_result.z > 1) {
@@ -150,8 +164,9 @@ void main()
//sceneColor += Input.DiffuseColor * (totalLighting.Diffuse) * diffuseTexel * Color; //sceneColor += Input.DiffuseColor * (totalLighting.Diffuse) * diffuseTexel * Color;
//sceneColor += Input.DiffuseColor + vec4(0.0, LightGrids.Data[currentTile].Amount/3, 0, 1); //sceneColor += Input.DiffuseColor + vec4(0.0, LightGrids.Data[currentTile].Amount/3, 0, 1);
//sceneColor = diffuseTexel * Input.DiffuseColor * Color;
//sceneColor += vec4(currentTile/3600.f, 0, 0, 1);
//Tiled Debug Code //Tiled Debug Code
/* /*
+12 -8
View File
@@ -3,18 +3,15 @@
uniform mat4 M; uniform mat4 M;
uniform mat4 V; uniform mat4 V;
uniform mat4 P; uniform mat4 P;
uniform mat4 Bones[100];
layout(location = 0) in vec3 Position; layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal; layout(location = 1) in vec3 Normal;
layout(location = 2) in vec3 Tangent; layout(location = 2) in vec3 Tangent;
layout(location = 3) in vec3 BiTangent; layout(location = 3) in vec3 BiTangent;
layout(location = 4) in vec2 TextureCoords; layout(location = 4) in vec2 TextureCoords;
layout(location = 5) in vec4 DiffuseVertexColor; layout(location = 5) in vec4 BoneIndices;
layout(location = 6) in vec4 SpecularVertexColor; layout(location = 6) in vec4 BoneWeights;
layout(location = 7) in vec4 BoneIndices1;
layout(location = 8) in vec4 BoneIndices2;
layout(location = 9) in vec4 BoneWeights1;
layout(location = 10) in vec4 BoneWeights2;
out VertexData{ out VertexData{
vec3 Position; vec3 Position;
@@ -22,7 +19,14 @@ out VertexData{
void main() void main()
{ {
gl_Position = P * V* M * vec4(Position, 1.0); 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])];
}
Output.Position = Position; gl_Position = P*V*M*boneTransform * vec4(Position, 1.0);
Output.Position = (boneTransform * vec4(Position, 1.0)).xyz;
} }
+40 -8
View File
@@ -3,6 +3,11 @@
const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Invalid); const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Invalid);
const std::string EntityWrapper::Name()
{
return World->GetName(ID);
}
bool EntityWrapper::HasComponent(const std::string& componentName) bool EntityWrapper::HasComponent(const std::string& componentName)
{ {
if (!Valid()) { if (!Valid()) {
@@ -22,17 +27,18 @@ EntityWrapper EntityWrapper::Parent()
EntityWrapper EntityWrapper::FirstChildByName(const std::string& name) EntityWrapper EntityWrapper::FirstChildByName(const std::string& name)
{ {
auto itPair = this->World->GetChildren(this->ID); return firstChildByNameRecursive(name, this->ID);
if (itPair.first == itPair.second) { }
return EntityWrapper::Invalid;
}
for (auto it = itPair.first; it != itPair.second; ++it) { EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& componentType)
if (this->World->GetName(it->second) == name) { {
return EntityWrapper(this->World, it->second); EntityWrapper entity = *this;
while (entity.Parent().Valid()) {
entity = entity.Parent();
if (entity.HasComponent(componentType)) {
return entity;
} }
} }
return EntityWrapper::Invalid; return EntityWrapper::Invalid;
} }
@@ -96,3 +102,29 @@ EntityWrapper::operator bool()
return this->Valid(); return this->Valid();
} }
EntityWrapper EntityWrapper::firstChildByNameRecursive(const std::string& name, EntityID parent)
{
if (!this->World->ValidEntity(parent)) {
return EntityWrapper::Invalid;
}
auto itPair = this->World->GetChildren(parent);
if (itPair.first == itPair.second) {
return EntityWrapper::Invalid;
}
for (auto it = itPair.first; it != itPair.second; ++it) {
std::string itName = this->World->GetName(it->second);
if (itName == name) {
return EntityWrapper(this->World, it->second);
} else if (it->second != EntityID_Invalid) {
EntityWrapper result = firstChildByNameRecursive(name, it->second);
if (result != EntityWrapper::Invalid) {
return result;
}
}
}
return EntityWrapper::Invalid;
}
+27
View File
@@ -1,5 +1,17 @@
#include "Core/Transform.h" #include "Core/Transform.h"
glm::mat4 Transform::AbsoluteTransformation(EntityWrapper entity)
{
glm::mat4 t = glm::mat4(1.f);
while (entity.Valid()) {
t = glm::translate((glm::vec3&)entity["Transform"]["Position"]) * glm::toMat4(glm::quat((glm::vec3&)entity["Transform"]["Orientation"])) * glm::scale((glm::vec3&)entity["Transform"]["Scale"]) * t;
entity = entity.Parent();
}
return t;
}
glm::vec3 Transform::AbsolutePosition(EntityWrapper entity) glm::vec3 Transform::AbsolutePosition(EntityWrapper entity)
{ {
return AbsolutePosition(entity.World, entity.ID); return AbsolutePosition(entity.World, entity.ID);
@@ -19,6 +31,19 @@ glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity)
return position; return position;
} }
glm::vec3 Transform::AbsoluteOrientationEuler(EntityWrapper entity)
{
glm::vec3 orientation;
while (entity.Valid()) {
ComponentWrapper transform = entity["Transform"];
orientation += (glm::vec3)transform["Orientation"];
entity = entity.Parent();
}
return orientation;
}
glm::quat Transform::AbsoluteOrientation(EntityWrapper entity) glm::quat Transform::AbsoluteOrientation(EntityWrapper entity)
{ {
return AbsoluteOrientation(entity.World, entity.ID); return AbsoluteOrientation(entity.World, entity.ID);
@@ -62,6 +87,8 @@ glm::mat4 Transform::ModelMatrix(EntityWrapper entity)
glm::mat4 Transform::ModelMatrix(EntityID entity, World* world) glm::mat4 Transform::ModelMatrix(EntityID entity, World* world)
{ {
return AbsoluteTransformation(EntityWrapper(world, entity));
glm::vec3 position = Transform::AbsolutePosition(world, entity); glm::vec3 position = Transform::AbsolutePosition(world, entity);
glm::quat orientation = Transform::AbsoluteOrientation(world, entity); glm::quat orientation = Transform::AbsoluteOrientation(world, entity);
glm::vec3 scale = Transform::AbsoluteScale(world, entity); glm::vec3 scale = Transform::AbsoluteScale(world, entity);
+66 -32
View File
@@ -1,4 +1,6 @@
#include "Core/World.h" #include "Core/World.h"
#include "Core/EEntityDeleted.h"
#include "Core/EComponentDeleted.h"
World::~World() World::~World()
{ {
@@ -21,37 +23,7 @@ EntityID World::CreateEntity(EntityID parent /*= 0*/)
void World::DeleteEntity(EntityID entity) void World::DeleteEntity(EntityID entity)
{ {
// Delete components deleteEntityRecursive(entity, false);
for (auto& pair : m_ComponentPools) {
auto& pool = pair.second;
if (pool->KnowsEntity(entity)) {
auto& c = pool->GetByEntity(entity);
pool->Delete(c);
}
}
// Loop through children
std::vector<EntityID> childrenToDelete;
auto children = m_EntityChildren.equal_range(entity);
for (auto it = children.first; it != children.second; ++it) {
childrenToDelete.push_back(it->second);
}
for (auto& child : childrenToDelete) {
DeleteEntity(child);
}
EntityID parent = m_EntityParents.at(entity);
m_EntityParents.erase(entity);
auto parentChildren = m_EntityChildren.equal_range(parent);
for (auto it = parentChildren.first; it != parentChildren.second; ++it) {
if (it->second == entity) {
m_EntityChildren.erase(it);
break;
}
}
// Erase potential name
m_EntityNames.erase(entity);
} }
bool World::ValidEntity(EntityID entity) const bool World::ValidEntity(EntityID entity) const
@@ -96,7 +68,15 @@ void World::DeleteComponent(EntityID entity, const std::string& componentType)
{ {
ComponentPool* pool = m_ComponentPools.at(componentType); ComponentPool* pool = m_ComponentPools.at(componentType);
ComponentWrapper c = pool->GetByEntity(entity); ComponentWrapper c = pool->GetByEntity(entity);
return pool->Delete(c); pool->Delete(c);
if (m_EventBroker != nullptr) {
Events::ComponentDeleted e;
e.Entity = entity;
e.ComponentType = componentType;
e.Cascaded = false;
m_EventBroker->Publish(e);
}
} }
const ComponentPool* World::GetComponents(const std::string& componentType) const ComponentPool* World::GetComponents(const std::string& componentType)
@@ -155,3 +135,57 @@ EntityID World::generateEntityID()
return m_CurrentEntityID++; return m_CurrentEntityID++;
} }
void World::deleteEntityRecursive(EntityID entity, bool cascaded /*= false*/)
{
// Don't attempt to delete entities that don't exist anyway
if (!ValidEntity(entity)) {
return;
}
if (m_EventBroker != nullptr) {
Events::EntityDeleted e;
e.DeletedEntity = entity;
e.Cascaded = cascaded;
m_EventBroker->Publish(e);
}
// Delete components
for (auto& pair : m_ComponentPools) {
auto& pool = pair.second;
if (pool->KnowsEntity(entity)) {
auto& c = pool->GetByEntity(entity);
pool->Delete(c);
if (m_EventBroker != nullptr) {
Events::ComponentDeleted e;
e.Entity = entity;
e.ComponentType = pair.first;
e.Cascaded = true;
m_EventBroker->Publish(e);
}
}
}
// Loop through children
std::vector<EntityID> childrenToDelete;
auto children = m_EntityChildren.equal_range(entity);
for (auto it = children.first; it != children.second; ++it) {
childrenToDelete.push_back(it->second);
}
for (auto& child : childrenToDelete) {
deleteEntityRecursive(child, true);
}
EntityID parent = m_EntityParents.at(entity);
m_EntityParents.erase(entity);
auto parentChildren = m_EntityChildren.equal_range(parent);
for (auto it = parentChildren.first; it != parentChildren.second; ++it) {
if (it->second == entity) {
m_EntityChildren.erase(it);
break;
}
}
// Erase potential name
m_EntityNames.erase(entity);
}
+9
View File
@@ -1,4 +1,5 @@
#include "Editor/EditorGUI.h" #include "Editor/EditorGUI.h"
#include "Rendering/ESetCamera.h"
EditorGUI::EditorGUI(World* world, EventBroker* eventBroker) EditorGUI::EditorGUI(World* world, EventBroker* eventBroker)
: m_World(world) : m_World(world)
@@ -305,6 +306,14 @@ bool EditorGUI::drawComponentNode(EntityWrapper entity, const ComponentInfo& ci)
} }
} }
if (ci.Name == "Camera") {
if (ImGui::Button("Activate")) {
Events::SetCamera e;
e.CameraEntity = entity;
m_EventBroker->Publish(e);
}
}
return true; return true;
} }
+1 -1
View File
@@ -48,7 +48,7 @@ void EditorRenderSystem::Update(double dt)
EntityWrapper entity(m_World, cModel.EntityID); EntityWrapper entity(m_World, cModel.EntityID);
glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, entity.World); glm::mat4 modelMatrix = Transform::ModelMatrix(entity.ID, entity.World);
for (auto matGroup : model->MaterialGroups()) { for (auto matGroup : model->MaterialGroups()) {
std::shared_ptr<ModelJob> modelJob = std::make_shared<ModelJob>(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World); std::shared_ptr<ModelJob> modelJob = std::make_shared<ModelJob>(model, scene.Camera, modelMatrix, matGroup, cModel, entity.World, glm::vec4(0), 0.f);
scene.ForwardJobs.push_back(modelJob); scene.ForwardJobs.push_back(modelJob);
} }
} }
+1 -1
View File
@@ -203,7 +203,7 @@ bool EditorSystem::OnSetCamera(const Events::SetCamera& e)
m_ActualCamera = e.CameraEntity; m_ActualCamera = e.CameraEntity;
Events::SetCamera e2; Events::SetCamera e2;
e2.CameraEntity = m_EditorCamera; e2.CameraEntity = m_EditorCamera;
m_EventBroker->Publish(e2); //m_EventBroker->Publish(e2);
} }
return true; return true;
} }
+130 -65
View File
@@ -7,13 +7,13 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService)
{ {
Network::initialize(); Network::initialize();
// Asumes root node is EntityID 0 // Asumes root node is EntityID_Invalid
insertIntoServerClientMaps(0, 0); insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid);
// Init timer // Init timer
m_TimeSinceSentInputs = std::clock(); m_TimeSinceSentInputs = std::clock();
// Default is local host // Default is local host
std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1"); std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1");
int port = config->Get<int>("Networking.Port", 13); int port = config->Get<int>("Networking.Port", 27666);
m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port);
// Set up network stream // Set up network stream
m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter"); m_PlayerName = config->Get<std::string>("Networking.Name", "Raptorcopter");
@@ -31,7 +31,8 @@ void Client::Start(World* world, EventBroker* eventBroker)
// Subscribe to events // Subscribe to events
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EPlayeDamage, &Client::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Client::OnPlayerDamage);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Client::OnPlayerSpawned);
m_Socket.connect(m_ReceiverEndpoint); m_Socket.connect(m_ReceiverEndpoint);
LOG_INFO("I am client. BIP BOP"); LOG_INFO("I am client. BIP BOP");
@@ -48,6 +49,7 @@ void Client::Update()
sendInputCommands(); sendInputCommands();
m_TimeSinceSentInputs = std::clock(); m_TimeSinceSentInputs = std::clock();
} }
sendLocalPlayerTransform();
} }
Network::Update(); Network::Update();
} }
@@ -96,6 +98,12 @@ void Client::parseMessageType(Packet& packet)
case MessageType::OnPlayerSpawned: case MessageType::OnPlayerSpawned:
parsePlayersSpawned(packet); parsePlayersSpawned(packet);
break; break;
case MessageType::EntityDeleted:
parseEntityDeletion(packet);
break;
case MessageType::ComponentDeleted:
parseComponentDeletion(packet);
break;
default: default:
break; break;
} }
@@ -128,20 +136,43 @@ void Client::parsePing()
} }
void Client::parseKick() void Client::parseKick()
{ {
LOG_WARNING("You have been kicked from the server."); LOG_WARNING("You have been kicked from the server.");
m_IsConnected = false; m_IsConnected = false;
} }
void Client::parsePlayersSpawned(Packet& packet) void Client::parsePlayersSpawned(Packet& packet)
{ {
Events::PlayerSpawned e; Events::PlayerSpawned e;
e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]); e.Player = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]); e.Spawner = EntityWrapper(m_World, m_ServerIDToClientID[packet.ReadPrimitive<EntityID>()]);
e.PlayerID = -1; e.PlayerID = -1;
e.PlayerName = packet.ReadString();
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
} }
void Client::parseEntityDeletion(Packet & packet)
{
EntityID entityToDelete = packet.ReadPrimitive<EntityID>();
// TODO: What if an entity that didn't previously exist comes as a delete request and later comes in a delayed snapshot?
if (m_ServerIDToClientID.find(entityToDelete) != m_ServerIDToClientID.end()) {
EntityID localEntity = m_ServerIDToClientID.at(entityToDelete);
if (m_World->ValidEntity(localEntity)) {
m_World->DeleteEntity(localEntity);
deleteFromServerClientMaps(entityToDelete, localEntity);
}
}
}
void Client::parseComponentDeletion(Packet & packet)
{
EntityID entity = packet.ReadPrimitive<EntityID>();
std::string componentType = packet.ReadString();
if (m_World->HasComponent(entity, componentType)) {
m_World->DeleteComponent(m_ServerIDToClientID.at(entity), componentType);
}
}
// Fields with strings will not work right now // Fields with strings will not work right now
void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType) void Client::InterpolateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType)
{ {
@@ -176,66 +207,53 @@ void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, co
void Client::parseSnapshot(Packet& packet) void Client::parseSnapshot(Packet& packet)
{ {
std::string componentType = packet.ReadString();
while (packet.DataReadSize() < packet.Size()) { while (packet.DataReadSize() < packet.Size()) {
// HACK EntityID serverEntityID = packet.ReadPrimitive<EntityID>();
std::string entityName = packet.ReadString(); EntityID serverParentID = packet.ReadPrimitive<EntityID>();
// Components EntityID std::string serverEntityName = packet.ReadString();
EntityID receivedEntityID = packet.ReadPrimitive<EntityID>(); int ammountOfComponents = packet.ReadPrimitive<int>();
// HACK for (int i = 0; i < ammountOfComponents; i++) {
m_World->SetName(receivedEntityID, entityName); std::string componentType = packet.ReadString();
// Parents EntityID ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo();
EntityID receivedParentEntityID = packet.ReadPrimitive<EntityID>(); if (serverClientMapsHasEntity(serverEntityID)) {
ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo(); EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
// Check if the received EntityID is mapped to one of our local EntityIDs // Update entity
if (serverClientMapsHasEntity(receivedEntityID)) { if (m_World->HasComponent(localEntityID, componentType)) {
// Get the local EntityID // Update component
EntityID entityID = m_ServerIDToClientID.at(receivedEntityID); if (componentType == "Transform") {
// Check if the component exists // Interpolate only transform components
if (m_World->HasComponent(entityID, componentType)) { InterpolateFields(packet, componentInfo, localEntityID, componentType);
// If the entity and the component exists update it } else if (componentType == "Physics" && m_World->HasComponent(localEntityID, "Player")) {
if (componentType == "Transform") { // HACK: Ignore velocity of physics
InterpolateFields(packet, componentInfo, entityID, componentType); packet.ReadData(componentInfo.Stride);
} else {
// Set component values
updateFields(packet, componentInfo, localEntityID, componentType);
}
} else { } else {
updateFields(packet, componentInfo, entityID, componentType); // Has entity but no component
m_World->AttachComponent(localEntityID, componentType);
updateFields(packet, componentInfo, localEntityID, componentType);
} }
// if entity exists but not the component
} else { } else {
// Create component // Create Entity and component
m_World->AttachComponent(entityID, componentType); EntityID newLocalEntityID;
// Copy data to newly created component if (serverParentID == EntityID_Invalid) {
updateFields(packet, componentInfo, entityID, componentType); newLocalEntityID = m_World->CreateEntity(EntityID_Invalid);
} else {
newLocalEntityID = m_World->CreateEntity(m_ServerIDToClientID.at(serverParentID));
}
m_World->SetName(newLocalEntityID, serverEntityName);
insertIntoServerClientMaps(serverEntityID, newLocalEntityID);
m_World->AttachComponent(newLocalEntityID, componentType);
updateFields(packet, componentInfo, newLocalEntityID, componentType);
} }
// If the entity dosent exist nor the component
} else {
// Create Entity
// If entity dosen't exist
EntityID newEntityID = m_World->CreateEntity();
insertIntoServerClientMaps(receivedEntityID, newEntityID);
// Check if EntityIDs are out of sync
if (newEntityID != receivedEntityID) {
LOG_INFO("Client::parseSnapshot(Packet& packet): Newly created EntityID is not the \
same as the one sent by server (EntityIDs are out of sync)");
}
// Create component
m_World->AttachComponent(newEntityID, componentType);
// Copy data to newly created component
updateFields(packet, componentInfo, newEntityID, componentType);
} }
// Parent logic
// Parent Logic // This should be enough beacause we know that the entities arives in pre-order (there will always be a parent)
// Don't need to check if receivedEntityID is mapped. (It should have been set) if (serverParentID != EntityID_Invalid) {
if (receivedParentEntityID != std::numeric_limits<EntityID>::max()) { EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
if (serverClientMapsHasEntity(receivedParentEntityID)) { m_World->SetParent(localEntityID, m_ServerIDToClientID.at(serverParentID));
m_World->SetParent(m_ServerIDToClientID.at(receivedEntityID), m_ServerIDToClientID.at(receivedParentEntityID));
// If Parent dosen't exist create one and map receivedParentEntityID to it.
} else {
// Create the new parent and add it to map
EntityID newParentEntityID = m_World->CreateEntity();
insertIntoServerClientMaps(receivedParentEntityID, newParentEntityID);
// Set the newly created Entity as parent.
m_World->SetParent(m_ServerIDToClientID.at(receivedEntityID), newParentEntityID);
}
} }
} }
} }
@@ -326,13 +344,40 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
bool Client::OnPlayerDamage(const Events::PlayerDamage & e) bool Client::OnPlayerDamage(const Events::PlayerDamage & e)
{ {
Packet packet(MessageType::OnInputCommand, m_SendPacketID); Packet packet(MessageType::OnPlayerDamage, m_SendPacketID);
packet.WritePrimitive(e.DamageAmount); packet.WritePrimitive(e.Damage);
packet.WritePrimitive(e.PlayerDamagedID); packet.WritePrimitive(m_ClientIDToServerID.at(e.Player.ID));
send(packet); send(packet);
return false; return false;
} }
bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e)
{
if (e.PlayerID == -1) {
m_LocalPlayer = e.Player;
}
return true;
}
void Client::sendLocalPlayerTransform()
{
if (!m_LocalPlayer.Valid()) {
return;
}
ComponentWrapper cTransform = m_LocalPlayer["Transform"];
glm::vec3& position = cTransform["Position"];
glm::vec3& orientation = cTransform["Orientation"];
Packet packet(MessageType::PlayerTransform, m_SendPacketID);
packet.WritePrimitive(position.x);
packet.WritePrimitive(position.y);
packet.WritePrimitive(position.z);
packet.WritePrimitive(orientation.x);
packet.WritePrimitive(orientation.y);
packet.WritePrimitive(orientation.z);
send(packet);
}
void Client::identifyPacketLoss() void Client::identifyPacketLoss()
{ {
// if no packets lost, difference should be equal to 1 // if no packets lost, difference should be equal to 1
@@ -386,12 +431,26 @@ void Client::becomePlayer()
bool Client::clientServerMapsHasEntity(EntityID clientEntityID) bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
{ {
return m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end(); if (m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end()) {
if (m_World->ValidEntity(clientEntityID)) {
return true;
}
EntityID serverEntityID = m_ClientIDToServerID.at(clientEntityID);
deleteFromServerClientMaps(serverEntityID, clientEntityID);
}
return false;
} }
bool Client::serverClientMapsHasEntity(EntityID serverEntityID) bool Client::serverClientMapsHasEntity(EntityID serverEntityID)
{ {
return m_ServerIDToClientID.find(serverEntityID) != m_ServerIDToClientID.end(); if (m_ServerIDToClientID.find(serverEntityID) != m_ServerIDToClientID.end()) {
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
if (m_World->ValidEntity(localEntityID)) {
return true;
}
deleteFromServerClientMaps(serverEntityID, localEntityID);
}
return false;
} }
void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID) void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID)
@@ -400,3 +459,9 @@ void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID client
m_ClientIDToServerID.insert(std::make_pair(clientEntityID, serverEntityID)); m_ClientIDToServerID.insert(std::make_pair(clientEntityID, serverEntityID));
} }
void Client::deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID)
{
m_ServerIDToClientID.erase(serverEntityID);
m_ClientIDToServerID.erase(clientEntityID);
}
+142 -139
View File
@@ -21,9 +21,8 @@ void Server::Start(World* world, EventBroker* eventBroker)
// Subscribe to events // Subscribe to events
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Server::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned); EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &Server::OnPlayerSpawned);
for (size_t i = 0; i < m_MaxConnections; i++) { EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &Server::OnEntityDeleted);
m_PlayerDefinitions[i].StopTime = std::clock(); EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
}
LOG_INFO("I am Server. BIP BOP\n"); LOG_INFO("I am Server. BIP BOP\n");
} }
@@ -96,8 +95,8 @@ void Server::parseMessageType(Packet& packet)
case MessageType::OnPlayerDamage: case MessageType::OnPlayerDamage:
parseOnPlayerDamage(packet); parseOnPlayerDamage(packet);
break; break;
case MessageType::BecomePlayer: case MessageType::PlayerTransform:
createPlayer(); parsePlayerTransform(packet);
break; break;
default: default:
break; break;
@@ -119,31 +118,22 @@ int Server::receive(char * data)
return length; return length;
} }
void Server::send(Packet& packet, UserID user)
{
int bytesSent = m_Socket.send_to(
boost::asio::buffer(packet.Data(), packet.Size()),
m_ConnectedUsers[user].Endpoint,
0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
m_NetworkData.AmountOfMessagesSent++;
}
}
void Server::send(PlayerID player, Packet& packet) void Server::send(PlayerID player, Packet& packet)
{ {
int bytesSent = m_Socket.send_to( try {
boost::asio::buffer(packet.Data(), packet.Size()), int bytesSent = m_Socket.send_to(
m_PlayerDefinitions[player].Endpoint, boost::asio::buffer(packet.Data(), packet.Size()),
0); m_ConnectedPlayers[player].Endpoint,
// Network Debug data 0);
if (isReadingData) { // Network Debug data
m_NetworkData.TotalDataSent += packet.Size(); if (isReadingData) {
m_NetworkData.DataSentThisInterval += packet.Size(); m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.AmountOfMessagesSent++; 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[player].Endpoint = boost::asio::ip::udp::endpoint();
} }
} }
@@ -164,58 +154,72 @@ void Server::send(Packet & packet)
void Server::broadcast(Packet& packet) void Server::broadcast(Packet& packet)
{ {
for (int i = 0; i < m_ConnectedUsers.size(); i++) { for (auto& kv : m_ConnectedPlayers) {
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) { packet.ChangePacketID(kv.second.PacketID);
packet.ChangePacketID(m_ConnectedUsers[i].PacketID); send(kv.first, packet);
send(packet, i);
}
} }
} }
// Send snapshot fields // Send snapshot fields
void Server::sendSnapshot() void Server::sendSnapshot()
{ {
// Should time this Packet packet(MessageType::Snapshot);
std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools(); addChildrenToPacket(packet, EntityID_Invalid);
for (auto& it : worldComponentPools) { broadcast(packet);
Packet packet(MessageType::Snapshot); }
ComponentPool* componentPool = it.second;
ComponentInfo componentInfo = componentPool->ComponentInfo();
// Component Type void Server::addChildrenToPacket(Packet & packet, EntityID entityID)
packet.WriteString(componentInfo.Name); {
for (auto& componentWrapper : *componentPool) { auto itPair = m_World->GetChildren(entityID);
// HACK: Send entity name std::unordered_map<std::string, ComponentPool*> worldComponentPools = m_World->GetComponentPools();
packet.WriteString(m_World->GetName(componentWrapper.EntityID)); // Loop through every child
// Components EntityID for (auto it = itPair.first; it != itPair.second; it++) {
packet.WritePrimitive(componentWrapper.EntityID); EntityID childEntityID = it->second;
// Parents EntityID // Write EntityID and parentsID and Entity name
packet.WritePrimitive(m_World->GetParent(componentWrapper.EntityID)); packet.WritePrimitive(childEntityID);
for (auto& componentField : componentWrapper.Info.FieldsInOrder) { packet.WritePrimitive(entityID);
ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(componentField); packet.WriteString(m_World->GetName(childEntityID));
if (fieldInfo.Type == "string") { // Write components to child
std::string& value = componentWrapper[componentField]; int numberOfComponents = 0;
packet.WriteString(value); for (auto& i : worldComponentPools) {
} else { if (i.second->KnowsEntity(childEntityID)) {
packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride); 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);
}
} }
} }
} }
if (packet.Size() > packet.HeaderSize() + componentInfo.Name.size()) { // Go to to your children
broadcast(packet); addChildrenToPacket(packet, childEntityID);
}
} }
} }
void Server::sendPing() void Server::sendPing()
{ {
// Prints connected players ping // Prints connected players ping
for (int i = 0; i < m_ConnectedUsers.size(); i++) { //for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) { // if (m_ConnectedPlayers[i].Endpoint.address() != boost::asio::ip::address()) {
int ping = 1000 * (m_ConnectedUsers[i].StopTime - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC); // int ping = 1000 * (m_ConnectedPlayers[i].StopTime - m_StartPingTime) / static_cast<double>(CLOCKS_PER_SEC);
LOG_INFO("Last packetID received %i: User %i's ping: %i", m_ConnectedUsers[i].PacketID, i, std::abs(ping)); // LOG_INFO("Last packetID received %i: User %i's ping: %i", m_ConnectedPlayers[i].PacketID, i, std::abs(ping));
} // }
} //}
// Create ping message // Create ping message
Packet packet(MessageType::Ping); Packet packet(MessageType::Ping);
packet.WriteString("Ping from server"); packet.WriteString("Ping from server");
@@ -230,9 +234,9 @@ void Server::checkForTimeOuts()
int startPing = 1000 * m_StartPingTime int startPing = 1000 * m_StartPingTime
/ static_cast<double>(CLOCKS_PER_SEC); / static_cast<double>(CLOCKS_PER_SEC);
for (int i = 0; i < m_ConnectedUsers.size(); i++) { for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() != boost::asio::ip::address()) { if (m_ConnectedPlayers[i].Endpoint.address() != boost::asio::ip::address()) {
int stopPing = 1000 * m_ConnectedUsers[i].StopTime / int stopPing = 1000 * m_ConnectedPlayers[i].StopTime /
static_cast<double>(CLOCKS_PER_SEC); static_cast<double>(CLOCKS_PER_SEC);
if (startPing > stopPing + m_TimeoutMs) { if (startPing > stopPing + m_TimeoutMs) {
LOG_INFO("User %i timed out!", i); LOG_INFO("User %i timed out!", i);
@@ -242,40 +246,30 @@ void Server::checkForTimeOuts()
} }
} }
void Server::disconnect(UserID user) void Server::disconnect(PlayerID playerID)
{ {
//broadcast("A player disconnected"); //broadcast("A player disconnected");
LOG_INFO("User %s disconnected/timed out", m_PlayerDefinitions[user].Name.c_str()); LOG_INFO("User %s disconnected/timed out", m_ConnectedPlayers[playerID].Name.c_str());
// Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have) // Remove enteties and stuff (When we can remove entity, remove it and tell clients to remove the copy they have)
Events::PlayerDisconnected e; Events::PlayerDisconnected e;
e.Entity = m_PlayerDefinitions[user].EntityID; e.Entity = m_ConnectedPlayers[playerID].EntityID;
e.PlayerID = user; e.PlayerID = playerID;
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
m_PlayerDefinitions[user].Endpoint = boost::asio::ip::udp::endpoint(); m_ConnectedPlayers.erase(playerID);
m_PlayerDefinitions[user].EntityID = -1;
m_PlayerDefinitions[user].Name = "";
m_PlayerDefinitions[user].PacketID = 0;
m_ConnectedUsers.erase(m_ConnectedUsers.begin() + user);
} }
void Server::parseOnInputCommand(Packet& packet) void Server::parseOnInputCommand(Packet& packet)
{ {
PlayerID player = -1; PlayerID player = -1;
// Check which player it was who sent the message // Check which player it was who sent the message
for (int i = 0; i < m_MaxConnections; i++) { player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
// 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()) {
player = i;
break;
}
}
if (player != -1) { if (player != -1) {
while (packet.DataReadSize() < packet.Size()) { while (packet.DataReadSize() < packet.Size()) {
Events::InputCommand e; Events::InputCommand e;
e.Command = packet.ReadString(); e.Command = packet.ReadString();
e.PlayerID = player; // Set correct player id e.PlayerID = player; // Set correct player id
e.Player = EntityWrapper(m_World, m_ConnectedPlayers.at(player).EntityID);
e.Value = packet.ReadPrimitive<float>(); e.Value = packet.ReadPrimitive<float>();
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
//LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); //LOG_INFO("Server::parseOnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
@@ -286,8 +280,8 @@ void Server::parseOnInputCommand(Packet& packet)
void Server::parseOnPlayerDamage(Packet & packet) void Server::parseOnPlayerDamage(Packet & packet)
{ {
Events::PlayerDamage e; Events::PlayerDamage e;
e.DamageAmount = packet.ReadPrimitive<double>(); e.Damage = packet.ReadPrimitive<double>();
e.PlayerDamagedID = packet.ReadPrimitive<EntityID>(); e.Player = EntityWrapper(m_World, packet.ReadPrimitive<EntityID>());
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
//LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str()); //LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str());
} }
@@ -299,9 +293,9 @@ void Server::parseConnect(Packet& packet)
if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) { if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) {
return; return;
} }
for (int i = 0; i < m_ConnectedUsers.size(); i++) { for (auto& kv : m_ConnectedPlayers) {
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address() && if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() &&
m_ConnectedUsers[i].Endpoint.port() == m_ReceiverEndpoint.port()) { kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) {
// Already connected // Already connected
return; return;
} }
@@ -313,11 +307,11 @@ void Server::parseConnect(Packet& packet)
pd.Name = packet.ReadString(); pd.Name = packet.ReadString();
pd.PacketID = 0; pd.PacketID = 0;
pd.StopTime = std::clock(); pd.StopTime = std::clock();
m_ConnectedUsers.push_back(pd); m_ConnectedPlayers[m_NextPlayerID++] = pd;
LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str()); LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str());
// Send a message to the player that connected // Send a message to the player that connected
Packet connnectPacket(MessageType::Connect, m_ConnectedUsers[m_ConnectedUsers.size() - 1].PacketID); Packet connnectPacket(MessageType::Connect, pd.PacketID);
send(connnectPacket); send(connnectPacket);
// Send notification that a player has connected // Send notification that a player has connected
@@ -329,9 +323,10 @@ void Server::parseDisconnect()
{ {
LOG_INFO("%i: Parsing disconnect", m_PacketID); LOG_INFO("%i: Parsing disconnect", m_PacketID);
for (int i = 0; i < m_ConnectedUsers.size(); i++) { for (auto& kv : m_ConnectedPlayers) {
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) { if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() &&
disconnect(i); kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) {
disconnect(kv.first);
break; break;
} }
} }
@@ -345,16 +340,16 @@ void Server::parseClientPing()
return; return;
} }
// Return ping // Return ping
Packet packet(MessageType::Ping, m_PlayerDefinitions[player].PacketID); Packet packet(MessageType::Ping, m_ConnectedPlayers[player].PacketID);
packet.WriteString("Ping received"); packet.WriteString("Ping received");
send(packet); send(packet);
} }
void Server::parsePing() void Server::parsePing()
{ {
for (int i = 0; i < m_ConnectedUsers.size(); i++) { for (int i = 0; i < m_ConnectedPlayers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) { if (m_ConnectedPlayers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
m_ConnectedUsers[i].StopTime = std::clock(); m_ConnectedPlayers[i].StopTime = std::clock();
break; break;
} }
} }
@@ -369,43 +364,6 @@ void Server::identifyPacketLoss()
} }
} }
void Server::createPlayer()
{
if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) {
// Already connected as player
LOG_WARNING("Already connected!");
return;
}
UserID 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 (PlayerID playerIndex = 0; playerIndex < m_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.mesh";
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!");
}
void Server::kick(PlayerID player) void Server::kick(PlayerID player)
{ {
disconnect(player); disconnect(player);
@@ -415,10 +373,10 @@ void Server::kick(PlayerID player)
PlayerID Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint) PlayerID Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
{ {
for (int i = 0; i < m_MaxConnections; i++) { for (auto& kv : m_ConnectedPlayers) {
if (m_PlayerDefinitions[i].Endpoint.address() == endpoint.address() && if (kv.second.Endpoint.address() == endpoint.address() &&
m_PlayerDefinitions[i].Endpoint.port() == endpoint.port()) { kv.second.Endpoint.port() == endpoint.port()) {
return i; return kv.first;
} }
} }
return -1; return -1;
@@ -443,9 +401,54 @@ bool Server::OnInputCommand(const Events::InputCommand & e)
bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e) bool Server::OnPlayerSpawned(const Events::PlayerSpawned & e)
{ {
m_ConnectedPlayers[e.PlayerID].EntityID = e.Player.ID;
Packet packet = Packet(MessageType::OnPlayerSpawned); Packet packet = Packet(MessageType::OnPlayerSpawned);
packet.WritePrimitive<EntityID>(e.Player.ID); packet.WritePrimitive<EntityID>(e.Player.ID);
packet.WritePrimitive<EntityID>(e.Spawner.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); send(e.PlayerID, packet);
return false; 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;
}
}
+47
View File
@@ -0,0 +1,47 @@
#include "Rendering/AnimationSystem.h"
void AnimationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& animationComponent, double dt)
{
if(!entity.HasComponent("Model")) {
return;
}
Model* model;
try {
model = ResourceManager::Load<::Model, true>(entity["Model"]["Resource"]);
} catch (const std::exception&) {
return;
}
Skeleton* skeleton = model->m_RawModel->m_Skeleton;
const Skeleton::Animation* animation = skeleton->GetAnimation(animationComponent["Name"]);
if(animation != nullptr) {
double animationSpeed = (double)animationComponent["Speed"];
if (animationSpeed != 0.0) {
double nextTime = (double)animationComponent["Time"] + animationSpeed * dt;
if (!(bool)animationComponent["Loop"] && glm::abs(nextTime) > animation->Duration) {
(double&)animationComponent["Time"] = glm::sign(nextTime) * animation->Duration;
(double&)animationComponent["Speed"] = 0.0;
Events::AnimationComplete e;
e.Entity = entity;
e.Name = (std::string)animationComponent["Name"];
m_EventBroker->Publish(e);
} else {
if (glm::abs(nextTime) > animation->Duration) {
(double&)animationComponent["Time"] = glm::abs(nextTime) - animation->Duration;
} else {
(double&)animationComponent["Time"] = nextTime;
}
}
}
}
}
+7 -6
View File
@@ -75,6 +75,10 @@ void DrawFinalPass::Draw(RenderScene& scene)
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(modelJob->DiffuseColor)); glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(modelJob->DiffuseColor));
glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(modelJob->FillColor));
glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), modelJob->FillPercentage);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
if(modelJob->DiffuseTexture != nullptr) { if(modelJob->DiffuseTexture != nullptr) {
glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture);
@@ -96,12 +100,9 @@ void DrawFinalPass::Draw(RenderScene& scene)
//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 :) //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) { if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("running");
if (animation != nullptr) { if (modelJob->Animation != nullptr) {
std::vector<glm::mat4> frameBones = modelJob->Model->m_RawModel->m_Skeleton->GetFrameBones( std::vector<glm::mat4> frameBones = modelJob->Skeleton->GetFrameBones( *modelJob->Animation, modelJob->AnimationTime);
*animation,
0.0f
);
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
} }
} }
+16 -8
View File
@@ -48,7 +48,7 @@ void PickingPass::Draw(RenderScene& scene)
PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle()); PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle());
//TODO: Render: Add code for more jobs than modeljobs. //TODO: Render: Add code for more jobs than modeljobs.
GLuint ShaderHandle = m_PickingProgram->GetHandle(); GLuint shaderHandle = m_PickingProgram->GetHandle();
m_PickingProgram->Bind(); m_PickingProgram->Bind();
if (scene.ClearDepth) { if (scene.ClearDepth) {
@@ -75,22 +75,30 @@ void PickingPass::Draw(RenderScene& scene)
m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]); m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]);
if (m_ColorCounter[0] > 255) { if (m_ColorCounter[0] > 255) {
m_ColorCounter[0] = 0; m_ColorCounter[0] = 0;
m_ColorCounter[1]++; m_ColorCounter[1] += 5;
} else { } else {
m_ColorCounter[0]++; m_ColorCounter[0] += 50;
} }
} }
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo; m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); glUniform2fv(glGetUniformLocation(shaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
if (modelJob->Animation != nullptr) {
std::vector<glm::mat4> frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime);
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
}
glBindVertexArray(modelJob->Model->VAO); glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex); glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
} }
} }
+22 -4
View File
@@ -4,6 +4,7 @@ RenderSystem::RenderSystem(World* world, EventBroker* eventBroker, const IRender
: System(world, eventBroker) : System(world, eventBroker)
, m_Renderer(renderer) , m_Renderer(renderer)
, m_RenderFrame(renderFrame) , m_RenderFrame(renderFrame)
, m_World(world)
{ {
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera); EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
@@ -51,6 +52,12 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
// Don't render the local player // Don't render the local player
if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) { if (entity == m_LocalPlayer || entity.IsChildOf(m_LocalPlayer)) {
if (!entity.HasComponent("HealthHUD") && entity.Name() != "Crosshair" && entity.Name() != "Weapon") { //Should work but needs to be fixed. Should only render the things "childed" to the local player camera
continue;
}
}
if ((entity.Name() == "Weapon" || entity.HasComponent("HealthHUD")) && !entity.IsChildOf(m_LocalPlayer)) {
continue; continue;
} }
@@ -68,9 +75,21 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
} }
} }
float fillPercentage = 0.f;
glm::vec4 fillColor = glm::vec4(0);
if(m_World->HasComponent(modelComponent.EntityID, "Fill")) {
auto fillComponent = m_World->GetComponent(modelComponent.EntityID, "Fill");
fillPercentage = (float)(double)fillComponent["Percentage"];
fillColor = (glm::vec4)fillComponent["Color"];
}
glm::mat4 modelMatrix = Transform::ModelMatrix(modelComponent.EntityID, m_World); glm::mat4 modelMatrix = Transform::ModelMatrix(modelComponent.EntityID, m_World);
for (auto matGroup : model->MaterialGroups()) { for (auto matGroup : model->MaterialGroups()) {
std::shared_ptr<ModelJob> modelJob = std::shared_ptr<ModelJob>(new ModelJob(model, m_Camera, modelMatrix, matGroup, modelComponent, m_World)); std::shared_ptr<ModelJob> modelJob = std::shared_ptr<ModelJob>(new ModelJob(model, m_Camera, modelMatrix, matGroup, modelComponent, m_World, fillColor, fillPercentage));
jobs.push_back(modelJob); jobs.push_back(modelJob);
} }
} }
@@ -156,8 +175,8 @@ void RenderSystem::fillText(std::list<std::shared_ptr<RenderJob>>& jobs, World*
} }
glm::mat4 modelMatrix = Transform::ModelMatrix(textComponent.EntityID, world); glm::mat4 modelMatrix = Transform::ModelMatrix(textComponent.EntityID, world);
std::shared_ptr<TextJob> modelJob = std::shared_ptr<TextJob>(new TextJob(modelMatrix, font, textComponent)); std::shared_ptr<TextJob> textJob = std::shared_ptr<TextJob>(new TextJob(modelMatrix, font, textComponent));
jobs.push_back(modelJob); jobs.push_back(textJob);
} }
} }
@@ -177,7 +196,6 @@ void RenderSystem::Update(double dt)
m_Camera->SetOrientation(Transform::AbsoluteOrientation(m_CurrentCamera)); m_Camera->SetOrientation(Transform::AbsoluteOrientation(m_CurrentCamera));
} }
//Only supports opaque geometry atm
RenderScene scene; RenderScene scene;
scene.Camera = m_Camera; scene.Camera = m_Camera;
+8 -1
View File
@@ -10,6 +10,9 @@
#include "Core/EntityFileWriter.h" #include "Core/EntityFileWriter.h"
#include "Game/Systems/CapturePointSystem.h" #include "Game/Systems/CapturePointSystem.h"
#include "Game/Systems/WeaponSystem.h" #include "Game/Systems/WeaponSystem.h"
#include "Game/Systems/PlayerHUD.h"
#include "Game/Systems/LifetimeSystem.h"
#include "../Engine/Rendering/AnimationSystem.h"
Game::Game(int argc, char* argv[]) Game::Game(int argc, char* argv[])
{ {
@@ -57,7 +60,7 @@ Game::Game(int argc, char* argv[])
m_FrameStack->Height = m_Renderer->Resolution().Height; m_FrameStack->Height = m_Renderer->Resolution().Height;
// Create a world // Create a world
m_World = new World(); m_World = new World(m_EventBroker);
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", ""); std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
if (!mapToLoad.empty()) { if (!mapToLoad.empty()) {
auto file = ResourceManager::Load<EntityFile>(mapToLoad); auto file = ResourceManager::Load<EntityFile>(mapToLoad);
@@ -83,9 +86,13 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerSpawnSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<PlayerSpawnSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<WeaponSystem>(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem<WeaponSystem>(updateOrderLevel, m_Renderer);
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
// Populate Octree with collidables // Populate Octree with collidables
++updateOrderLevel; ++updateOrderLevel;
m_SystemPipeline->AddSystem<CollidableOctreeSystem>(updateOrderLevel, m_OctreeCollision); m_SystemPipeline->AddSystem<CollidableOctreeSystem>(updateOrderLevel, m_OctreeCollision);
m_SystemPipeline->AddSystem<PlayerHUD>(updateOrderLevel);
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
// Collision and TriggerSystem should update after player. // Collision and TriggerSystem should update after player.
++updateOrderLevel; ++updateOrderLevel;
m_SystemPipeline->AddSystem<CollisionSystem>(updateOrderLevel, m_OctreeCollision); m_SystemPipeline->AddSystem<CollisionSystem>(updateOrderLevel, m_OctreeCollision);
+9 -4
View File
@@ -12,7 +12,6 @@ HealthSystem::HealthSystem(World* m_World, EventBroker* eventBroker)
void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt)
{ {
//if entityID of health is 9 then the players ID is also 9 (player,health are connected to the same entity) //if entityID of health is 9 then the players ID is also 9 (player,health are connected to the same entity)
ComponentWrapper player = m_World->GetComponent(component.EntityID, "Player");
double maxHealth = (double)component["MaxHealth"]; double maxHealth = (double)component["MaxHealth"];
//process the DeltaHealthVector and change the entitys health accordingly //process the DeltaHealthVector and change the entitys health accordingly
@@ -46,10 +45,16 @@ void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& comp
} }
} }
bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e) bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e)
{ {
//save the changed HP to a vector. it will be taken care of in UpdateComponent ComponentWrapper cHealth = e.Player["Health"];
m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerDamagedID, -e.DamageAmount)); double& health = cHealth["Health"];
health -= e.Damage;
if (health <= 0.0) {
m_World->DeleteEntity(e.Player.ID);
}
return true; return true;
} }
+8 -4
View File
@@ -12,6 +12,11 @@ InterpolationSystem::InterpolationSystem(World* world, EventBroker* eventBroker)
void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt) void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& transform, double dt)
{ {
// Don't interpolate entities that might already have been removed
if (!entity.Valid()) {
return;
}
if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map if (m_NextTransform.find(transform.EntityID) != m_NextTransform.end()) { // Exists in map
m_NextTransform[transform.EntityID].interpolationTime += dt; m_NextTransform[transform.EntityID].interpolationTime += dt;
Transform sTransform = m_NextTransform[transform.EntityID]; Transform sTransform = m_NextTransform[transform.EntityID];
@@ -31,11 +36,10 @@ void InterpolationSystem::UpdateComponent(EntityWrapper& entity, ComponentWrappe
// Position // Position
glm::vec3 nextPosition = sTransform.Position; glm::vec3 nextPosition = sTransform.Position;
glm::vec3 currentPosition = static_cast<glm::vec3>(transform["Position"]); glm::vec3 currentPosition = static_cast<glm::vec3>(transform["Position"]);
// HACK: Hardcoded tolerance value for player position desync = 1 // HACK: Don't force position for players
if (isLocalPlayer && glm::length(nextPosition - currentPosition) < 1.f) { if (!isLocalPlayer) {
return; (glm::vec3&)transform["Position"] += vectorInterpolation<glm::vec3>(currentPosition, nextPosition, sTransform.interpolationTime);
} }
(glm::vec3&)transform["Position"] += vectorInterpolation<glm::vec3>(currentPosition, nextPosition, sTransform.interpolationTime);
// Orientation // Orientation
// Don't force orientation for players // Don't force orientation for players
if (!isLocalPlayer) { if (!isLocalPlayer) {
+27
View File
@@ -0,0 +1,27 @@
#include "Systems/LifetimeSystem.h"
void LifetimeSystem::Update(double dt)
{
for (auto& e : m_Deletions) {
m_World->DeleteEntity(e.ID);
}
m_Deletions.clear();
}
void LifetimeSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cLifetime, double dt)
{
if (dt == 0.0) {
return;
}
if (!entity.Valid()) {
return;
}
double& lifetime = cLifetime["Lifetime"];
lifetime -= dt;
if (lifetime <= 0.0) {
m_Deletions.push_back(entity);
}
}
+57
View File
@@ -0,0 +1,57 @@
#include "Game/Systems/PlayerHUD.h"
PlayerHUD::PlayerHUD(World* world, EventBroker* eventBrokerer)
:System(world, eventBrokerer)
, m_World(world)
, m_EventBroker(eventBrokerer)
{
}
PlayerHUD::~PlayerHUD()
{
}
void PlayerHUD::Update(double dt)
{
auto healthHUDs = m_World->GetComponents("HealthHUD");
if (healthHUDs == nullptr) {
return;
}
for (auto& healthHUDComponent : *healthHUDs) {
EntityWrapper entity = EntityWrapper(m_World, healthHUDComponent.EntityID);
EntityWrapper entityIDParent = entity;
while (entityIDParent.Parent().Valid()) {
entityIDParent = entityIDParent.Parent();
if (entityIDParent.HasComponent("Health")) {
break;
}
}
if (entityIDParent.HasComponent("Health")) {
if (entity.HasComponent("Text")) {
std::string s = "";
s = s + std::to_string((int)(double)entityIDParent["Health"]["Health"]);
s = s + "/";
s = s + std::to_string((int)(double)entityIDParent["Health"]["MaxHealth"]);
float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"];
(glm::vec4&)entity["Text"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, 1.f);
entity["Text"]["Content"] = s;
}
if(entity.HasComponent("Fill")) {
float healthPercentage = (double)entityIDParent["Health"]["Health"]/(double)entityIDParent["Health"]["MaxHealth"];
(glm::vec4&)entity["Fill"]["Color"] = glm::vec4(1.0 - healthPercentage, 0.f, healthPercentage, 0.f);
(double&)entity["Fill"]["Percentage"] = healthPercentage;
}
}
}
}
+31 -3
View File
@@ -36,15 +36,18 @@ void PlayerMovementSystem::Update(double dt)
glm::vec3& ori = cTransform["Orientation"]; glm::vec3& ori = cTransform["Orientation"];
ori.y += controller->Rotation().y; ori.y += controller->Rotation().y;
float playerMovementSpeed = player["Player"]["MovementSpeed"];
float playerCrouchSpeed = player["Player"]["CrouchSpeed"];
if (player.HasComponent("Physics")) { if (player.HasComponent("Physics")) {
ComponentWrapper cPhysics = player["Physics"]; ComponentWrapper cPhysics = player["Physics"];
glm::vec3 wishDirection = controller->Movement() * glm::inverse(glm::quat(ori)); glm::vec3 wishDirection = controller->Movement() * glm::inverse(glm::quat(ori));
float wishSpeed; float wishSpeed;
if (controller->Crouching()) { if (controller->Crouching()) {
wishSpeed = player["Player"]["CrouchSpeed"]; wishSpeed = playerCrouchSpeed;
} else { } else {
wishSpeed = player["Player"]["MovementSpeed"]; wishSpeed = playerMovementSpeed;
} }
glm::vec3& velocity = cPhysics["Velocity"]; glm::vec3& velocity = cPhysics["Velocity"];
ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z); ImGui::Text("velocity: (%f, %f, %f)", velocity.x, velocity.y, velocity.z);
@@ -85,8 +88,33 @@ void PlayerMovementSystem::Update(double dt)
// size = glm::vec3(1.f, 1.6f, 1.f); // size = glm::vec3(1.f, 1.6f, 1.f);
// } // }
//} //}
// Animations
EntityWrapper playerModel = player.FirstChildByName("PlayerModel");
if (playerModel.Valid()) {
ComponentWrapper cAnimation = playerModel["Animation"];
float movementLength = glm::length(groundVelocity);
if (glm::length(controller->Movement()) > 0.f) {
if (controller->Crouching()) {
cAnimation["Name"] = "Crouch Walk";
(double&)cAnimation["Speed"] = 1.f * -glm::sign(controller->Movement().z);
} else {
cAnimation["Name"] = "Run";
(double&)cAnimation["Speed"] = 2.f * -glm::sign(controller->Movement().z);
}
} else {
if (controller->Crouching()) {
cAnimation["Name"] = "Crouch";
(double&)cAnimation["Speed"] = 1.f;
} else {
cAnimation["Name"] = "Hold Pos";
(double&)cAnimation["Speed"] = 1.f;
}
}
}
} }
controller->Reset(); controller->Reset();
} }
} }
+4 -4
View File
@@ -102,10 +102,10 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
} }
// TODO: Set the player name to whatever // TODO: Set the player name to whatever
//EntityWrapper playerName = e.Player.FirstChildByName("PlayerName"); EntityWrapper playerName = e.Player.FirstChildByName("PlayerName");
//if (playerName.Valid()) { if (playerName.Valid()) {
// playerName["Text"]["Content"] = ???; playerName["Text"]["Content"] = e.PlayerName;
//} }
return true; return true;
} }
+2 -1
View File
@@ -50,7 +50,8 @@ EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /
// Set its position and orientation to that of the SpawnPoint // Set its position and orientation to that of the SpawnPoint
spawnedEntity["Transform"]["Position"] = Transform::AbsolutePosition(spawnPoint.World, spawnPoint.ID); spawnedEntity["Transform"]["Position"] = Transform::AbsolutePosition(spawnPoint.World, spawnPoint.ID);
spawnedEntity["Transform"]["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(spawnPoint.World, spawnPoint.ID)); // TODO: Quaternions, bitch
//spawnedEntity["Transform"]["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(spawnPoint.World, spawnPoint.ID));
return spawnedEntity; return spawnedEntity;
} }
+103 -25
View File
@@ -5,49 +5,127 @@ WeaponSystem::WeaponSystem(World* world, EventBroker* eventBroker, IRenderer* re
, ImpureSystem() , ImpureSystem()
, m_Renderer(renderer) , m_Renderer(renderer)
{ {
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &WeaponSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot); EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot);
} }
void WeaponSystem::Update(double dt) void WeaponSystem::Update(double dt)
{ {
for (int i = m_EShootVector.size(); i > 0; i--)
{
//TODO: check if player has enough ammo and if weapon has a cooldown or not
//pick the object }
PickData pickDataFromShot = m_Renderer->Pick(std::get<1>(m_EShootVector[i - 1]));
if (pickDataFromShot.Entity == EntityID_Invalid) { bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e)
m_EShootVector.erase(m_EShootVector.begin() + i - 1); {
continue; if (e.PlayerID == -1) {
} m_LocalPlayer = e.Player;
//if its a player, do PlayerDamage event
const bool hasPlayerComponent = m_World->HasComponent(pickDataFromShot.Entity, "Player");
if (hasPlayerComponent) {
Events::PlayerDamage ePlayerDamage;
//TODO: damage based on weapontype/class?
//TODO: multiple shots at the same time? (shotgunner)
ePlayerDamage.DamageAmount = 25;
ePlayerDamage.PlayerDamagedID = pickDataFromShot.Entity;
m_EventBroker->Publish(ePlayerDamage);
}
m_EShootVector.erase(m_EShootVector.begin() + i - 1);
} }
return true;
} }
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e) bool WeaponSystem::OnInputCommand(const Events::InputCommand& e)
{ {
if (e.Command == "PrimaryFire" && e.Value > 0) { if (e.Command == "PrimaryFire" && e.Value > 0) {
Events::Shoot eShoot; Events::Shoot eShoot;
eShoot.shooter = e.PlayerID; if (e.PlayerID == -1) {
eShoot.Player = m_LocalPlayer;
} else {
eShoot.Player = e.Player;
}
m_EventBroker->Publish(eShoot); m_EventBroker->Publish(eShoot);
} }
return true; return true;
} }
bool WeaponSystem::OnShoot(const Events::Shoot& e) {
//screen center, based on current resolution! bool WeaponSystem::OnShoot(Events::Shoot& eShoot)
{
if (!eShoot.Player.Valid()) {
return false;
}
// TODO: Weapon firing effects here
auto rayRed = ResourceManager::Load<EntityFile>("Schema/Entities/RayRed.xml");
auto rayBlue = ResourceManager::Load<EntityFile>("Schema/Entities/RayBlue.xml");
EntityWrapper weapon = eShoot.Player.FirstChildByName("WeaponMuzzle");
if (weapon.Valid()) {
EntityWrapper ray;
if ((ComponentInfo::EnumType)eShoot.Player["Team"]["Team"] == eShoot.Player["Team"]["Team"].Enum("Red")) {
EntityFileParser parser(rayRed);
EntityID rayID = parser.MergeEntities(m_World);
ray = EntityWrapper(m_World, rayID);
} else {
EntityFileParser parser(rayBlue);
EntityID rayID = parser.MergeEntities(m_World);
ray = EntityWrapper(m_World, rayID);
}
glm::mat4 transformation = Transform::AbsoluteTransformation(weapon);
glm::vec3 scale;
glm::vec3 translation;
glm::quat orientation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(transformation, scale, orientation, translation, skew, perspective);
// Matrix to euler angles
glm::vec3 euler;
euler.y = glm::asin(-transformation[0][2]);
if (cos(euler.y) != 0) {
euler.x = atan2(transformation[1][2], transformation[2][2]);
euler.z = atan2(transformation[0][1], transformation[0][0]);
} else {
euler.x = atan2(-transformation[2][0], transformation[1][1]);
euler.z = 0;
}
//LOG_DEBUG("rotation: %f %f %f", euler.x, euler.y, euler.z);
(glm::vec3&)ray["Transform"]["Position"] = translation;
(glm::vec3&)ray["Transform"]["Orientation"] = euler;
//(glm::vec3&)ray["Transform"]["Orientation"] = Transform::AbsoluteOrientationEuler(weapon);
}
// Only run further picking code client-side!
if (eShoot.Player != m_LocalPlayer) {
return false;
}
// Screen center, based on current resolution!
// TODO: check if player has enough ammo and if weapon has a cooldown or not
Rectangle screenResolution = m_Renderer->Resolution(); Rectangle screenResolution = m_Renderer->Resolution();
glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2); glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2);
m_EShootVector.push_back(std::make_pair(e.shooter, centerScreen));
// TODO: check if player has enough ammo and if weapon has a cooldown or not
// Pick middle of screen
PickData pickData = m_Renderer->Pick(centerScreen);
if (pickData.Entity == EntityID_Invalid) {
return false;
}
EntityWrapper player(m_World, pickData.Entity);
// Only care about players being hit
if (!player.HasComponent("Player")) {
player = player.FirstParentWithComponent("Player");
}
if (!player.Valid()) {
return false;
}
// Check for friendly fire
EntityWrapper shooter = eShoot.Player;
if ((ComponentInfo::EnumType)player["Team"]["Team"] == (ComponentInfo::EnumType)shooter["Team"]["Team"]) {
return false;
}
// TODO: Weapon damage calculations etc
Events::PlayerDamage ePlayerDamage;
ePlayerDamage.Player = player;
ePlayerDamage.Damage = 100;
m_EventBroker->Publish(ePlayerDamage);
return true; return true;
} }