Compare commits

..

57 Commits

Author SHA1 Message Date
Jocke ac0c6ff952 WIP started on reliable messages 2016-01-27 18:22:28 +01:00
stiffly 06f64f8fbf Added a player name to the PlayerSpawned event. When a player has spawned the server sends the name to the client which publishes the event. 2016-01-24 22:00:38 +01:00
Jace 0c56a05144 Merge branch 'master' of github.com:teamfisk/TacticalZ
# Conflicts:
#	resources/Schema/Entities/Player.xml
#	src/Engine/Network/Server.cpp
2016-01-24 21:21:51 +01:00
Jace 382eff169f Server refactoring to remove player dependency and lots of fixes. 2016-01-24 21:20:43 +01:00
Tleety d4797b0808 Some entity files 2016-01-24 21:08:01 +01:00
Jace 25890c8d6c Merge remote-tracking branch 'origin/Networking' 2016-01-24 19:01:15 +01:00
Jace 0fb1dbcae1 Client now has authority over its own absolute position and orientation until we have reliable input messaging 2016-01-24 19:00:50 +01:00
Jace 9f3d887ac4 Networking bugfixes 2016-01-24 18:37:36 +01:00
Jace b4081b3e45 Merge remote-tracking branch 'origin/Networking'
# Conflicts:
#	src/Engine/Network/Client.cpp
#	src/Game/Systems/WeaponSystem.cpp
2016-01-24 18:36:37 +01:00
stiffly 8d61632c26 No longer spawns a f**king sphere. 2016-01-24 17:40:43 +01:00
stiffly 2eaad2aa00 Client now responds to deleted entity and component in server 2016-01-24 17:16:26 +01:00
Jace 235b26ad61 WIP shoot 2016-01-24 17:16:18 +01:00
Viktor Ljung f80fb5eda8 Merge pull request #52 from teamfisk/Importer
Importer
2016-01-24 17:05:02 +01:00
antc13 aa115befa9 UnitRaptor is now displayed while models are being loaded in. 2016-01-24 17:04:12 +01:00
antc13 aa20b48188 Merge remote-tracking branch 'origin/master' into Importer
# Conflicts:
#	resources/Schema/Entities/MovementTest.xml
#	resources/Schema/Entities/Player.xml
2016-01-24 16:22:22 +01:00
antc13 96a735c542 Changed .obj to .mesh for all meshes. 2016-01-24 16:12:31 +01:00
antc13 666f1fd878 Removed temp variables & the "forced" animation in DrawFinalPass 2016-01-24 15:30:20 +01:00
antc13 4c5d17b203 Merge remote-tracking branch 'origin/master' into Importer
# Conflicts:
#	resources/Schema/Entities/RenderingWorld.xml
#	resources/Shaders/ForwardPlus.frag.glsl
#	src/Engine/Editor/EditorSystem.cpp
#	src/Engine/Network/Server.cpp
#	src/Engine/Rendering/DrawFinalPass.cpp
#	src/Tests/OctTreeTestGameClass.cpp
#	src/Tests/OctTreeTestHardCodedTestWorld.h
#	src/Tests/ResourceManagerTest.cpp
2016-01-24 14:40:52 +01:00
antc13 8286d052b3 Changed color values from floats to glm::vec4 2016-01-24 14:38:17 +01:00
Jace 67477ff3ae EEntityDeleted and EComponentDeleted events published by World 2016-01-24 13:49:45 +01:00
antc13 b5b1140f5c Custom Animations should now work. We also save color values if there's no texture. 2016-01-24 13:28:40 +01:00
Jocke 7567f47a68 Weapon system now searches parents for health component (stops at first health component). 2016-01-24 11:56:46 +01:00
Jocke 97d70f8e32 Fixed in client for shoot event. Weapon system now damages health on any target not only players. 2016-01-24 11:36:01 +01:00
antc13 3baa988ad4 Changed .obj files to our own format. DummyScene.mesh may be broken. 2016-01-23 20:35:58 +01:00
stiffly a28748b35d Merge remote-tracking branch 'origin/master' into Networking 2016-01-23 18:42:16 +01:00
antc13 f1835fd89c Animations PROBABLY works fine if all joints got keyframes. 2016-01-23 18:02:42 +01:00
stiffly ecdb5ed07d Merge remote-tracking branch 'origin/master' into Networking 2016-01-23 17:51:06 +01:00
Jocke 6d2c656a04 Merge remote-tracking branch 'origin/Networking' into Networking 2016-01-23 16:41:42 +01:00
Jocke 2bf0434bcb Remade Snapshot logic from component based to entity based. 2016-01-23 16:40:38 +01:00
antc13 c984f76b2f Importing & Reading Custom animation data. TODO: Shaders. 2016-01-20 18:36:03 +01:00
antc13 84b7cf165c Reduced the chance of crashing in Export. 2016-01-20 11:46:32 +01:00
antc13 386e76f642 Puyshing 2016-01-20 09:49:54 +01:00
antc13 a47317bb32 Merge branch 'master' of https://github.com/teamfisk/TacticalZ into Importer
# Conflicts:
#	include/Engine/Collision/Collision.h
#	resources/Shaders/ForwardPlus.frag.glsl
#	resources/Shaders/ForwardPlus.vert.glsl
2016-01-19 18:26:45 +01:00
antc13 e643581971 Commit in order to pull from Master. 2016-01-19 18:21:27 +01:00
antc13 3826142e94 Now supporting multiple material per mesh. Simon changed glDrawElementsBaseVertex to glDrawElements in DrawFinalPass.cpp Hallelulijah! 2016-01-19 17:40:34 +01:00
antc13 2a3009212a Importing custom mesh without material. 2016-01-18 19:37:55 +01:00
antc13 16c39df439 Merge branch 'master' of https://github.com/teamfisk/TacticalZ into Importer
# Conflicts:
#	include/Engine/Collision/Collision.h
#	src/Engine/Rendering/Model.cpp
#	src/Engine/Rendering/RawModelAssimp.cpp
2016-01-15 18:00:30 +01:00
antc13 8437b9c734 Commit for Pull 2016-01-15 17:58:26 +01:00
antc13 6317a6092d Merge branch 'MayaExporter' of https://github.com/teamfisk/TacticalZ into Importer 2016-01-15 16:51:10 +01:00
antc13 4e70439653 Merge branch 'Importer' of https://github.com/teamfisk/TacticalZ into Importer 2016-01-15 09:48:42 +01:00
antc13 24486c314d Reworked the Exporter. 2016-01-13 14:03:58 +01:00
antc13 7b62dc19bf Spitting out Meshes & Animation Data to file. 2016-01-12 15:39:29 +01:00
antc13 0e90382fd1 Merge branch 'master' of https://github.com/teamfisk/TacticalZ into MayaExporter 2016-01-11 13:09:09 +01:00
antc13 1667358e0c We now export animations. 2016-01-08 16:47:04 +01:00
FakeShemp eb5fca898f Fix small bug with push_back order
Commited directly from GitHub. Blame it if something explodes.
2015-12-21 12:55:25 +01:00
antc13 c9db46564f Spitting out files WIP 2015-12-18 16:21:07 +01:00
Teejoon 509a989d3b Merge branch 'MayaExporter' of github.com:teamfisk/TacticalZ into MayaExporter
Conflicts:
	tools/MayaExporter/MayaExporter/Menu.cpp
2015-12-18 10:07:44 +01:00
Teejoon bc4cc5db54 Changed how we get skeletons. Made so that we could get the bind pose for each skeleton in the scene 2015-12-18 10:03:00 +01:00
antc13 73708ec706 You can now add/remove animation clips. 2015-12-17 14:58:46 +01:00
antc13 67017fcaf4 Stepping through the timeline. 2015-12-16 11:33:42 +01:00
antc13 498afb3a5e Merge branch 'MayaExporter' of https://github.com/teamfisk/TacticalZ into MayaExporter
# Conflicts:
#	tools/MayaExporter/MayaExporter/Menu.h
2015-12-15 15:41:18 +01:00
antc13 4e535c1102 File Writer WIP. Rework soon™ 2015-12-15 15:24:46 +01:00
FakeShemp 1689370356 Export the skeletons
Not really tested though
2015-12-15 11:49:59 +01:00
antc13 60b3ce89b2 Skeleton/Joints WIP 2015-12-14 12:59:54 +01:00
antc13 a22d086e60 Tested some of the Material Code. Seems to work. The project should now be following the code standard properly (hopefully). 2015-12-10 11:18:34 +01:00
FakeShemp 74c1beed20 gitignore 2015-12-09 12:03:01 +01:00
FakeShemp c8cb0ee939 Grab all materials 2015-12-09 11:58:49 +01:00
95 changed files with 3782 additions and 780 deletions
+8
View File
@@ -4,3 +4,11 @@ bin/
lib/ lib/
# Because apparently nobody has any self control # Because apparently nobody has any self control
*.orig *.orig
*.suo
*.sdf
tools/MayaExporter/MayaExporter/x64/Debug/
tools/MayaExporter/x64/Debug/
tools/MayaExporter/MayaExporter/Debug/
tools/MayaExporter/MayaExporter/GeneratedFiles/
+1 -1
Submodule assets updated: e8174f630f...068fbb2d20
+2 -1
View File
@@ -10,7 +10,8 @@
#include "../Core/Ray.h" #include "../Core/Ray.h"
#include "../Core/AABB.h" #include "../Core/AABB.h"
#include "../Rendering/RawModel.h" #include "Rendering/RawModelCustom.h"
//#include "Rendering/RawModelAssimp.h"
#include "../Core/Transform.h" #include "../Core/Transform.h"
#include "../Core/Entity.h" #include "../Core/Entity.h"
#include "../Core/EntityWrapper.h" #include "../Core/EntityWrapper.h"
+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;
}; };
} }
+2 -1
View File
@@ -23,9 +23,10 @@ struct EntityWrapper
static const EntityWrapper Invalid; static const EntityWrapper Invalid;
bool HasComponent(const std::string& componentName); bool HasComponent(const std::string& componentType);
EntityWrapper Parent(); EntityWrapper Parent();
EntityWrapper FirstChildByName(const std::string& name); EntityWrapper FirstChildByName(const std::string& name);
EntityWrapper FirstParentWithComponent(const std::string& componentType);
bool IsChildOf(EntityWrapper potentialParent); bool IsChildOf(EntityWrapper potentialParent);
bool Valid(); bool Valid();
+4 -4
View File
@@ -32,10 +32,10 @@ public:
}; };
struct FailedLoadingException : public std::exception struct FailedLoadingException : public std::exception
{ {
virtual const char* what() const throw() FailedLoadingException(char const* const _Message)
{ : std::exception(_Message)
return "Resource is failed to load."; { }
} FailedLoadingException() :std::exception("Resource failed to load.") { };
}; };
// Pretend that this is a pure virtual function that you have to implement // Pretend that this is a pure virtual function that you have to implement
+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
+9 -1
View File
@@ -43,6 +43,7 @@ private:
PacketID m_PacketID = 0; PacketID m_PacketID = 0;
PacketID m_PreviousPacketID = 0; PacketID m_PreviousPacketID = 0;
PacketID m_SendPacketID = 0; PacketID m_SendPacketID = 0;
AckBitPattern ackBitField = 0;
// Game logic // Game logic
World* m_World; World* m_World;
@@ -50,6 +51,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 +81,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 +97,16 @@ private:
// Returns if server EntityID exist in map // Returns if server EntityID exist in map
bool serverClientMapsHasEntity(EntityID serverEntityID); bool serverClientMapsHasEntity(EntityID serverEntityID);
void insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID); void insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID);
void deleteFromServerClientMaps(EntityID serverEntityID, EntityID clientEntityID);
// Events // Events
EventBroker* m_EventBroker; EventBroker* m_EventBroker;
EventRelay<Client, Events::InputCommand> m_EInputCommand; EventRelay<Client, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e); bool OnInputCommand(const Events::InputCommand& e);
EventRelay<Client, Events::PlayerDamage> m_EPlayeDamage; EventRelay<Client, Events::PlayerDamage> m_EPlayerDamage;
bool OnPlayerDamage(const Events::PlayerDamage& e); bool OnPlayerDamage(const Events::PlayerDamage& e);
EventRelay<Client, Events::PlayerSpawned> m_EPlayerSpawned;
bool OnPlayerSpawned(const Events::PlayerSpawned& e);
}; };
#endif #endif
+4 -1
View File
@@ -15,7 +15,10 @@ enum class MessageType
PlayerConnected, PlayerConnected,
BecomePlayer, BecomePlayer,
Kick, Kick,
OnPlayerSpawned OnPlayerSpawned,
EntityDeleted,
ComponentDeleted,
PlayerTransform
}; };
#endif #endif
+2 -1
View File
@@ -11,11 +11,12 @@
#include "Core/ConfigFile.h" #include "Core/ConfigFile.h"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <bitset>
#define INPUTSIZE 4097 #define INPUTSIZE 4097
typedef unsigned int PlayerID; typedef unsigned int PlayerID;
typedef unsigned int PacketID; typedef unsigned int PacketID;
typedef unsigned int UserID; typedef unsigned int AckBitPattern;
class Network class Network
{ {
+5 -3
View File
@@ -11,12 +11,12 @@ class Packet
public: public:
// arg1: Type of message (Connect, Disconnect...) // arg1: Type of message (Connect, Disconnect...)
// arg2: PacketID for identifying packet loss. // arg2: PacketID for identifying packet loss.
Packet(MessageType type, unsigned int& packetID); Packet(MessageType type, unsigned int& packetID, unsigned int lastReceivedPacket, unsigned int ackBitField);
// Used to create packet from already existing data buffer. // Used to create packet from already existing data buffer.
Packet(char* data, const int sizeOfPacket); Packet(char* data, const int sizeOfPacket);
Packet(MessageType type); Packet(MessageType type);
~Packet(); ~Packet();
void Init(MessageType type, unsigned int& packetID); void Init(MessageType type, unsigned int& packetID, unsigned int lastReceivedPacket, unsigned int ackBitField);
// Add primitive types like int, float, char... // Add primitive types like int, float, char...
template<typename T> template<typename T>
@@ -50,7 +50,9 @@ public:
// Pops the first element as if it was a string. // Pops the first element as if it was a string.
std::string ReadString(); std::string ReadString();
char* ReadData(int SizeOfData); char* ReadData(int SizeOfData);
void ChangePacketID(unsigned int& packetID); // No purpose any more
//void ChangePacketID(unsigned int& packetID);
void ChangeHeaderInfo(unsigned int& packetID, unsigned int lastReceivedPacket, unsigned int ackBitField);
int Size() { return m_Offset; }; int Size() { return m_Offset; };
char* Data() { return m_Data; }; char* Data() { return m_Data; };
unsigned int DataReadSize() { return m_ReturnDataOffset; } unsigned int DataReadSize() { return m_ReturnDataOffset; }
+8 -1
View File
@@ -1,12 +1,19 @@
#ifndef PlayerDefinition_h__ #ifndef PlayerDefinition_h__
#define PlayerDefinition_h__ #define PlayerDefinition_h__
#include <string> #include <string>
#include "../Core/Entity.h"
struct PlayerDefinition { struct PlayerDefinition {
int EntityID = -1; ::EntityID EntityID = EntityID_Invalid;
std::string Name = ""; std::string Name = "";
boost::asio::ip::udp::endpoint Endpoint; boost::asio::ip::udp::endpoint Endpoint;
// The ID of the last sent packet. (Local sequence number)
unsigned int PacketID; unsigned int PacketID;
// The ID of the last received packet. (Remote sequence number)
// This is sent as the ackNumber.
unsigned int LastPacketReceivedID;
// The bit pattern of the last 32 received packets.
unsigned int AckBitField;
std::clock_t StopTime; std::clock_t StopTime;
}; };
+21 -14
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,18 +33,18 @@ private:
boost::asio::ip::udp::socket m_Socket; boost::asio::ip::udp::socket m_Socket;
// Sending messages to client logic // Sending messages to client logic
PlayerDefinition m_PlayerDefinitions[8]; // std::map<PlayerID, PlayerDefinition> m_ConnectedPlayers;
std::vector<PlayerDefinition> m_ConnectedUsers;
char readBuffer[INPUTSIZE] = { 0 }; char readBuffer[INPUTSIZE] = { 0 };
int bytesRead = 0; int bytesRead = 0;
// time for previouse message // time for previouse message
std::clock_t previousePingMessage = std::clock(); std::clock_t previousPingMessage = std::clock();
std::clock_t previousSnapshotMessage = std::clock(); std::clock_t previousSnapshotMessage = std::clock();
std::clock_t timOutTimer = std::clock(); std::clock_t timOutTimer = std::clock();
// How often we send messages (milliseconds) // How often we send messages (milliseconds)
int 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;
@@ -56,32 +58,37 @@ private:
PacketID m_PreviousPacketID = 0; PacketID m_PreviousPacketID = 0;
// Private member functions // Private member functions
void addChildrenToPacket(Packet& packet, EntityID entityID);
void broadcast(Packet& packet);
void checkForTimeOuts();
void disconnect(PlayerID playerID);
void identifyPacketLoss();
void kick(PlayerID player);
int receive(char* data); int receive(char* data);
void readFromClients(); void readFromClients();
void send(Packet& packet, UserID user); void send(PlayerID playerID, Packet& packet);
void send(PlayerID player, Packet& packet);
void send(Packet& packet); void send(Packet& packet);
void broadcast(Packet& packet);
void sendSnapshot(); void sendSnapshot();
void sendPing(); void sendPing();
void checkForTimeOuts(); void parseClientPing(PlayerID playerID);
void disconnect(UserID user); void parseConnect(Packet& packet, PlayerID playerID);
void parseDisconnect();
void parseMessageType(Packet& packet); void parseMessageType(Packet& packet);
void parseOnInputCommand(Packet& packet); void parseOnInputCommand(Packet& packet);
void parseOnPlayerDamage(Packet& packet); void parseOnPlayerDamage(Packet& packet);
void parseConnect(Packet& packet);
void parseDisconnect();
void parseClientPing();
void parsePing(); void parsePing();
void identifyPacketLoss();
void createPlayer();
void kick(PlayerID player);
PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); PlayerID GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
// Debug event // Debug event
EventRelay<Server, Events::InputCommand> m_EInputCommand; EventRelay<Server, Events::InputCommand> m_EInputCommand;
bool OnInputCommand(const Events::InputCommand& e); bool OnInputCommand(const Events::InputCommand& e);
EventRelay<Server, Events::PlayerSpawned> m_EPlayerSpawned; 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
+4 -4
View File
@@ -1,7 +1,8 @@
#ifndef Model_h__ #ifndef Model_h__
#define Model_h__ #define Model_h__
#include "RawModel.h" #include "Rendering/RawModelCustom.h"
//#include "Rendering/RawModelAssimp.h"
#include "../OpenGL.h" #include "../OpenGL.h"
class Model : public ThreadUnsafeResource class Model : public ThreadUnsafeResource
@@ -19,12 +20,11 @@ public:
GLuint VAO; GLuint VAO;
GLuint ElementBuffer; GLuint ElementBuffer;
RawModel* m_RawModel;
private: private:
RawModel* m_RawModel;
GLuint VertexBuffer; GLuint VertexBuffer;
GLuint DiffuseVertexColorBuffer;
GLuint SpecularVertexColorBuffer;
GLuint NormalBuffer; GLuint NormalBuffer;
GLuint TangentNormalsBuffer; GLuint TangentNormalsBuffer;
GLuint BiTangentNormalsBuffer; GLuint BiTangentNormalsBuffer;
+8
View File
@@ -24,6 +24,10 @@ struct ModelJob : RenderJob
DiffuseTexture = matGroup.Texture.get(); DiffuseTexture = matGroup.Texture.get();
NormalTexture = matGroup.NormalMap.get(); NormalTexture = matGroup.NormalMap.get();
SpecularTexture = matGroup.SpecularMap.get(); SpecularTexture = matGroup.SpecularMap.get();
IncandescenceTexture = matGroup.IncandescenceMap.get();
DiffuseColor = matGroup.DiffuseColor;
SpecularColor = matGroup.SpecularColor;
IncandescenceColor = matGroup.IncandescenceColor;
StartIndex = matGroup.StartIndex; StartIndex = matGroup.StartIndex;
EndIndex = matGroup.EndIndex; EndIndex = matGroup.EndIndex;
Matrix = matrix; Matrix = matrix;
@@ -43,9 +47,13 @@ struct ModelJob : RenderJob
const Texture* DiffuseTexture; const Texture* DiffuseTexture;
const Texture* NormalTexture; const Texture* NormalTexture;
const Texture* SpecularTexture; const Texture* SpecularTexture;
const Texture* IncandescenceTexture;
float Shininess = 0.f; float Shininess = 0.f;
glm::vec4 Color; glm::vec4 Color;
const ::Model* Model = nullptr; const ::Model* Model = nullptr;
glm::vec4 DiffuseColor;
glm::vec4 SpecularColor;
glm::vec4 IncandescenceColor;
unsigned int StartIndex = 0; unsigned int StartIndex = 0;
unsigned int EndIndex = 0; unsigned int EndIndex = 0;
World* World; World* World;
@@ -1,5 +1,7 @@
#ifndef RawModel_h__ #ifndef RawModelAssimp_h__
#define RawModel_h__ #define RawModelAssimp_h__
#ifdef USING_ASSIMP_AS_IMPORTER
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
@@ -18,29 +20,27 @@
#include "Texture.h" #include "Texture.h"
#include "Skeleton.h" #include "Skeleton.h"
class RawModel : public Resource #define RawModel RawModelAssimp
class RawModelAssimp : public Resource
{ {
friend class ResourceManager; friend class ResourceManager;
protected: protected:
RawModel(std::string fileName); RawModelAssimp(std::string fileName);
public: public:
~RawModel(); ~RawModelAssimp();
struct Vertex struct Vertex
{ {
glm::vec3 Position; glm::vec3 Position;
glm::vec3 Normal; glm::vec3 Normal;
glm::vec3 Tangent; glm::vec3 Tangent;
glm::vec3 BiTangent; glm::vec3 BiNormal;
glm::vec2 TextureCoords; glm::vec2 TextureCoords;
glm::vec4 DiffuseVertexColor; glm::vec4 BoneIndices;
glm::vec4 SpecularVertexColor; glm::vec4 BoneWeights;
glm::vec4 BoneIndices1;
glm::vec4 BoneIndices2;
glm::vec4 BoneWeights1;
glm::vec4 BoneWeights2;
}; };
struct MaterialGroup struct MaterialGroup
@@ -68,8 +68,6 @@ private:
std::vector<glm::ivec2> BoneIndices; std::vector<glm::ivec2> BoneIndices;
std::vector<glm::vec2> BoneWeights; std::vector<glm::vec2> BoneWeights;
std::vector<glm::vec3> Normals; std::vector<glm::vec3> Normals;
std::vector<glm::vec4> DiffuseVertexColor;
std::vector<glm::vec4> SpecularVertexColor;
std::vector<glm::vec3> TangentNormals; std::vector<glm::vec3> TangentNormals;
std::vector<glm::vec3> BiTangentNormals; std::vector<glm::vec3> BiTangentNormals;
std::vector<glm::vec2> TextureCoords; std::vector<glm::vec2> TextureCoords;
@@ -78,3 +76,4 @@ private:
}; };
#endif #endif
#endif
+102
View File
@@ -0,0 +1,102 @@
#ifndef RawModelCustom_h__
#define RawModelCustom_h__
#ifndef USING_ASSIMP_AS_IMPORTER
#define RawModel RawModelCustom
#include <fstream>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <stack>
#include <boost/filesystem/path.hpp>
#include "../Common.h"
#include "../GLM.h"
#include "../Core/ResourceManager.h"
#include "Texture.h"
#include "Skeleton.h"
#include "boost\endian\buffers.hpp"
class RawModelCustom : public Resource
{
friend class ResourceManager;
protected:
RawModelCustom(std::string fileName);
public:
~RawModelCustom();
struct Vertex
{
glm::vec3 Position;
glm::vec3 Normal;
glm::vec3 Tangent;
glm::vec3 BiNormal;
glm::vec2 TextureCoords;
glm::vec4 BoneIndices;
glm::vec4 BoneWeights;
};
struct MaterialGroup
{
float SpecularExponent;
float ReflectionFactor;
glm::vec4 DiffuseColor{ 1.0f, 1.0f, 1.0f, 1.0f };
glm::vec4 SpecularColor{ 1.0f, 1.0f, 1.0f, 1.0f };
glm::vec4 IncandescenceColor{ 1.0f, 1.0f, 1.0f, 1.0f };
unsigned int StartIndex;
unsigned int EndIndex;
//float Transparency;
std::string TexturePath;
std::shared_ptr<::Texture> Texture;
std::string NormalMapPath;
std::shared_ptr<::Texture> NormalMap;
std::string SpecularMapPath;
std::shared_ptr<::Texture> SpecularMap;
std::string IncandescenceMapPath;
std::shared_ptr<::Texture> IncandescenceMap;
};
std::vector<MaterialGroup> MaterialGroups;
std::vector<Vertex> m_Vertices;
std::vector<unsigned int> m_Indices;
Skeleton* m_Skeleton = nullptr;
glm::mat4 m_Matrix;
private:
void ReadMeshFile(std::string filePath);
void ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
void ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
void ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
void ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize);
void ReadMaterialFile(std::string filePath);
void ReadMaterials(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
void ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
void ReadAnimationFile(std::string filePath);
void ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
void ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize);
void ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips);
void ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex);
void ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfJoints, Skeleton::Animation& animation);
//void CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID);
};
#else
#include "RawModelAssimp.h"
#endif
#endif
+2 -1
View File
@@ -4,6 +4,7 @@
#include <sstream> #include <sstream>
#include "Common.h" #include "Common.h"
#include "../GLM.h" #include "../GLM.h"
#include <glm/gtx/matrix_decompose.hpp>
//struct Bone //struct Bone
//{ //{
@@ -38,9 +39,9 @@ public:
, OffsetMatrix(offsetMatrix) , OffsetMatrix(offsetMatrix)
{ } { }
int ID;
std::string Name; std::string Name;
glm::mat4 OffsetMatrix; glm::mat4 OffsetMatrix;
int ID;
Bone* Parent; Bone* Parent;
std::vector<Bone*> Children; std::vector<Bone*> Children;
+11 -8
View File
@@ -9,6 +9,7 @@
#include "Core/System.h" #include "Core/System.h"
#include "Core/EPlayerDamage.h" #include "Core/EPlayerDamage.h"
#include "Core/EShoot.h" #include "Core/EShoot.h"
#include "Core/EPlayerSpawned.h"
#include "Input/EInputCommand.h" #include "Input/EInputCommand.h"
#include <tuple> #include <tuple>
@@ -23,16 +24,18 @@ public:
virtual void Update(double dt) override; virtual void Update(double dt) override;
private: private:
//methods which will take care of specific events
EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
bool WeaponSystem::OnShoot(const Events::Shoot& e);
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e);
IRenderer* m_Renderer; IRenderer* m_Renderer;
std::vector<std::tuple<EntityID, glm::vec2>> m_EShootVector; // State
EntityWrapper m_LocalPlayer = EntityWrapper::Invalid;
// Events
EventRelay<WeaponSystem, Events::PlayerSpawned> m_EPlayerSpawned;
bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e);
EventRelay<WeaponSystem, Events::Shoot> m_EShoot;
bool WeaponSystem::OnShoot(const Events::Shoot& e);
EventRelay<WeaponSystem, Events::InputCommand> m_EInputCommand;
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e);
}; };
#endif #endif
+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
+273
View File
@@ -0,0 +1,273 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:Camera/>
<c:Listener/>
<c:Transform>
<Position X="4.52910185" Y="5.50171423" Z="7.69566345"/>
<Orientation X="-0.453785568" Y="0.436270237" Z="-1.03594937e-06"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>models/dummyscene.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="-0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>models/animtest.</Resource>
</c:Model>
<c:Transform>
<Position X="-0.0966923237" Y="1.2939688" Z="0.399702221"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>models/animTest.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="1.31816244" Z="1.1888907"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>models/animTest.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0.708824873" Y="1.30000007" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>models/animTest.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="1.36948848" Y="1.20000005" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:DirectionalLight>
<Intensity>0.13000047206878662</Intensity>
</c:DirectionalLight>
<c:Transform>
<Position X="0" Y="2.77622533" Z="0"/>
<Orientation X="0" Y="1.30900002" Z="1.73600006"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:RaptorCopter>
<Speed>0.30000001192092896</Speed>
<Axis X="0" Y="5" Z="0"/>
</c:RaptorCopter>
<c:Transform>
<Orientation X="117.03714" Y="3023.50244" Z="3.03297734"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="1" G="1" R="0"/>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="0" Y="1" Z="1.29999995"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0" G="1" R="0"/>
<Radius>5</Radius>
<Intensity>0.80000001192092896</Intensity>
</c:PointLight>
<c:Transform>
<Position X="0" Y="1" Z="-1.29999995"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="1" G="0" R="0.478431374"/>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="-1.30000007" Y="1" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0" G="1" R="1"/>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="1.29999995" Y="1" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity>
<Components>
<c:RaptorCopter>
<Speed>0.50999981164932251</Speed>
<Axis X="0" Y="1" Z="0"/>
</c:RaptorCopter>
<c:Transform>
<Position X="0" Y="-0.100000001" Z="0"/>
<Orientation X="0" Y="191.457993" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0.301960796" G="0.0901960805" R="0.247058824"/>
<Radius>5</Radius>
<Intensity>5</Intensity>
</c:PointLight>
<c:Transform>
<Position X="0" Y="3" Z="5"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0.960784316" G="1" R="0"/>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="0" Y="3" Z="-7.66608238"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0.00784313772" G="1" R="1"/>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="-3.47176075" Y="3" Z="-8.09415054"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0" G="0" R="1"/>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="-9.50536728" Y="2" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="1" G="0" R="1"/>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="0" Y="3" Z="4.40877533"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0.431372553" G="0.0745098069" R="1"/>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="5.83008432" Y="3" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0" G="0.623529434" R="0.929411769"/>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="3.72500014" Y="3" Z="-4.26100016"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="0" Y="3" Z="-7.50000048"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:PointLight>
<Color A="1" B="0.192156866" G="1" R="0"/>
<Radius>5</Radius>
</c:PointLight>
<c:Transform>
<Position X="-5.90153885" Y="3" Z="-5.40681458"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
+7 -7
View File
@@ -9,7 +9,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource> <Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -41,7 +41,7 @@
<HomePointForTeam>3</HomePointForTeam> <HomePointForTeam>3</HomePointForTeam>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="0.200000003" R="0"/> <Color A="1" B="1" G="0.200000003" R="0"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -61,7 +61,7 @@
<CapturePointNumber>1</CapturePointNumber> <CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="1" R="1"/> <Color A="1" B="0" G="1" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -81,7 +81,7 @@
<CapturePointNumber>2</CapturePointNumber> <CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="1" R="0"/> <Color A="1" B="1" G="1" R="0"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -102,7 +102,7 @@
<CapturePointNumber>3</CapturePointNumber> <CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="0.200000003" R="1"/> <Color A="1" B="0" G="0.200000003" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -120,7 +120,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0.482352942" G="0.490196079" R="1"/> <Color A="1" B="0.482352942" G="0.490196079" R="1"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -138,7 +138,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="0.196078435" R="0.196078435"/> <Color A="1" B="1" G="0.196078435" R="0.196078435"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -9,7 +9,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource> <Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -42,7 +42,7 @@
<CaptureTimer>6.9158446328696002</CaptureTimer> <CaptureTimer>6.9158446328696002</CaptureTimer>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="1" R="1"/> <Color A="1" B="0" G="1" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -63,7 +63,7 @@
<CapturePointNumber>1</CapturePointNumber> <CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="1" R="0"/> <Color A="1" B="1" G="1" R="0"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -83,7 +83,7 @@
<CapturePointNumber>2</CapturePointNumber> <CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="0.200000003" R="1"/> <Color A="1" B="0" G="0.200000003" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -104,7 +104,7 @@
<CapturePointNumber>3</CapturePointNumber> <CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="0.200000003" R="1"/> <Color A="1" B="0" G="0.200000003" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -122,7 +122,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0.482352942" G="0.490196079" R="1"/> <Color A="1" B="0.482352942" G="0.490196079" R="1"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -140,7 +140,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="0.196078435" R="0.196078435"/> <Color A="1" B="1" G="0.196078435" R="0.196078435"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -9,7 +9,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource> <Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -41,7 +41,7 @@
<HomePointForTeam>3</HomePointForTeam> <HomePointForTeam>3</HomePointForTeam>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="0.200000003" R="0"/> <Color A="1" B="1" G="0.200000003" R="0"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -61,7 +61,7 @@
<CapturePointNumber>1</CapturePointNumber> <CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="1" R="0"/> <Color A="1" B="1" G="1" R="0"/>
</c:Model> </c:Model>
<c:Team/> <c:Team/>
@@ -79,7 +79,7 @@
<CapturePointNumber>2</CapturePointNumber> <CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="1" R="1"/> <Color A="1" B="0" G="1" R="1"/>
</c:Model> </c:Model>
<c:Team/> <c:Team/>
@@ -98,7 +98,7 @@
<CapturePointNumber>3</CapturePointNumber> <CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="0.200000003" R="1"/> <Color A="1" B="0" G="0.200000003" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -116,7 +116,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0.482352942" G="0.490196079" R="1"/> <Color A="1" B="0.482352942" G="0.490196079" R="1"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -134,7 +134,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="0.196078435" R="0.196078435"/> <Color A="1" B="1" G="0.196078435" R="0.196078435"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
+10 -10
View File
@@ -9,7 +9,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource> <Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -41,7 +41,7 @@
<HomePointForTeam>3</HomePointForTeam> <HomePointForTeam>3</HomePointForTeam>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="0.200000003" R="0"/> <Color A="1" B="1" G="0.200000003" R="0"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -61,7 +61,7 @@
<CapturePointNumber>1</CapturePointNumber> <CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="1" R="1"/> <Color A="1" B="0" G="1" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -81,7 +81,7 @@
<CapturePointNumber>2</CapturePointNumber> <CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="1" R="0"/> <Color A="1" B="1" G="1" R="0"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -101,7 +101,7 @@
<CapturePointNumber>3</CapturePointNumber> <CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="0.200000003" R="1"/> <Color A="1" B="0" G="0.200000003" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -122,7 +122,7 @@
<CapturePointNumber>4</CapturePointNumber> <CapturePointNumber>4</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="0.200000003" R="1"/> <Color A="1" B="0" G="0.200000003" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -140,7 +140,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0.482352942" G="0.490196079" R="1"/> <Color A="1" B="0.482352942" G="0.490196079" R="1"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -158,7 +158,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0.482352942" G="0.490196079" R="1"/> <Color A="1" B="0.482352942" G="0.490196079" R="1"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -176,7 +176,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="0.196078435" R="0.196078435"/> <Color A="1" B="1" G="0.196078435" R="0.196078435"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -194,7 +194,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="0.196078435" R="0.196078435"/> <Color A="1" B="1" G="0.196078435" R="0.196078435"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
+10 -10
View File
@@ -9,7 +9,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource> <Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -41,7 +41,7 @@
<HomePointForTeam>3</HomePointForTeam> <HomePointForTeam>3</HomePointForTeam>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="0.200000003" R="0"/> <Color A="1" B="1" G="0.200000003" R="0"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -61,7 +61,7 @@
<CapturePointNumber>1</CapturePointNumber> <CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="1" R="0"/> <Color A="1" B="1" G="1" R="0"/>
</c:Model> </c:Model>
<c:Team/> <c:Team/>
@@ -79,7 +79,7 @@
<CapturePointNumber>2</CapturePointNumber> <CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
</c:Model> </c:Model>
<c:Team/> <c:Team/>
<c:Transform> <c:Transform>
@@ -96,7 +96,7 @@
<CapturePointNumber>3</CapturePointNumber> <CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="1" R="1"/> <Color A="1" B="0" G="1" R="1"/>
</c:Model> </c:Model>
<c:Team/> <c:Team/>
@@ -115,7 +115,7 @@
<CapturePointNumber>4</CapturePointNumber> <CapturePointNumber>4</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="0.200000003" R="1"/> <Color A="1" B="0" G="0.200000003" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -133,7 +133,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0.482352942" G="0.490196079" R="1"/> <Color A="1" B="0.482352942" G="0.490196079" R="1"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -151,7 +151,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0.482352942" G="0.490196079" R="1"/> <Color A="1" B="0.482352942" G="0.490196079" R="1"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -169,7 +169,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="0.196078435" R="0.196078435"/> <Color A="1" B="1" G="0.196078435" R="0.196078435"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -187,7 +187,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="0.196078435" R="0.196078435"/> <Color A="1" B="1" G="0.196078435" R="0.196078435"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
+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 -1
View File
@@ -24,7 +24,7 @@
<Static>false</Static> <Static>false</Static>
</c:Collidable> </c:Collidable>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0" G="1" R="0"/> <Color A="1" B="0" G="1" R="0"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -6,7 +6,7 @@
<Orientation X="0" Y="0" Z="0"/> <Orientation X="0" Y="0" Z="0"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/DummyScene.obj</Resource> <Resource>Models/DummyScene.mesh</Resource>
</c:Model> </c:Model>
</Components> </Components>
<Children> <Children>
@@ -17,7 +17,7 @@
<Scale X="1" Y="1" Z="1"/> <Scale X="1" Y="1" Z="1"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource> <Resource>Models/Core/UnitSphere.mesh</Resource>
</c:Model> </c:Model>
</Components> </Components>
</Entity> </Entity>
@@ -28,7 +28,7 @@
<Scale X="2" Y="2" Z="2"/> <Scale X="2" Y="2" Z="2"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/RotationWidgetX.obj</Resource> <Resource>Models/RotationWidgetX.mesh</Resource>
</c:Model> </c:Model>
<c:Trigger> <c:Trigger>
</c:Trigger> </c:Trigger>
@@ -43,7 +43,7 @@
<Position X="2.5"/> <Position X="2.5"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model> </c:Model>
<c:AABB> <c:AABB>
</c:AABB> </c:AABB>
@@ -69,7 +69,7 @@
<Orientation X="0.0" Y="0" Z="1.0"/> <Orientation X="0.0" Y="0" Z="1.0"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/Core/UnitRaptor.obj</Resource> <Resource>Models/Core/UnitRaptor.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/> <Color R="1" G="0.4" B="0.8"/>
</c:Model> </c:Model>
</Components> </Components>
@@ -94,7 +94,7 @@
<Orientation X="0" Y="0" Z="0"/> <Orientation X="0" Y="0" Z="0"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/> <Color R="1" G="0.4" B="0.8"/>
</c:Model> </c:Model>
</Components> </Components>
@@ -107,7 +107,7 @@
<Orientation X="0" Y="1.57" Z="0"/> <Orientation X="0" Y="1.57" Z="0"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/> <Color R="1" G="0.4" B="0.8"/>
</c:Model> </c:Model>
</Components> </Components>
@@ -9,7 +9,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Scale X="100" Y="1" Z="100"/> <Scale X="100" Y="1" Z="100"/>
@@ -58,7 +58,7 @@
<Components> <Components>
<c:DirectionalLight/> <c:DirectionalLight/>
<c:Model> <c:Model>
<Resource>Models/DirectionalLightWidget.obj</Resource> <Resource>Models/DirectionalLightWidget.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="2.1529963" Y="6.59221172" Z="0.169116676"/> <Position X="2.1529963" Y="6.59221172" Z="0.169116676"/>
@@ -70,7 +70,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Assault.obj</Resource> <Resource>Models/Assault.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="-2.00568962" Y="0.527161121" Z="0"/> <Position X="-2.00568962" Y="0.527161121" Z="0"/>
@@ -94,7 +94,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource> <Resource>Models/Core/UnitSphere.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="0" Y="3.70000029" Z="0"/> <Position X="0" Y="3.70000029" Z="0"/>
@@ -18,7 +18,7 @@
<Axis X="1" Y="0" Z="0"/> <Axis X="1" Y="0" Z="0"/>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/RotationWidgetX.obj</Resource> <Resource>Models/RotationWidgetX.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -33,7 +33,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/RotationWidgetY.obj</Resource> <Resource>Models/RotationWidgetY.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -48,7 +48,7 @@
<Axis X="0" Y="0" Z="1"/> <Axis X="0" Y="0" Z="1"/>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/RotationWidgetZ.obj</Resource> <Resource>Models/RotationWidgetZ.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -3,7 +3,7 @@
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/ScaleWidgetOrigin.obj</Resource> <Resource>Models/ScaleWidgetOrigin.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
<c:UniformScale> <c:UniformScale>
@@ -20,7 +20,7 @@
</Type> </Type>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/ScaleWidgetX.obj</Resource> <Resource>Models/ScaleWidgetX.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -34,7 +34,7 @@
</Type> </Type>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/ScaleWidgetY.obj</Resource> <Resource>Models/ScaleWidgetY.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -48,7 +48,7 @@
</Type> </Type>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/ScaleWidgetZ.obj</Resource> <Resource>Models/ScaleWidgetZ.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -3,7 +3,7 @@
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/TranslationWidgetOrigin.obj</Resource> <Resource>Models/TranslationWidgetOrigin.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
<c:UniformScale> <c:UniformScale>
@@ -18,7 +18,7 @@
<Axis X="1" Y="0" Z="0"/> <Axis X="1" Y="0" Z="0"/>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/TranslationWidgetX.obj</Resource> <Resource>Models/TranslationWidgetX.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -30,7 +30,7 @@
<Axis X="0" Y="1" Z="0"/> <Axis X="0" Y="1" Z="0"/>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/TranslationWidgetY.obj</Resource> <Resource>Models/TranslationWidgetY.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -42,7 +42,7 @@
<Axis X="0" Y="0" Z="1"/> <Axis X="0" Y="0" Z="1"/>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/TranslationWidgetZ.obj</Resource> <Resource>Models/TranslationWidgetZ.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -54,7 +54,7 @@
<Axis X="0" Y="1" Z="1"/> <Axis X="0" Y="1" Z="1"/>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/WidgetPlaneX.obj</Resource> <Resource>Models/WidgetPlaneX.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -66,7 +66,7 @@
<Axis X="1" Y="0" Z="1"/> <Axis X="1" Y="0" Z="1"/>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/WidgetPlaneY.obj</Resource> <Resource>Models/WidgetPlaneY.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -78,7 +78,7 @@
<Axis X="1" Y="1" Z="0"/> <Axis X="1" Y="1" Z="0"/>
</c:EditorWidget> </c:EditorWidget>
<c:Model> <c:Model>
<Resource>Models/WidgetPlaneZ.obj</Resource> <Resource>Models/WidgetPlaneZ.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
+11 -1
View File
@@ -5,6 +5,16 @@
<c:Transform/> <c:Transform/>
</Components> </Components>
<Children/> <Children>
<Entity>
<Components>
<c:Model>
<Resource></Resource>
</c:Model>
<c:Transform/>
</Components>
<Children/>
</Entity>
</Children>
</Entity> </Entity>
+128
View File
@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity name="Scenemesh">
<Components>
<c:Model>
<Resource>Models\MapVersion1.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
<Children/>
</Entity>
<Entity name="DirectionalLight">
<Components>
<c:DirectionalLight>
<Intensity>2</Intensity>
</c:DirectionalLight>
<c:Model>
<Resource>Models/DirectionalLightWidget.mesh</Resource>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="0" Y="61.9050903" Z="0"/>
<Scale X="50" Y="50" Z="50"/>
<Orientation X="4.42700005" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="PointLight">
<Components>
<c:PointLight>
<Radius>8</Radius>
<Intensity>2.7999999523162842</Intensity>
</c:PointLight>
<c:Transform>
<Position X="0.370978802" Y="1.88588905" Z="-0.55370003"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="PointLight">
<Components>
<c:PointLight>
<Radius>8</Radius>
<Intensity>2.7999999523162842</Intensity>
</c:PointLight>
<c:Transform>
<Position X="38.0347443" Y="1.88588905" Z="62.7340622"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-0.904668212" Y="0" Z="8.48177528"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-4.61666441" Y="0" Z="-8.51156044"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="-7.56803513" Y="-0.0658408776" Z="0.59418112"/>
<Scale X="1.20000005" Y="0.900000036" Z="1.30000007"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="10.460474" Y="0" Z="-3.92580295"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:AABB/>
<c:Collidable/>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="1.09146011" Y="-0.315138876" Z="-0.333906144"/>
<Scale X="150" Y="1" Z="180"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+30
View File
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Transform/>
</Components>
<Children>
<Entity>
<Components>
<c:Camera/>
<c:Listener/>
<c:Transform>
<Orientation X="0" Y="-0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity>
<Components>
<c:Model>
<Resource>models/animTest.mesh</Resource>
</c:Model>
<c:Transform/>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
+10 -10
View File
@@ -11,7 +11,7 @@
<c:AABB/> <c:AABB/>
<c:Collidable/> <c:Collidable/>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0.513725519" G="0" R="1"/> <Color A="1" B="0.513725519" G="0" R="1"/>
<Visible>false</Visible> <Visible>false</Visible>
</c:Model> </c:Model>
@@ -42,7 +42,7 @@
<Components> <Components>
<c:SpawnPoint/> <c:SpawnPoint/>
<c:Model> <c:Model>
<Resource>Models/Assault.obj</Resource> <Resource>Models/Assault.mesh</Resource>
<Color A="1" B="0" G="0" R="1"/> <Color A="1" B="0" G="0" R="1"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -55,7 +55,7 @@
<Components> <Components>
<c:SpawnPoint/> <c:SpawnPoint/>
<c:Model> <c:Model>
<Resource>Models/Assault.obj</Resource> <Resource>Models/Assault.mesh</Resource>
<Color A="1" B="0.0117647061" G="0" R="1"/> <Color A="1" B="0.0117647061" G="0" R="1"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -70,7 +70,7 @@
<Components> <Components>
<c:DirectionalLight/> <c:DirectionalLight/>
<c:Model> <c:Model>
<Resource>Models/DirectionalLightWidget.obj</Resource> <Resource>Models/DirectionalLightWidget.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="-6.00145912" Y="1.42697716" Z="3.04144025"/> <Position X="-6.00145912" Y="1.42697716" Z="3.04144025"/>
@@ -82,7 +82,7 @@
<Entity name="ObstacleCourse"> <Entity name="ObstacleCourse">
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Test/ObstacleCourse.obj</Resource> <Resource>Models/Test/ObstacleCourse.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -93,7 +93,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>
<Visible>false</Visible> <Visible>false</Visible>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -108,7 +108,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>
<Visible>false</Visible> <Visible>false</Visible>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -123,7 +123,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>
<Visible>false</Visible> <Visible>false</Visible>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -154,7 +154,7 @@
<Components> <Components>
<c:SpawnPoint/> <c:SpawnPoint/>
<c:Model> <c:Model>
<Resource>Models/Assault.obj</Resource> <Resource>Models/Assault.mesh</Resource>
<Color A="1" B="1" G="0.254901975" R="0"/> <Color A="1" B="1" G="0.254901975" R="0"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -167,7 +167,7 @@
<Components> <Components>
<c:SpawnPoint/> <c:SpawnPoint/>
<c:Model> <c:Model>
<Resource>Models/Assault.obj</Resource> <Resource>Models/Assault.mesh</Resource>
<Color A="1" B="1" G="0.254901975" R="0"/> <Color A="1" B="1" G="0.254901975" R="0"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
+3 -3
View File
@@ -11,7 +11,7 @@
<c:AABB/> <c:AABB/>
<c:Collidable/> <c:Collidable/>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="0" R="0"/> <Color A="1" B="1" G="0" R="0"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -27,7 +27,7 @@
<Static>false</Static> <Static>false</Static>
</c:Collidable> </c:Collidable>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0" G="0" R="1"/> <Color A="1" B="0" G="0" R="1"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -42,7 +42,7 @@
<Static>false</Static> <Static>false</Static>
</c:Collidable> </c:Collidable>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0" G="1" R="0"/> <Color A="1" B="0" G="1" R="0"/>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
+8 -10
View File
@@ -8,9 +8,7 @@
</c:AABB> </c:AABB>
<c:Collidable/> <c:Collidable/>
<c:Model/> <c:Model/>
<c:Physics> <c:Physics/>
<Velocity X="8.33307467e-09" Y="0" Z="9.82836834e-09"/>
</c:Physics>
<c:Player> <c:Player>
<MovementSpeed>5</MovementSpeed> <MovementSpeed>5</MovementSpeed>
</c:Player> </c:Player>
@@ -20,7 +18,7 @@
</Team> </Team>
</c:Team> </c:Team>
<c:Transform> <c:Transform>
<Position X="2.84928203" Y="0.0264999866" Z="7.31610918"/> <Position X="-0.246963501" Y="0.0265000071" Z="3.01600003"/>
<Orientation X="0" Y="2.14675093" Z="0"/> <Orientation X="0" Y="2.14675093" Z="0"/>
</c:Transform> </c:Transform>
</Components> </Components>
@@ -31,7 +29,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>
@@ -53,7 +50,7 @@
<Entity name="CameraModel"> <Entity name="CameraModel">
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Camera.obj</Resource> <Resource>Models/Camera.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="0" Y="0.0331346765" Z="-0.0792061687"/> <Position X="0" Y="0.0331346765" Z="-0.0792061687"/>
@@ -68,7 +65,7 @@
<Components> <Components>
<c:Camera/> <c:Camera/>
<c:Model> <c:Model>
<Resource>Models/Camera.obj</Resource> <Resource>Models/Camera.mesh</Resource>
<Visible>false</Visible> <Visible>false</Visible>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -81,7 +78,8 @@
<Entity name="PlayerModel"> <Entity name="PlayerModel">
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/AssaultHeadless.obj</Resource> <Resource>Models/AssaultHeadless.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"/> <Orientation X="0" Y="3.14159274" Z="0"/>
@@ -92,7 +90,7 @@
<Entity name="AABBStanding"> <Entity name="AABBStanding">
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="0.427450985" B="1" G="1" R="1"/> <Color A="0.427450985" B="1" G="1" R="1"/>
<Visible>false</Visible> <Visible>false</Visible>
</c:Model> </c:Model>
@@ -106,7 +104,7 @@
<Entity name="AABBCrouching"> <Entity name="AABBCrouching">
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="0.745098054" B="1" G="0" R="1"/> <Color A="0.745098054" B="1" G="0" R="1"/>
<Visible>false</Visible> <Visible>false</Visible>
</c:Model> </c:Model>
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity name="PointLight" xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:PointLight>
<Radius>8</Radius>
<Intensity>2.7999999523162842</Intensity>
</c:PointLight>
<c:Transform>
<Position X="0.370978802" Y="1.88588905" Z="-0.55370003"/>
</c:Transform>
</Components>
<Children/>
</Entity>
+4 -4
View File
@@ -7,7 +7,7 @@
<Orientation X="0.0" Y="0" Z="0.0"/> <Orientation X="0.0" Y="0" Z="0.0"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/Core/UnitRaptor.obj</Resource> <Resource>Models/Core/UnitRaptor.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/> <Color R="1" G="0.4" B="0.8"/>
</c:Model> </c:Model>
</Components> </Components>
@@ -31,7 +31,7 @@
<Scale X="0.1" Y="0.4" Z="0.1"/> <Scale X="0.1" Y="0.4" Z="0.1"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCylinder.obj</Resource> <Resource>Models/Core/UnitCylinder.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/> <Color R="1" G="0.4" B="0.8"/>
</c:Model> </c:Model>
</Components> </Components>
@@ -44,7 +44,7 @@
<Orientation X="0" Y="0" Z="0"/> <Orientation X="0" Y="0" Z="0"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/> <Color R="1" G="0.4" B="0.8"/>
</c:Model> </c:Model>
</Components> </Components>
@@ -57,7 +57,7 @@
<Orientation X="0" Y="1.57" Z="0"/> <Orientation X="0" Y="1.57" Z="0"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color R="1" G="0.4" B="0.8"/> <Color R="1" G="0.4" B="0.8"/>
</c:Model> </c:Model>
</Components> </Components>
+7 -7
View File
@@ -12,7 +12,7 @@
<Name>ActionCamera</Name> <Name>ActionCamera</Name>
</c:Camera> </c:Camera>
<c:Model> <c:Model>
<Resource>Models/Camera.obj</Resource> <Resource>Models/Camera.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="-0.504807115" Y="6.00582743" Z="9.68687439"/> <Position X="-0.504807115" Y="6.00582743" Z="9.68687439"/>
@@ -39,7 +39,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Core/UnitPlane.obj</Resource> <Resource>Models/Core/UnitPlane.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="0" Y="-1" Z="0.600000024"/> <Position X="0" Y="-1" Z="0.600000024"/>
@@ -51,7 +51,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Assault.obj</Resource> <Resource>Models/Assault.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="-2.5" Y="0" Z="1"/> <Position X="-2.5" Y="0" Z="1"/>
@@ -190,7 +190,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Assault.obj</Resource> <Resource>Models/Assault.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="2.5" Y="0" Z="1"/> <Position X="2.5" Y="0" Z="1"/>
@@ -205,7 +205,7 @@
</c:Camera> </c:Camera>
<c:Listener/> <c:Listener/>
<c:Model> <c:Model>
<Resource>Models/Camera.obj</Resource> <Resource>Models/Camera.mesh</Resource>
<Visible>false</Visible> <Visible>false</Visible>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
@@ -237,7 +237,7 @@
<Intensity>0.80000001192092896</Intensity> <Intensity>0.80000001192092896</Intensity>
</c:DirectionalLight> </c:DirectionalLight>
<c:Model> <c:Model>
<Resource>Models/DirectionalLightWidget.obj</Resource> <Resource>Models/DirectionalLightWidget.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="-0.0013256073" Y="1.89540339" Z="6.53467274"/> <Position X="-0.0013256073" Y="1.89540339" Z="6.53467274"/>
@@ -249,7 +249,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="-5.4082036" Y="0" Z="-1.84950542"/> <Position X="-5.4082036" Y="0" Z="-1.84950542"/>
+10 -10
View File
@@ -9,7 +9,7 @@
<Entity> <Entity>
<Components> <Components>
<c:Model> <c:Model>
<Resource>../assets/Models/DummyScene.obj</Resource> <Resource>../assets/Models/DummyScene.mesh</Resource>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
</Components> </Components>
@@ -41,7 +41,7 @@
<HomePointForTeam>3</HomePointForTeam> <HomePointForTeam>3</HomePointForTeam>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="0.200000003" R="0"/> <Color A="1" B="1" G="0.200000003" R="0"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -61,7 +61,7 @@
<CapturePointNumber>1</CapturePointNumber> <CapturePointNumber>1</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="1" G="1" R="0"/> <Color A="1" B="1" G="1" R="0"/>
</c:Model> </c:Model>
<c:Team/> <c:Team/>
@@ -79,7 +79,7 @@
<CapturePointNumber>2</CapturePointNumber> <CapturePointNumber>2</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
</c:Model> </c:Model>
<c:Team/> <c:Team/>
<c:Transform> <c:Transform>
@@ -96,7 +96,7 @@
<CapturePointNumber>3</CapturePointNumber> <CapturePointNumber>3</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="1" R="1"/> <Color A="1" B="0" G="1" R="1"/>
</c:Model> </c:Model>
<c:Team/> <c:Team/>
@@ -115,7 +115,7 @@
<CapturePointNumber>4</CapturePointNumber> <CapturePointNumber>4</CapturePointNumber>
</c:CapturePoint> </c:CapturePoint>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitSphere.obj</Resource> <Resource>../assets/Models/Core/UnitSphere.mesh</Resource>
<Color A="1" B="0" G="0.200000003" R="1"/> <Color A="1" B="0" G="0.200000003" R="1"/>
</c:Model> </c:Model>
<c:Team> <c:Team>
@@ -133,7 +133,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0.482352942" G="0.490196079" R="1"/> <Color A="1" B="0.482352942" G="0.490196079" R="1"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -151,7 +151,7 @@
<c:Health/> <c:Health/>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0.482352942" G="0.490196079" R="1"/> <Color A="1" B="0.482352942" G="0.490196079" R="1"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -171,7 +171,7 @@
</c:Health> </c:Health>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0" G="0" R="2.25"/> <Color A="1" B="0" G="0" R="2.25"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
@@ -191,7 +191,7 @@
</c:Health> </c:Health>
<c:AABB/> <c:AABB/>
<c:Model> <c:Model>
<Resource>../assets/Models/Core/UnitCube.obj</Resource> <Resource>../assets/Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="0" G="0" R="4.5"/> <Color A="1" B="0" G="0" R="4.5"/>
</c:Model> </c:Model>
<c:Player/> <c:Player/>
+1 -1
View File
@@ -12,7 +12,7 @@
<FilePath></FilePath> <FilePath></FilePath>
</c:SoundEmitter> </c:SoundEmitter>
<c:Model> <c:Model>
<Resource>Models/Core/UnitCube.obj</Resource> <Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="1" B="1" G="0.58431375" R="0.43921569"/> <Color A="1" B="1" G="0.58431375" R="0.43921569"/>
</c:Model> </c:Model>
<c:Transform/> <c:Transform/>
+2 -2
View File
@@ -24,7 +24,7 @@
<Components> <Components>
<c:SpawnPoint/> <c:SpawnPoint/>
<c:Model> <c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource> <Resource>Models/Core/UnitSphere.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="1.26689196"/> <Position X="0" Y="0" Z="1.26689196"/>
@@ -37,7 +37,7 @@
<Components> <Components>
<c:SpawnPoint/> <c:SpawnPoint/>
<c:Model> <c:Model>
<Resource>Models/Core/UnitSphere.obj</Resource> <Resource>Models/Core/UnitSphere.mesh</Resource>
</c:Model> </c:Model>
<c:Transform> <c:Transform>
<Position X="0" Y="0" Z="-1.14786315"/> <Position X="0" Y="0" Z="-1.14786315"/>
+2 -2
View File
@@ -6,7 +6,7 @@
<Orientation X="0" Y="0" Z="0"/> <Orientation X="0" Y="0" Z="0"/>
</c:Transform> </c:Transform>
<c:Model> <c:Model>
<Resource>Models/DummyScene.obj</Resource> <Resource>Models/DummyScene.mesh</Resource>
</c:Model> </c:Model>
</Components> </Components>
<Children> <Children>
@@ -19,7 +19,7 @@
<c:Camera> <c:Camera>
</c:Camera> </c:Camera>
<c:Model> <c:Model>
<Resource>Models/Camera.obj</Resource> <Resource>Models/Camera.mesh</Resource>
</c:Model> </c:Model>
</Components> </Components>
</Entity> </Entity>
+3 -8
View File
@@ -9,18 +9,14 @@ layout(location = 1) in vec3 Normal;
layout(location = 2) in vec3 Tangent; layout(location = 2) in vec3 Tangent;
layout(location = 3) in vec3 BiTangent; layout(location = 3) in vec3 BiTangent;
layout(location = 4) in vec2 TextureCoords; layout(location = 4) in vec2 TextureCoords;
layout(location = 5) in vec4 DiffuseVertexColor; layout(location = 5) in vec4 BoneIndices;
layout(location = 6) in vec4 SpecularVertexColor; layout(location = 6) in vec4 BoneWeights;
layout(location = 7) in vec4 BoneIndices1;
layout(location = 8) in vec4 BoneIndices2;
layout(location = 9) in vec4 BoneWeights1;
layout(location = 10) in vec4 BoneWeights2;
out VertexData{ out VertexData{
vec3 Position; vec3 Position;
vec3 Normal; vec3 Normal;
vec2 TextureCoordinate; vec2 TextureCoordinate;
vec4 DiffuseColor;
}Output; }Output;
void main() void main()
@@ -30,5 +26,4 @@ void main()
Output.Position = Position; Output.Position = Position;
Output.TextureCoordinate = TextureCoords; Output.TextureCoordinate = TextureCoords;
Output.Normal = Normal; Output.Normal = Normal;
Output.DiffuseColor = DiffuseVertexColor;
} }
+2 -2
View File
@@ -4,6 +4,7 @@ uniform mat4 M;
uniform mat4 V; uniform mat4 V;
uniform mat4 P; uniform mat4 P;
uniform vec4 Color; uniform vec4 Color;
uniform vec4 DiffuseColor;
uniform vec2 ScreenDimensions; uniform vec2 ScreenDimensions;
layout (binding = 0) uniform sampler2D DiffuseTexture; layout (binding = 0) uniform sampler2D DiffuseTexture;
layout (binding = 1) uniform sampler2D GlowMap; layout (binding = 1) uniform sampler2D GlowMap;
@@ -46,7 +47,6 @@ in VertexData{
vec3 Position; vec3 Position;
vec3 Normal; vec3 Normal;
vec2 TextureCoordinate; vec2 TextureCoordinate;
vec4 DiffuseColor;
}Input; }Input;
out vec4 sceneColor; out vec4 sceneColor;
@@ -135,7 +135,7 @@ void main()
} }
//sceneColor += Input.DiffuseColor; //sceneColor += Input.DiffuseColor;
vec4 color_result = Input.DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color; vec4 color_result = DiffuseColor * (totalLighting.Diffuse + totalLighting.Specular) * diffuseTexel * Color;
//bloomColor = vec4(0.3, 0.8, 0.6, 1.0); //bloomColor = vec4(0.3, 0.8, 0.6, 1.0);
sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1)); sceneColor = vec4(color_result.xyz, clamp(color_result.a, 0, 1));
//These if statements should be removed if they are slow. //These if statements should be removed if they are slow.
+15 -10
View File
@@ -3,32 +3,37 @@
uniform mat4 M; uniform mat4 M;
uniform mat4 V; uniform mat4 V;
uniform mat4 P; uniform mat4 P;
uniform mat4 Bones[100];
layout(location = 0) in vec3 Position; layout(location = 0) in vec3 Position;
layout(location = 1) in vec3 Normal; layout(location = 1) in vec3 Normal;
layout(location = 2) in vec3 Tangent; layout(location = 2) in vec3 Tangent;
layout(location = 3) in vec3 BiTangent; layout(location = 3) in vec3 BiTangent;
layout(location = 4) in vec2 TextureCoords; layout(location = 4) in vec2 TextureCoords;
layout(location = 5) in vec4 DiffuseVertexColor; layout(location = 5) in vec4 BoneIndices;
layout(location = 6) in vec4 SpecularVertexColor; layout(location = 6) in vec4 BoneWeights;
layout(location = 7) in vec4 BoneIndices1;
layout(location = 8) in vec4 BoneIndices2;
layout(location = 9) in vec4 BoneWeights1;
layout(location = 10) in vec4 BoneWeights2;
out VertexData{ out VertexData{
vec3 Position; vec3 Position;
vec3 Normal; vec3 Normal;
vec2 TextureCoordinate; vec2 TextureCoordinate;
vec4 DiffuseColor;
}Output; }Output;
void main() void main()
{ {
gl_Position = P*V*M * vec4(Position, 1.0);
Output.Position = Position;
mat4 boneTransform = mat4(1);
if(BoneWeights[0] > 0.0f){
boneTransform = BoneWeights[0] * Bones[int(BoneIndices[0])]
+ BoneWeights[1] * Bones[int(BoneIndices[1])]
+ BoneWeights[2] * Bones[int(BoneIndices[2])]
+ BoneWeights[3] * Bones[int(BoneIndices[3])];
}
gl_Position = P*V*M*boneTransform * vec4(Position, 1.0);
Output.Position = (boneTransform * vec4(Position, 1.0)).xyz;
Output.TextureCoordinate = TextureCoords; Output.TextureCoordinate = TextureCoords;
Output.Normal = vec3(M * vec4(Normal, 0.0)); Output.Normal = vec3(M * vec4(Normal, 0.0));
Output.DiffuseColor = DiffuseVertexColor;
} }
+12
View File
@@ -36,6 +36,18 @@ EntityWrapper EntityWrapper::FirstChildByName(const std::string& name)
return EntityWrapper::Invalid; return EntityWrapper::Invalid;
} }
EntityWrapper EntityWrapper::FirstParentWithComponent(const std::string& componentType)
{
EntityWrapper entity = *this;
while (entity.Parent().Valid()) {
entity = entity.Parent();
if (entity.HasComponent(componentType)) {
return entity;
}
}
return EntityWrapper::Invalid;
}
bool EntityWrapper::IsChildOf(EntityWrapper potentialParent) bool EntityWrapper::IsChildOf(EntityWrapper potentialParent)
{ {
EntityWrapper entity = *this; EntityWrapper entity = *this;
+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);
}
+1 -1
View File
@@ -39,7 +39,7 @@ void EditorRenderSystem::Update(double dt)
continue; continue;
} catch (const std::exception&) { } catch (const std::exception&) {
try { try {
model = ResourceManager::Load<::Model>("Models/Core/Error.obj"); model = ResourceManager::Load<::Model>("Models/Core/Error.mesh");
} catch (const std::exception&) { } catch (const std::exception&) {
continue; continue;
} }
+136 -71
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;
} }
@@ -122,26 +130,49 @@ void Client::parsePing()
LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime); LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime);
m_StartPingTime = std::clock(); m_StartPingTime = std::clock();
Packet packet(MessageType::Ping, m_SendPacketID); Packet packet(MessageType::Ping, m_SendPacketID, m_PacketID, ackBitField);
packet.WriteString("Ping recieved"); packet.WriteString("Ping recieved");
send(packet); send(packet);
} }
void Client::parseKick() 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);
}
} }
} }
} }
@@ -276,7 +294,7 @@ void Client::send(Packet& packet)
void Client::connect() void Client::connect()
{ {
Packet packet(MessageType::Connect, m_SendPacketID); Packet packet(MessageType::Connect, m_SendPacketID, m_PacketID, ackBitField);
packet.WriteString(m_PlayerName); packet.WriteString(m_PlayerName);
m_StartPingTime = std::clock(); m_StartPingTime = std::clock();
send(packet); send(packet);
@@ -286,7 +304,7 @@ void Client::disconnect()
{ {
m_PreviousPacketID = 0; m_PreviousPacketID = 0;
m_PacketID = 0; m_PacketID = 0;
Packet packet(MessageType::Disconnect, m_SendPacketID); Packet packet(MessageType::Disconnect, m_SendPacketID, m_PacketID, ackBitField);
send(packet); send(packet);
} }
@@ -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, m_PacketID, ackBitField);
packet.WritePrimitive(e.DamageAmount); packet.WritePrimitive(e.Damage);
packet.WritePrimitive(e.PlayerDamagedID); packet.WritePrimitive(e.Player.ID);
send(packet); send(packet);
return false; return false;
} }
bool Client::OnPlayerSpawned(const Events::PlayerSpawned& e)
{
if (e.PlayerID == -1) {
m_LocalPlayer = e.Player;
}
return true;
}
void Client::sendLocalPlayerTransform()
{
if (!m_LocalPlayer.Valid()) {
return;
}
ComponentWrapper cTransform = m_LocalPlayer["Transform"];
glm::vec3& position = cTransform["Position"];
glm::vec3& orientation = cTransform["Orientation"];
Packet packet(MessageType::PlayerTransform, m_SendPacketID, m_PacketID, ackBitField);
packet.WritePrimitive(position.x);
packet.WritePrimitive(position.y);
packet.WritePrimitive(position.z);
packet.WritePrimitive(orientation.x);
packet.WritePrimitive(orientation.y);
packet.WritePrimitive(orientation.z);
send(packet);
}
void Client::identifyPacketLoss() void Client::identifyPacketLoss()
{ {
// if no packets lost, difference should be equal to 1 // if no packets lost, difference should be equal to 1
@@ -360,7 +405,7 @@ EntityID Client::createPlayer()
EntityID entityID = m_World->CreateEntity(); EntityID entityID = m_World->CreateEntity();
ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform"); ComponentWrapper transform = m_World->AttachComponent(entityID, "Transform");
ComponentWrapper model = m_World->AttachComponent(entityID, "Model"); ComponentWrapper model = m_World->AttachComponent(entityID, "Model");
model["Resource"] = "Models/Core/UnitSphere.obj"; model["Resource"] = "Models/Core/UnitSphere.mesh";
ComponentWrapper player = m_World->AttachComponent(entityID, "Player"); ComponentWrapper player = m_World->AttachComponent(entityID, "Player");
return entityID; return entityID;
} }
@@ -368,7 +413,7 @@ EntityID Client::createPlayer()
void Client::sendInputCommands() void Client::sendInputCommands()
{ {
if (m_InputCommandBuffer.size() > 0) { if (m_InputCommandBuffer.size() > 0) {
Packet packet(MessageType::OnInputCommand, m_SendPacketID); Packet packet(MessageType::OnInputCommand, m_SendPacketID, m_PacketID, ackBitField);
for (int i = 0; i < m_InputCommandBuffer.size(); i++) { for (int i = 0; i < m_InputCommandBuffer.size(); i++) {
packet.WriteString(m_InputCommandBuffer[i].Command); packet.WriteString(m_InputCommandBuffer[i].Command);
packet.WritePrimitive(m_InputCommandBuffer[i].Value); packet.WritePrimitive(m_InputCommandBuffer[i].Value);
@@ -380,18 +425,32 @@ void Client::sendInputCommands()
void Client::becomePlayer() void Client::becomePlayer()
{ {
Packet packet = Packet(MessageType::BecomePlayer, m_SendPacketID); Packet packet(MessageType::BecomePlayer, m_SendPacketID, m_PacketID, ackBitField);
send(packet); send(packet);
} }
bool Client::clientServerMapsHasEntity(EntityID clientEntityID) bool Client::clientServerMapsHasEntity(EntityID clientEntityID)
{ {
return m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end(); if (m_ClientIDToServerID.find(clientEntityID) != m_ClientIDToServerID.end()) {
if (m_World->ValidEntity(clientEntityID)) {
return true;
}
EntityID serverEntityID = m_ClientIDToServerID.at(clientEntityID);
deleteFromServerClientMaps(serverEntityID, clientEntityID);
}
return false;
} }
bool Client::serverClientMapsHasEntity(EntityID serverEntityID) bool Client::serverClientMapsHasEntity(EntityID serverEntityID)
{ {
return m_ServerIDToClientID.find(serverEntityID) != m_ServerIDToClientID.end(); if (m_ServerIDToClientID.find(serverEntityID) != m_ServerIDToClientID.end()) {
EntityID localEntityID = m_ServerIDToClientID.at(serverEntityID);
if (m_World->ValidEntity(localEntityID)) {
return true;
}
deleteFromServerClientMaps(serverEntityID, localEntityID);
}
return false;
} }
void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID) void Client::insertIntoServerClientMaps(EntityID serverEntityID, EntityID clientEntityID)
@@ -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);
}
+28 -9
View File
@@ -1,9 +1,9 @@
#include "Network/Packet.h" #include "Network/Packet.h"
Packet::Packet(MessageType type, unsigned int& packetID) Packet::Packet(MessageType type, unsigned int& packetID, unsigned int lastReceivedPacket, unsigned int ackBitField)
{ {
m_Data = new char[m_MaxPacketSize]; m_Data = new char[m_MaxPacketSize];
Init(type, packetID); Init(type, packetID, lastReceivedPacket, ackBitField);
} }
// Create message // Create message
@@ -21,7 +21,9 @@ Packet::Packet(MessageType type)
{ {
m_Data = new char[m_MaxPacketSize]; m_Data = new char[m_MaxPacketSize];
unsigned int dummy = 0; unsigned int dummy = 0;
Init(type, dummy); // Dummy allocates memory for later insertion of
// correct values
Init(type, dummy, dummy, dummy);
} }
Packet::~Packet() Packet::~Packet()
@@ -29,15 +31,17 @@ Packet::~Packet()
delete[] m_Data; delete[] m_Data;
} }
void Packet::Init(MessageType type, unsigned int & packetID) void Packet::Init(MessageType type, unsigned int & packetID, unsigned int lastReceivedPacket, unsigned int ackBitField)
{ {
m_ReturnDataOffset = 0; m_ReturnDataOffset = 0;
m_Offset = 0; m_Offset = 0;
// Create message header // Create message header
// Add message type // Add message type
int messageType = static_cast<int>(type); int messageType = static_cast<int>(type);
Packet::WritePrimitive<int>(messageType); WritePrimitive<int>(messageType);
Packet::WritePrimitive<int>(packetID); WritePrimitive<unsigned int>(packetID);
WritePrimitive<unsigned int>(lastReceivedPacket);
WritePrimitive<unsigned int>(ackBitField);
packetID++; packetID++;
m_HeaderSize = m_Offset; m_HeaderSize = m_Offset;
} }
@@ -87,16 +91,31 @@ char * Packet::ReadData(int SizeOfData)
return (m_Data + oldReturnDataOffset); return (m_Data + oldReturnDataOffset);
} }
void Packet::ChangePacketID(unsigned int & packetID) //void Packet::ChangePacketID(unsigned int & packetID)
//{
// packetID = packetID + 1;
// // Overwrite old PacketID
// memcpy(m_Data + sizeof(int), &packetID, sizeof(int));
//}
void Packet::ChangeHeaderInfo(unsigned int& packetID, unsigned int lastReceivedPacket, unsigned int ackBitField)
{ {
packetID = packetID + 1; packetID = packetID + 1;
// Start at sizeOf(int) cause of MessageType
int offset = sizeof(int);
// Overwrite old PacketID // Overwrite old PacketID
memcpy(m_Data + sizeof(int), &packetID, sizeof(int)); memcpy(m_Data + sizeof(unsigned int), &packetID, offset);
offset += sizeof(unsigned int);
// Overwrite old LastReceivedPacket
memcpy(m_Data + sizeof(unsigned int), &lastReceivedPacket, offset);
offset += sizeof(unsigned int);
// Overwrite old ackBitField
memcpy(m_Data + sizeof(unsigned int), &ackBitField, offset);
offset += sizeof(unsigned int);
} }
void Packet::resizeData() void Packet::resizeData()
{ {
// Allocate memory to store our data in // Allocate memory to store our data in
char* holdData = new char[m_MaxPacketSize]; char* holdData = new char[m_MaxPacketSize];
// Copy our data to the newly allocated memory // Copy our data to the newly allocated memory
+171 -155
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");
} }
@@ -33,6 +32,16 @@ void Server::Update()
m_EventBroker->Process<Server>(); m_EventBroker->Process<Server>();
if (isReadingData) { if (isReadingData) {
Network::Update(); Network::Update();
// Test bit patterns
//std::bitset<32> bitPattern;
//bitPattern[0].flip();
//bitPattern[15].flip();
//bitPattern[31].flip();
//std::cout << "bitPattern: " << bitPattern << '\n';
//unsigned int bitPatternInt = static_cast<unsigned int>(bitPattern.to_ulong());
//std::cout << "Int pattern: " << bitPatternInt << '\n';
//std::bitset<32> bitPatternRev(bitPatternInt);
//std::cout << "bitPatternReverted: " << bitPatternRev << '\n';
} }
} }
@@ -56,9 +65,9 @@ void Server::readFromClients()
} }
// Send pings each // Send pings each
if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { if (pingIntervalMs < (1000 * (currentTime - previousPingMessage) / (double)CLOCKS_PER_SEC)) {
sendPing(); sendPing();
previousePingMessage = currentTime; previousPingMessage = currentTime;
} }
// Time out logic // Time out logic
@@ -70,15 +79,19 @@ void Server::readFromClients()
void Server::parseMessageType(Packet& packet) void Server::parseMessageType(Packet& packet)
{ {
int messageType = packet.ReadPrimitive<int>(); // Read what type off message was sent from server PlayerID playerID = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
int messageType = packet.ReadPrimitive<int>(); // Read what type off message was sent from server
// Read packet ID // Read packet ID
m_PreviousPacketID = m_PacketID; // Set previous packet id if (playerID != -1) {
m_PacketID = packet.ReadPrimitive<int>(); //Read new packet id // TODO: Bit pattern stuff!"#!"#
m_ConnectedPlayers[playerID].LastPacketReceivedID = packet.ReadPrimitive<PacketID>();
}
//identifyPacketLoss(); //identifyPacketLoss();
switch (static_cast<MessageType>(messageType)) { switch (static_cast<MessageType>(messageType)) {
case MessageType::Connect: case MessageType::Connect:
parseConnect(packet); parseConnect(packet, playerID);
break; break;
case MessageType::Ping: case MessageType::Ping:
parsePing(); parsePing();
@@ -96,8 +109,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 +132,22 @@ int Server::receive(char * data)
return length; return length;
} }
void Server::send(Packet& packet, UserID user) void Server::send(PlayerID playerID, Packet& packet)
{ {
int bytesSent = m_Socket.send_to( try {
boost::asio::buffer(packet.Data(), packet.Size()), int bytesSent = m_Socket.send_to(
m_ConnectedUsers[user].Endpoint, boost::asio::buffer(packet.Data(), packet.Size()),
0); m_ConnectedPlayers[playerID].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) {
void Server::send(PlayerID player, Packet& packet) // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later
{ m_ConnectedPlayers[playerID].Endpoint = boost::asio::ip::udp::endpoint();
int bytesSent = m_Socket.send_to(
boost::asio::buffer(packet.Data(), packet.Size()),
m_PlayerDefinitions[player].Endpoint,
0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
m_NetworkData.AmountOfMessagesSent++;
} }
} }
@@ -164,58 +168,76 @@ 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.ChangeHeaderInfo(
packet.ChangePacketID(m_ConnectedUsers[i].PacketID); kv.second.PacketID,
send(packet, i); kv.second.LastPacketReceivedID,
} kv.second.AckBitField
);
send(kv.first, packet);
} }
} }
// Send snapshot fields // Send snapshot fields
void Server::sendSnapshot() void Server::sendSnapshot()
{ {
// Should time this Packet packet(MessageType::Snapshot);
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 +252,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,35 +264,24 @@ 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;
@@ -286,26 +297,19 @@ void Server::parseOnInputCommand(Packet& packet)
void Server::parseOnPlayerDamage(Packet & packet) void Server::parseOnPlayerDamage(Packet & packet)
{ {
Events::PlayerDamage e; Events::PlayerDamage e;
e.DamageAmount = packet.ReadPrimitive<double>(); e.Damage = packet.ReadPrimitive<double>();
e.PlayerDamagedID = packet.ReadPrimitive<EntityID>(); e.Player = EntityWrapper(m_World, packet.ReadPrimitive<EntityID>());
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
//LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str()); //LOG_DEBUG("Server::parseOnPlayerDamage: Command is %s. Value is %f. PlayerID is %i.", e.DamageAmount, e.PlayerDamagedID, e.TypeOfDamage.c_str());
} }
void Server::parseConnect(Packet& packet) void Server::parseConnect(Packet& packet, PlayerID playerID)
{ {
LOG_INFO("Parsing connections"); LOG_INFO("Parsing connections");
// Check if player is already connected // Check if player is already connected
if (GetPlayerIDFromEndpoint(m_ReceiverEndpoint) != -1) { if (playerID != -1) {
return; return;
} }
for (int i = 0; i < m_ConnectedUsers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address() &&
m_ConnectedUsers[i].Endpoint.port() == m_ReceiverEndpoint.port()) {
// Already connected
return;
}
}
// Create a new player // Create a new player
PlayerDefinition pd; PlayerDefinition pd;
pd.EntityID = 0; // Overlook this pd.EntityID = 0; // Overlook this
@@ -313,11 +317,11 @@ void Server::parseConnect(Packet& packet)
pd.Name = packet.ReadString(); pd.Name = packet.ReadString();
pd.PacketID = 0; pd.PacketID = 0;
pd.StopTime = std::clock(); pd.StopTime = std::clock();
m_ConnectedUsers.push_back(pd); Packet connnectPacket(MessageType::Connect, pd.PacketID, pd.LastPacketReceivedID, pd.AckBitField);
m_ConnectedPlayers[m_NextPlayerID++] = pd;
LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str()); LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str());
// Send a message to the player that connected // Send a message to the player that connected
Packet connnectPacket(MessageType::Connect, m_ConnectedUsers[m_ConnectedUsers.size() - 1].PacketID);
send(connnectPacket); send(connnectPacket);
// Send notification that a player has connected // Send notification that a player has connected
@@ -329,32 +333,36 @@ void Server::parseDisconnect()
{ {
LOG_INFO("%i: Parsing disconnect", m_PacketID); LOG_INFO("%i: Parsing disconnect", m_PacketID);
for (int i = 0; i < m_ConnectedUsers.size(); i++) { for (auto& kv : m_ConnectedPlayers) {
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) { if (kv.second.Endpoint.address() == m_ReceiverEndpoint.address() &&
disconnect(i); kv.second.Endpoint.port() == m_ReceiverEndpoint.port()) {
disconnect(kv.first);
break; break;
} }
} }
} }
void Server::parseClientPing() void Server::parseClientPing(PlayerID player)
{ {
LOG_INFO("%i: Parsing ping", m_PacketID);
PlayerID player = GetPlayerIDFromEndpoint(m_ReceiverEndpoint);
if (player == -1) { if (player == -1) {
return; return;
} }
// Return ping // Return ping
Packet packet(MessageType::Ping, m_PlayerDefinitions[player].PacketID); Packet packet(
MessageType::Ping,
m_ConnectedPlayers[player].PacketID,
m_ConnectedPlayers[player].LastPacketReceivedID,
m_ConnectedPlayers[player].AckBitField
);
packet.WriteString("Ping received"); packet.WriteString("Ping received");
send(packet); send(packet);
} }
void Server::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 +377,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.obj";
model["Color"] = glm::vec4(rand()%255 / 255.f, rand()%255 / 255.f, rand() %255 / 255.f, 1.f);
ComponentWrapper player = m_World->AttachComponent(entityID, "Player");
m_PlayerDefinitions[playerIndex].EntityID = entityID;
return;
}
}
LOG_WARNING("Server is full!");
}
void Server::kick(PlayerID player) void Server::kick(PlayerID player)
{ {
disconnect(player); disconnect(player);
@@ -415,10 +386,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 +414,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;
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ DrawBloomPass::DrawBloomPass(IRenderer* renderer)
{ {
m_Renderer = renderer; m_Renderer = renderer;
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj"); m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
InitializeTextures(); InitializeTextures();
InitializeBuffers(); InitializeBuffers();
@@ -4,8 +4,8 @@ DrawColorCorrectionPass::DrawColorCorrectionPass(IRenderer* renderer)
{ {
m_Renderer = renderer; m_Renderer = renderer;
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj"); m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
m_Exposure = 1; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting. m_Exposure = 0.4; //TODO: Renderer: Fixa så att denna går att ändra på genom komponent eller setting.
InitializeShaderPrograms(); InitializeShaderPrograms();
} }
+24 -9
View File
@@ -65,6 +65,7 @@ void DrawFinalPass::Draw(RenderScene& scene)
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); glUniform2f(glGetUniformLocation(shaderHandle, "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
//TODO: Render: Add code for more jobs than modeljobs. //TODO: Render: Add code for more jobs than modeljobs.
for (auto &job : scene.ForwardJobs) { for (auto &job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job); auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
@@ -72,6 +73,7 @@ void DrawFinalPass::Draw(RenderScene& scene)
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms //TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
glUniform4fv(glGetUniformLocation(shaderHandle, "DiffuseColor"), 1, glm::value_ptr(modelJob->DiffuseColor));
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
if(modelJob->DiffuseTexture != nullptr) { if(modelJob->DiffuseTexture != nullptr) {
@@ -80,22 +82,35 @@ void DrawFinalPass::Draw(RenderScene& scene)
glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture);
} }
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); if (modelJob->IncandescenceTexture != nullptr) {
glBindTexture(GL_TEXTURE_2D, modelJob->IncandescenceTexture->m_Texture);
/*if(modelJob->GlowMap != nullptr) {
glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture);
} else { } else {
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture); glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
}
/*if(modelJob->GlowMap != nullptr) {
glBindTexture(GL_TEXTURE_2D, modelJob->GlowMap->m_Texture);
} else {
glBindTexture(GL_TEXTURE_2D, m_BlackTexture->m_Texture);
}*/ }*/
//TODO: Fixa så att modelsJobs kan spela upp olika animationer och så att den kan få in en tid istället för 1.0f - Hälsningar Johan och Andreas :)
if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) {
auto animation = modelJob->Model->m_RawModel->m_Skeleton->GetAnimation("running");
if (animation != nullptr) {
std::vector<glm::mat4> frameBones = modelJob->Model->m_RawModel->m_Skeleton->GetFrameBones(
*animation,
0.0f
);
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0]));
}
}
glBindVertexArray(modelJob->Model->VAO); glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex); glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex * sizeof(unsigned int)));
continue;
} }
} }
m_FinalPassFrameBuffer.Unbind();
GLERROR("DrawFinalPass::Draw: END"); GLERROR("DrawFinalPass::Draw: END");
delete state; delete state;
} }
@@ -133,4 +148,4 @@ void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
GLERROR("MipMap Texture initialization failed"); GLERROR("MipMap Texture initialization failed");
} }
+1 -1
View File
@@ -4,7 +4,7 @@ DrawScreenQuadPass::DrawScreenQuadPass(IRenderer* renderer)
{ {
m_Renderer = renderer; m_Renderer = renderer;
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj"); m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh");
InitializeShaderPrograms(); InitializeShaderPrograms();
} }
+4 -9
View File
@@ -15,6 +15,9 @@ Model::Model(std::string fileName)
if (!group.SpecularMapPath.empty()) { if (!group.SpecularMapPath.empty()) {
group.SpecularMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.SpecularMapPath)); group.SpecularMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.SpecularMapPath));
} }
if (!group.IncandescenceMapPath.empty()) {
group.IncandescenceMap = std::shared_ptr<Texture>(ResourceManager::Load<Texture>(group.IncandescenceMapPath));
}
} }
// Generate GL buffers // Generate GL buffers
@@ -32,7 +35,7 @@ Model::Model(std::string fileName)
GLERROR("GLEW: BufferFail4"); GLERROR("GLEW: BufferFail4");
glBindBuffer(GL_ARRAY_BUFFER, buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer);
std::vector<int> structSizes = { 3, 3, 3, 3, 2, 4, 4, 4, 4, 4, 4 }; std::vector<int> structSizes = { 3, 3, 3, 3, 2, 4, 4 };
int stride = 0; int stride = 0;
for (int size : structSizes) { for (int size : structSizes) {
stride += size; stride += size;
@@ -48,10 +51,6 @@ Model::Model(std::string fileName)
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++; glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++; glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++; glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
glVertexAttribPointer(element, structSizes[element], GL_FLOAT, GL_FALSE, stride, (GLvoid*)(sizeof(GLfloat) * (offset += structSizes[element - 1]))); element++;
} }
GLERROR("GLEW: BufferFail5"); GLERROR("GLEW: BufferFail5");
@@ -62,10 +61,6 @@ Model::Model(std::string fileName)
glEnableVertexAttribArray(4); glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5); glEnableVertexAttribArray(5);
glEnableVertexAttribArray(6); glEnableVertexAttribArray(6);
glEnableVertexAttribArray(7);
glEnableVertexAttribArray(8);
glEnableVertexAttribArray(9);
glEnableVertexAttribArray(10);
GLERROR("GLEW: BufferFail5"); GLERROR("GLEW: BufferFail5");
//CreateBuffers(); //CreateBuffers();
@@ -1,6 +1,8 @@
#include "Rendering/RawModel.h" #include "Rendering/RawModelAssimp.h"
RawModel::RawModel(std::string fileName) #ifdef USING_ASSIMP_AS_IMPORTER
RawModelAssimp::RawModelAssimp(std::string fileName)
{ {
Assimp::Importer importer; Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(fileName, aiProcess_CalcTangentSpace | aiProcess_Triangulate); const aiScene* scene = importer.ReadFile(fileName, aiProcess_CalcTangentSpace | aiProcess_Triangulate);
@@ -38,7 +40,7 @@ RawModel::RawModel(std::string fileName)
//LOG_DEBUG("Index count %i", numIndices); //LOG_DEBUG("Index count %i", numIndices);
//LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures); //LOG_DEBUG("Model has %i embedded textures", scene->mNumTextures);
std::vector<std::tuple<std::string, glm::mat4>> boneInfo; std::vector<std::tuple<std::string, glm::mat4>> boneInfo;
std::map<std::string, int> boneNameMapping; std::map<std::string, int> boneNameMapping;
@@ -74,21 +76,7 @@ RawModel::RawModel(std::string fileName)
auto uv = mesh->mTextureCoords[0][vertexIndex]; auto uv = mesh->mTextureCoords[0][vertexIndex];
desc.TextureCoords = glm::vec2(uv.x, uv.y); desc.TextureCoords = glm::vec2(uv.x, uv.y);
} }
// Material diffuse color
aiColor3D diffuse;
material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
float opacity;
material->Get(AI_MATKEY_OPACITY, opacity);
desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity);
desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity);
// Material specular color
aiColor3D specular;
material->Get(AI_MATKEY_COLOR_SPECULAR, specular);
desc.SpecularVertexColor = glm::vec4(specular.r, specular.g, specular.b, 1.f);
m_Vertices.push_back(desc); m_Vertices.push_back(desc);
} }
@@ -128,7 +116,7 @@ RawModel::RawModel(std::string fileName)
} }
for (auto& vertex : m_Vertices) { for (auto& vertex : m_Vertices) {
vertex.Tangent = glm::normalize(vertex.Tangent); vertex.Tangent = glm::normalize(vertex.Tangent);
vertex.BiTangent = glm::normalize(glm::cross(vertex.Tangent, glm::normalize(vertex.Normal))); vertex.BiNormal = glm::normalize(glm::cross(vertex.Tangent, glm::normalize(vertex.Normal)));
} }
// Material info // Material info
@@ -201,10 +189,7 @@ RawModel::RawModel(std::string fileName)
LOG_WARNING("Vertex weights (%i) greater than max weights per vertex (%i)", weights.size(), maxWeights); LOG_WARNING("Vertex weights (%i) greater than max weights per vertex (%i)", weights.size(), maxWeights);
} }
for (int weightIndex = 0; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 4; ++weightIndex) { for (int weightIndex = 0; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 4; ++weightIndex) {
std::tie(desc.BoneIndices1[weightIndex], desc.BoneWeights1[weightIndex]) = weights[weightIndex]; std::tie(desc.BoneIndices[weightIndex], desc.BoneWeights[weightIndex]) = weights[weightIndex];
}
for (int weightIndex = 4; weightIndex < weights.size() && weightIndex < maxWeights && weightIndex < 8; ++weightIndex) {
std::tie(desc.BoneIndices2[weightIndex - 4], desc.BoneWeights2[weightIndex - 4]) = weights[weightIndex];
} }
} }
@@ -290,14 +275,14 @@ RawModel::RawModel(std::string fileName)
} }
} }
RawModel::~RawModel() RawModelAssimp::~RawModelAssimp()
{ {
if (m_Skeleton) { if (m_Skeleton) {
delete m_Skeleton; delete m_Skeleton;
} }
} }
void RawModel::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID) void RawModelAssimp::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &boneInfo, std::map<std::string, int> &boneNameMapping, aiNode* node, int parentID)
{ {
std::string nodeName = node->mName.C_Str(); std::string nodeName = node->mName.C_Str();
@@ -317,3 +302,5 @@ void RawModel::CreateSkeleton(std::vector<std::tuple<std::string, glm::mat4>> &b
CreateSkeleton(boneInfo, boneNameMapping, child, parentID); CreateSkeleton(boneInfo, boneNameMapping, child, parentID);
} }
} }
#endif
+381
View File
@@ -0,0 +1,381 @@
#include "Rendering/RawModelCustom.h"
#ifndef USING_ASSIMP_AS_IMPORTER
RawModelCustom::RawModelCustom(std::string fileName)
{
if(fileName.substr(fileName.find_last_of(".")).compare(".mesh") != 0) {
throw Resource::FailedLoadingException("Unknown model file format. Please use \".mesh\" files.");
}
fileName = fileName.erase(fileName.find_last_of("."), fileName.find_last_of(".") - fileName.size());
ReadMeshFile(fileName);
ReadMaterialFile(fileName);
ReadAnimationFile(fileName);
}
void RawModelCustom::ReadMeshFile(std::string filePath)
{
char* fileData;
filePath += ".mesh";
std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate);
if (!in.is_open()) {
throw Resource::FailedLoadingException("Open mesh file failed");
}
unsigned int fileByteSize = in.tellg();
in.seekg(0, std::ios_base::beg);
fileData = new char[fileByteSize];
in.read(fileData, fileByteSize);
in.close();
unsigned int offset = 0;
if (fileByteSize > 0) {
ReadMeshFileHeader(offset, fileData, fileByteSize);
ReadMesh(offset, fileData, fileByteSize);
}
delete fileData;
}
void RawModelCustom::ReadMeshFileHeader(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
{
#ifdef BOOST_LITTLE_ENDIAN
m_Vertices.resize(*(unsigned int*)(fileData + offset));
offset += sizeof(unsigned int);
m_Indices.resize(*(unsigned int*)(fileData + offset));
offset += sizeof(unsigned int);
#else
#endif
}
void RawModelCustom::ReadMesh(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
{
ReadVertices(offset, fileData, fileByteSize);
ReadIndices(offset, fileData, fileByteSize);
}
void RawModelCustom::ReadVertices(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
{
#ifdef BOOST_LITTLE_ENDIAN
if (offset + m_Vertices.size() * sizeof(Vertex) > fileByteSize) {
throw Resource::FailedLoadingException("Reading vertices failed");
}
memcpy(&m_Vertices[0], fileData + offset, m_Vertices.size() * sizeof(Vertex));
offset += m_Vertices.size() * sizeof(Vertex);
#else
#endif
}
void RawModelCustom::ReadIndices(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
{
#ifdef BOOST_LITTLE_ENDIAN
if (offset + m_Indices.size() * sizeof(unsigned int) > fileByteSize) {
throw Resource::FailedLoadingException("Reading indices failed");
}
memcpy(&m_Indices[0], fileData + offset, m_Indices.size() * sizeof(unsigned int));
offset += m_Indices.size() * sizeof(unsigned int);
#else
#endif
}
void RawModelCustom::ReadMaterialFile(std::string filePath)
{
char* fileData;
filePath += ".mtrl";
std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate);
if (!in.is_open()) {
throw Resource::FailedLoadingException("Open material file failed");
}
unsigned int fileByteSize = in.tellg();
in.seekg(0, std::ios_base::beg);
fileData = new char[fileByteSize];
in.read(fileData, fileByteSize);
in.close();
unsigned int offset = 0;
if (fileByteSize > 0) {
ReadMaterials(offset, fileData, fileByteSize);
}
delete fileData;
}
void RawModelCustom::ReadMaterials(unsigned int& offset, char* fileData, unsigned int& fileByteSize)
{
#ifdef BOOST_LITTLE_ENDIAN
unsigned int* numMaterials = (unsigned int*)(fileData);
MaterialGroups.reserve(*numMaterials);
offset += sizeof(unsigned int);
for (int i = 0; i < *numMaterials; i++) {
ReadMaterialSingle(offset, fileData, fileByteSize);
}
#else
#endif
}
void RawModelCustom::ReadMaterialSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize)
{
MaterialGroup newMaterial;
#ifdef BOOST_LITTLE_ENDIAN
if (offset + sizeof(unsigned int) * 4 > fileByteSize) {
throw Resource::FailedLoadingException("Reading Material texture names length failed");
}
unsigned int* nameLengths = (unsigned int*)(fileData + offset);
offset += sizeof(unsigned int) * 4;
if (offset + sizeof(float) * 11 + sizeof(unsigned int) * 2 > fileByteSize) {
throw Resource::FailedLoadingException("Reading Material specular, reflection, color and start and end index values failed");
}
newMaterial.SpecularExponent = *(float*)(fileData + offset);
offset += sizeof(float);
newMaterial.ReflectionFactor = *(float*)(fileData + offset);
offset += sizeof(float);
memcpy(&newMaterial.DiffuseColor[0], fileData + offset, sizeof(float) * 3);
offset += sizeof(float) * 3;
memcpy(&newMaterial.SpecularColor[0], fileData + offset, sizeof(float) * 3);
offset += sizeof(float) * 3;
memcpy(&newMaterial.IncandescenceColor[0], fileData + offset, sizeof(float) * 3);
offset += sizeof(float) * 3;
newMaterial.StartIndex = *(unsigned int*)(fileData + offset);
offset += sizeof(unsigned int);
newMaterial.EndIndex = *(unsigned int*)(fileData + offset);
offset += sizeof(unsigned int);
if (nameLengths[0] > 0) {
if (offset + nameLengths[0] > fileByteSize) {
throw Resource::FailedLoadingException("Reading Material texture path failed");
}
newMaterial.TexturePath = "Textures/";
newMaterial.TexturePath += (fileData + offset);
newMaterial.TexturePath += ".png";
offset += nameLengths[0];
}
if (nameLengths[1] > 0) {
if (offset + nameLengths[1] > fileByteSize) {
throw Resource::FailedLoadingException("Reading Material NormalMap path failed");
}
newMaterial.NormalMapPath = "Textures/";
newMaterial.NormalMapPath += (fileData + offset);
newMaterial.NormalMapPath += ".png";
offset += nameLengths[1];
}
if (nameLengths[2] > 0) {
if (offset + nameLengths[2] > fileByteSize) {
throw Resource::FailedLoadingException("Reading Material SpecularMap path failed");
}
newMaterial.SpecularMapPath = "Textures/";
newMaterial.SpecularMapPath += (fileData + offset);
newMaterial.SpecularMapPath += ".png";
offset += nameLengths[2];
}
if (nameLengths[3] > 0) {
if (offset + nameLengths[3] > fileByteSize) {
throw Resource::FailedLoadingException("Reading Material IncandescenceMap path failed");
}
newMaterial.IncandescenceMapPath = "Textures/";
newMaterial.IncandescenceMapPath += (fileData + offset);
newMaterial.IncandescenceMapPath += ".png";
offset += nameLengths[3];
}
#else
#endif
MaterialGroups.push_back(newMaterial);
}
void RawModelCustom::ReadAnimationFile(std::string filePath)
{
char* fileData;
filePath += ".anim";
std::ifstream in(filePath.c_str(), std::ios_base::binary | std::ios_base::ate);
if (!in.is_open()) {
//throw Resource::FailedLoadingException("Open animation file failed");
return;
}
unsigned int fileByteSize = in.tellg();
in.seekg(0, std::ios_base::beg);
fileData = new char[fileByteSize];
in.read(fileData, fileByteSize);
in.close();
unsigned int offset = 0;
if (fileByteSize > 0) {
m_Skeleton = new Skeleton();
#ifdef BOOST_LITTLE_ENDIAN
unsigned int numBindPoses = *(unsigned int*)(fileData);
offset += sizeof(unsigned int);
unsigned int numAnimations = *(unsigned int*)(fileData + offset);
offset += sizeof(unsigned int);
#else
#endif
ReadAnimationBindPoses(offset, fileData, fileByteSize);
ReadAnimationClips(offset, fileData, fileByteSize, numAnimations);
}
delete fileData;
}
void RawModelCustom::ReadAnimationBindPoses(unsigned int &offset, char* fileData, unsigned int& fileByteSize)
{
#ifdef BOOST_LITTLE_ENDIAN
unsigned int* numBones = (unsigned int*)(fileData + offset);
offset += sizeof(unsigned int);
for (unsigned int i = 0; i < *numBones; i++) {
ReadAnimationJoint(offset, fileData, fileByteSize);
}
#else
#endif
}
void RawModelCustom::ReadAnimationJoint(unsigned int &offset, char* fileData, unsigned int& fileByteSize)
{
#ifdef BOOST_LITTLE_ENDIAN
if (offset + sizeof(unsigned int) > fileByteSize) {
throw Resource::FailedLoadingException("Reading Joint name length failed");
}
unsigned int jointNameLength = *(unsigned int*)(fileData + offset);
offset += sizeof(unsigned int);
if (offset + jointNameLength > fileByteSize) {
throw Resource::FailedLoadingException("Reading Joint name failed");
}
std::string jointName = (fileData + offset);
offset += jointNameLength;
if (offset + sizeof(float) * 4 * 4 > fileByteSize) {
throw Resource::FailedLoadingException("Reading Joint offset matrix failed");
}
glm::mat4 offsetMatrix;
memcpy(&offsetMatrix, fileData + offset, sizeof(float) * 4 * 4);
offset += sizeof(float) * 4 * 4;
if (offset + sizeof(int) > fileByteSize) {
throw Resource::FailedLoadingException("Reading Joint ID failed");
}
int jointID = *(int*)(fileData + offset);
offset += sizeof(int);
if (offset + sizeof(int) > fileByteSize) {
throw Resource::FailedLoadingException("Reading Joint Parent ID failed");
}
int jointParentID = *(int*)(fileData + offset);
offset += sizeof(int);
// Adding joint to the Skeleton
m_Skeleton->CreateBone(jointID, jointParentID, jointName, offsetMatrix);
#else
#endif
}
void RawModelCustom::ReadAnimationClips(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int numberOfClips)
{
for (unsigned int i = 0; i < numberOfClips; i++) {
ReadAnimationClipSingle(offset, fileData, fileByteSize, i);
}
}
void RawModelCustom::ReadAnimationClipSingle(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int clipIndex)
{
#ifdef BOOST_LITTLE_ENDIAN
Skeleton::Animation newAnimation;
if (offset + sizeof(unsigned int) > fileByteSize) {
throw Resource::FailedLoadingException("Reading AnimationClip name length failed");
}
unsigned int clipNameLength = *(unsigned int*)(fileData + offset);
offset += sizeof(unsigned int);
if (offset + clipNameLength > fileByteSize) {
throw Resource::FailedLoadingException("Reading AnimationClip name failed");
}
newAnimation.Name = (fileData + offset);
offset += clipNameLength;
if (offset + sizeof(float) > fileByteSize) {
throw Resource::FailedLoadingException("Reading AnimationClip duration failed");
}
newAnimation.Duration = *(float*)(fileData + offset);
offset += sizeof(float);
if (offset + sizeof(unsigned int) > fileByteSize) {
throw Resource::FailedLoadingException("Reading AnimationClip NrOfKeyframes failed");
}
unsigned int nrOfKeyframes = *(unsigned int*)(fileData + offset);
offset += sizeof(unsigned int);
if (offset + sizeof(unsigned int) > fileByteSize) {
throw Resource::FailedLoadingException("Reading AnimationClip NrOfJoints failed");
}
unsigned int nrOfJoints = *(unsigned int*)(fileData + offset);
offset += sizeof(unsigned int);
newAnimation.Keyframes.reserve(nrOfKeyframes);
for (unsigned int i = 0; i < nrOfKeyframes; i++) {
ReadAnimationKeyFrame(offset, fileData, fileByteSize, nrOfJoints, newAnimation);
}
m_Skeleton->Animations[newAnimation.Name] = newAnimation;
#else
#endif
}
void RawModelCustom::ReadAnimationKeyFrame(unsigned int &offset, char* fileData, unsigned int& fileByteSize, unsigned int nrOfJoints, Skeleton::Animation& animation)
{
Skeleton::Animation::Keyframe newKeyFrame;
if (offset + sizeof(int) > fileByteSize) {
throw Resource::FailedLoadingException("Reading AnimationKeyFrame index failed");
}
newKeyFrame.Index = *(int*)(fileData + offset);
offset += sizeof(int);
if (offset + sizeof(float) > fileByteSize) {
throw Resource::FailedLoadingException("Reading AnimationKeyFrame time failed");
}
newKeyFrame.Time = *(float*)(fileData + offset);
offset += sizeof(float);
if (offset + sizeof(Skeleton::Animation::Keyframe::BoneProperty) * nrOfJoints> fileByteSize) {
throw Resource::FailedLoadingException("Reading AnimationKeyFrame joints failed");
}
Skeleton::Animation::Keyframe::BoneProperty newBone;
for (unsigned int i = 0; i < nrOfJoints; i++) {
memcpy(&newBone, (fileData + offset), sizeof(Skeleton::Animation::Keyframe::BoneProperty));
offset += sizeof(Skeleton::Animation::Keyframe::BoneProperty);
newKeyFrame.BoneProperties[newBone.ID] = newBone;
}
animation.Keyframes.push_back(newKeyFrame);
}
RawModelCustom::~RawModelCustom()
{
if (m_Skeleton != nullptr) {
delete m_Skeleton;
}
}
#endif
+2 -2
View File
@@ -59,10 +59,10 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs)
model = ResourceManager::Load<::Model, true>(resource); model = ResourceManager::Load<::Model, true>(resource);
} catch (const Resource::StillLoadingException&) { } catch (const Resource::StillLoadingException&) {
//continue; //continue;
model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.obj"); model = ResourceManager::Load<::Model>("Models/Core/UnitRaptor.mesh");
} catch (const std::exception&) { } catch (const std::exception&) {
try { try {
model = ResourceManager::Load<::Model>("Models/Core/Error.obj"); model = ResourceManager::Load<::Model>("Models/Core/Error.mesh");
} catch (const std::exception&) { } catch (const std::exception&) {
continue; continue;
} }
+2 -2
View File
@@ -13,9 +13,9 @@ void Renderer::Initialize()
m_TextPass->Initialize(); m_TextPass->Initialize();
m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj"); /* m_ScreenQuad = ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj");
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj"); m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj"); m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");*/
m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker); m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker);
} }
+6 -2
View File
@@ -68,7 +68,7 @@ std::vector<glm::mat4> Skeleton::GetFrameBones(const Animation& animation, doubl
void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe &currentFrame, const Animation::Keyframe &nextFrame, float progress, std::map<int, glm::mat4> &boneMatrices, const Bone* bone, glm::mat4 parentMatrix) void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyframe &currentFrame, const Animation::Keyframe &nextFrame, float progress, std::map<int, glm::mat4> &boneMatrices, const Bone* bone, glm::mat4 parentMatrix)
{ {
glm::mat4 boneMatrix; glm::mat4 boneMatrix;
if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() || nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) { if (currentFrame.BoneProperties.find(bone->ID) != currentFrame.BoneProperties.end() || nextFrame.BoneProperties.find(bone->ID) != nextFrame.BoneProperties.end()) {
Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties.at(bone->ID); Animation::Keyframe::BoneProperty currentBoneProperty = currentFrame.BoneProperties.at(bone->ID);
@@ -84,10 +84,13 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf
positionInterp.z = 0; positionInterp.z = 0;
} }
boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp)); boneMatrix = parentMatrix * (glm::translate(positionInterp) * glm::toMat4(rotationInterp) * glm::scale(scaleInterp));
boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix; boneMatrices[bone->ID] = boneMatrix * bone->OffsetMatrix;
} else { } else {
boneMatrix = parentMatrix * bone->Parent->OffsetMatrix; // * glm::inverse(bone->OffsetMatrix); if (bone->Parent) {
boneMatrix = parentMatrix; // * glm::inverse(bone->OffsetMatrix);
}
boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix; boneMatrices[bone->ID] = boneMatrix; // * bone->OffsetMatrix;
} }
@@ -95,6 +98,7 @@ void Skeleton::AccumulateBoneTransforms(bool noRootMotion, const Animation::Keyf
std::string name = child->Name; std::string name = child->Name;
AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, progress, boneMatrices, child, boneMatrix); AccumulateBoneTransforms(noRootMotion, currentFrame, nextFrame, progress, boneMatrices, child, boneMatrix);
} }
} }
int Skeleton::GetBoneID(std::string name) int Skeleton::GetBoneID(std::string name)
+1 -1
View File
@@ -198,7 +198,7 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e)
(float&)(double)emitter["RollOffFactor"] = e.RollOffFactor; (float&)(double)emitter["RollOffFactor"] = e.RollOffFactor;
(float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance; (float&)(double)emitter["ReferenceDistance"] = e.ReferenceDistance;
auto model = m_World->AttachComponent(emitterID, "Model"); auto model = m_World->AttachComponent(emitterID, "Model");
(std::string&)model["Resource"] = "Models/Core/UnitCube.obj"; (std::string&)model["Resource"] = "Models/Core/UnitCube.mesh"; // 360NoScope UnitCube
source->Type = SoundType::SFX; source->Type = SoundType::SFX;
m_Sources[emitterID] = source; m_Sources[emitterID] = source;
playSound(source); playSound(source);
+2 -2
View File
@@ -57,7 +57,7 @@ Game::Game(int argc, char* argv[])
m_FrameStack->Height = m_Renderer->Resolution().Height; m_FrameStack->Height = m_Renderer->Resolution().Height;
// Create a world // Create a world
m_World = new World(); m_World = new World(m_EventBroker);
std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", ""); std::string mapToLoad = m_Config->Get<std::string>("Debug.LoadMap", "");
if (!mapToLoad.empty()) { if (!mapToLoad.empty()) {
auto file = ResourceManager::Load<EntityFile>(mapToLoad); auto file = ResourceManager::Load<EntityFile>(mapToLoad);
@@ -77,7 +77,7 @@ Game::Game(int argc, char* argv[])
// All systems with orderlevel 0 will be updated first. // All systems with orderlevel 0 will be updated first.
unsigned int updateOrderLevel = 0; unsigned int updateOrderLevel = 0;
m_SystemPipeline->AddSystem<RaptorCopterSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<RaptorCopterSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel); //m_SystemPipeline->AddSystem<HealthSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<PlayerMovementSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel); m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
+1 -2
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
@@ -49,7 +48,7 @@ void HealthSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& comp
bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e) bool HealthSystem::OnPlayerDamaged(const Events::PlayerDamage& e)
{ {
//save the changed HP to a vector. it will be taken care of in UpdateComponent //save the changed HP to a vector. it will be taken care of in UpdateComponent
m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerDamagedID, -e.DamageAmount)); //m_DeltaHealthVector.push_back(std::make_tuple(e.PlayerDamagedID, -e.DamageAmount));
return true; return true;
} }
+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) {
+56 -25
View File
@@ -5,49 +5,80 @@ WeaponSystem::WeaponSystem(World* world, EventBroker* eventBroker, IRenderer* re
, ImpureSystem() , ImpureSystem()
, m_Renderer(renderer) , m_Renderer(renderer)
{ {
EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &WeaponSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot); EVENT_SUBSCRIBE_MEMBER(m_EShoot, &WeaponSystem::OnShoot);
} }
void WeaponSystem::Update(double dt) void WeaponSystem::Update(double dt)
{ {
for (int i = m_EShootVector.size(); i > 0; i--)
{
//TODO: check if player has enough ammo and if weapon has a cooldown or not
//pick the object }
PickData pickDataFromShot = m_Renderer->Pick(std::get<1>(m_EShootVector[i - 1]));
if (pickDataFromShot.Entity == EntityID_Invalid) { bool WeaponSystem::OnPlayerSpawned(const Events::PlayerSpawned& e)
m_EShootVector.erase(m_EShootVector.begin() + i - 1); {
continue; if (e.PlayerID == -1) {
} m_LocalPlayer = e.Player;
//if its a player, do PlayerDamage event
const bool hasPlayerComponent = m_World->HasComponent(pickDataFromShot.Entity, "Player");
if (hasPlayerComponent) {
Events::PlayerDamage ePlayerDamage;
//TODO: damage based on weapontype/class?
//TODO: multiple shots at the same time? (shotgunner)
ePlayerDamage.DamageAmount = 25;
ePlayerDamage.PlayerDamagedID = pickDataFromShot.Entity;
m_EventBroker->Publish(ePlayerDamage);
}
m_EShootVector.erase(m_EShootVector.begin() + i - 1);
} }
return true;
} }
bool WeaponSystem::OnInputCommand(const Events::InputCommand& e) bool WeaponSystem::OnInputCommand(const Events::InputCommand& e)
{ {
// Only shoot client-side!
if (e.PlayerID != -1) {
return false;
}
// Only shoot if the player is alive
if (!m_LocalPlayer.Valid()) {
return false;
}
if (e.Command == "PrimaryFire" && e.Value > 0) { if (e.Command == "PrimaryFire" && e.Value > 0) {
Events::Shoot eShoot; Events::Shoot eShoot;
eShoot.shooter = e.PlayerID; eShoot.Player = m_LocalPlayer;
m_EventBroker->Publish(eShoot); m_EventBroker->Publish(eShoot);
} }
return true; return true;
} }
bool WeaponSystem::OnShoot(const Events::Shoot& e) {
//screen center, based on current resolution! bool WeaponSystem::OnShoot(const Events::Shoot& eShoot) {
// Screen center, based on current resolution!
//TODO: check if player has enough ammo and if weapon has a cooldown or not
Rectangle screenResolution = m_Renderer->Resolution(); Rectangle screenResolution = m_Renderer->Resolution();
glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2); glm::vec2 centerScreen = glm::vec2(screenResolution.Width / 2, screenResolution.Height / 2);
m_EShootVector.push_back(std::make_pair(e.shooter, centerScreen));
// TODO: check if player has enough ammo and if weapon has a cooldown or not
// Pick middle of screen
PickData pickData = m_Renderer->Pick(centerScreen);
if (pickData.Entity == EntityID_Invalid) {
return false;
}
EntityWrapper player(m_World, pickData.Entity);
// Only care about players being hit
if (!player.HasComponent("Player")) {
player = player.FirstParentWithComponent("Player");
}
if (!player.Valid()) {
return false;
}
// Check for friendly fire
EntityWrapper shooter = eShoot.Player;
if ((ComponentInfo::EnumType)player["Team"]["Team"] == (ComponentInfo::EnumType)shooter["Team"]["Team"]) {
return false;
}
// TODO: Weapon damage calculations etc
Events::PlayerDamage ePlayerDamage;
ePlayerDamage.Player = player;
ePlayerDamage.Damage = 100;
m_EventBroker->Publish(ePlayerDamage);
return true; return true;
} }
+8 -6
View File
@@ -27,7 +27,9 @@ using boost::unit_test_framework::test_case;
void RayTest(std::string fileName) { void RayTest(std::string fileName) {
//simple box test //simple box test
Ray ray(glm::vec3(-50, 0, 0), glm::vec3(1, 0, 0)); Ray ray(glm::vec3(-50, 0, 0), glm::vec3(1, 0, 0));
//using a rawmodel here, else we have to init the renderingsystem //using a
//here, else we have to init the renderingsystem
ResourceManager::RegisterType<RawModel>("RawModel"); ResourceManager::RegisterType<RawModel>("RawModel");
auto unitBox = ResourceManager::Load<RawModel>(fileName); auto unitBox = ResourceManager::Load<RawModel>(fileName);
BOOST_REQUIRE(unitBox != nullptr); BOOST_REQUIRE(unitBox != nullptr);
@@ -106,7 +108,7 @@ BOOST_AUTO_TEST_CASE(collisionTest2)
BOOST_AUTO_TEST_CASE(rayVsModelTest) BOOST_AUTO_TEST_CASE(rayVsModelTest)
{ {
//simple box test //simple box test
RayTest("Models/Core/UnitCube.obj"); RayTest("Models/Core/UnitCube.mesh"); // 360NoScope Unitcube
} }
BOOST_AUTO_TEST_CASE(rayVsModelTest2) BOOST_AUTO_TEST_CASE(rayVsModelTest2)
@@ -128,7 +130,7 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
someAABB = AABB(minPos, maxPos); someAABB = AABB(minPos, maxPos);
//using a rawmodel here, else we have to init the renderingsystem //using a rawmodel here, else we have to init the renderingsystem
ResourceManager::RegisterType<RawModel>("RawModel"); ResourceManager::RegisterType<RawModel>("RawModel");
auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitCube.obj"); auto unitBox = ResourceManager::Load<RawModel>("Models/Core/UnitCube.mesh"); // 360NoScope unitcube
BOOST_CHECK(unitBox != nullptr); BOOST_CHECK(unitBox != nullptr);
for (size_t i = 0; i < 1000000; i++) for (size_t i = 0; i < 1000000; i++)
@@ -187,19 +189,19 @@ BOOST_AUTO_TEST_CASE(rayVsModelTest2)
BOOST_AUTO_TEST_CASE(rayVsModelTest3) BOOST_AUTO_TEST_CASE(rayVsModelTest3)
{ {
//simple test //simple test
RayTest("Models/Core/UnitSphere.obj"); RayTest("Models/Core/UnitSphere.mesh"); // 360NoScope unitSphere
} }
BOOST_AUTO_TEST_CASE(rayVsModelTest4) BOOST_AUTO_TEST_CASE(rayVsModelTest4)
{ {
//simple test //simple test
RayTest("Models/Core/UnitCylinder.obj"); RayTest("Models/Core/UnitCylinder.mesh"); // 360NoScope unitCylinder
} }
BOOST_AUTO_TEST_CASE(rayVsModelTest5) BOOST_AUTO_TEST_CASE(rayVsModelTest5)
{ {
//simple test //simple test
RayTest("Models/Core/UnitRaptor.obj"); RayTest("Models/Core/UnitRaptor.mesh"); // 360NoScope unitRaptor
} }
BOOST_AUTO_TEST_CASE(octTest) BOOST_AUTO_TEST_CASE(octTest)
{ {
+4 -4
View File
@@ -56,7 +56,7 @@ GameHealthSystemTest::GameHealthSystemTest()
EntityID playerID = m_World->CreateEntity(); EntityID playerID = m_World->CreateEntity();
ComponentWrapper transform = m_World->AttachComponent(playerID, "Transform"); ComponentWrapper transform = m_World->AttachComponent(playerID, "Transform");
ComponentWrapper model = m_World->AttachComponent(playerID, "Model"); ComponentWrapper model = m_World->AttachComponent(playerID, "Model");
model["Resource"] = "Models/Core/UnitSphere.obj"; model["Resource"] = "Models/Core/UnitSphere.mesh"; // 360NoScope UnitSphere
ComponentWrapper player = m_World->AttachComponent(playerID, "Player"); ComponentWrapper player = m_World->AttachComponent(playerID, "Player");
ComponentWrapper health = m_World->AttachComponent(playerID, "Health"); ComponentWrapper health = m_World->AttachComponent(playerID, "Health");
healthsID = playerID; healthsID = playerID;
@@ -69,8 +69,8 @@ GameHealthSystemTest::GameHealthSystemTest()
m_EventBroker->Publish(e3); m_EventBroker->Publish(e3);
//damage player with 50 //damage player with 50
Events::PlayerDamage e; Events::PlayerDamage e;
e.DamageAmount = 50.0f; e.Damage = 50.0f;
e.PlayerDamagedID = healthsID; //e.Player = healthsID;
m_EventBroker->Publish(e); m_EventBroker->Publish(e);
//heal some other player with 40 //heal some other player with 40
Events::PlayerHealthPickup e2; Events::PlayerHealthPickup e2;
@@ -81,7 +81,7 @@ GameHealthSystemTest::GameHealthSystemTest()
EntityID playerID2 = m_World->CreateEntity(); EntityID playerID2 = m_World->CreateEntity();
ComponentWrapper transform2 = m_World->AttachComponent(playerID2, "Transform"); ComponentWrapper transform2 = m_World->AttachComponent(playerID2, "Transform");
ComponentWrapper model2 = m_World->AttachComponent(playerID2, "Model"); ComponentWrapper model2 = m_World->AttachComponent(playerID2, "Model");
model2["Resource"] = "Models/Core/UnitSphere.obj"; model2["Resource"] = "Models/Core/UnitSphere.mesh"; // 360NoScope UnitSphere
ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player"); ComponentWrapper player2 = m_World->AttachComponent(playerID2, "Player");
ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health"); ComponentWrapper health2 = m_World->AttachComponent(playerID2, "Health");
//END TEST //END TEST
+1 -1
View File
@@ -112,7 +112,7 @@ void OctTree::Update(float dt, World* world, Camera* cam)
ComponentWrapper transform = world->AttachComponent(m_BoxID, "Transform"); ComponentWrapper transform = world->AttachComponent(m_BoxID, "Transform");
transform["Scale"] = boxSize; transform["Scale"] = boxSize;
ComponentWrapper model = world->AttachComponent(m_BoxID, "Model"); ComponentWrapper model = world->AttachComponent(m_BoxID, "Model");
model["Resource"] = "Models/Core/UnitBox.obj"; model["Resource"] = "Models/Core/UnitBox.mesh"; // 360NoScope UnitBox
m_UpdatedOnce = true; m_UpdatedOnce = true;
} }
+1 -1
View File
@@ -26,7 +26,7 @@ BOOST_AUTO_TEST_CASE(resourceManagerTest)
BOOST_CHECK(!ResourceManager::IsResourceLoaded("ConfigFile", "Config.ini")); BOOST_CHECK(!ResourceManager::IsResourceLoaded("ConfigFile", "Config.ini"));
//configfile without register //configfile without register
BOOST_CHECK_THROW(ResourceManager::Load<Model>("Models/Core/ScreenQuad.obj"),Resource::FailedLoadingException); BOOST_CHECK_THROW(ResourceManager::Load<Model>("Models/Core/ScreenQuad.mesh"),Resource::FailedLoadingException);
//there is no error feedback to check if you try to release the wrong resources - hence that cant be tested either //there is no error feedback to check if you try to release the wrong resources - hence that cant be tested either
} }
+224
View File
@@ -0,0 +1,224 @@
#include "Export.h"
Export::Export()
{
}
bool Export::Meshes(std::string pathName, bool selectedOnly)
{
MStatus status;
if (pathName.empty()) {
MGlobal::displayError(MString() + "Export::Meshes() got no pathName. Do not know where to write file");
return false;
}
MSelectionList selectedOnStart;
MGlobal::getActiveSelectionList(selectedOnStart);
if (selectedOnStart.length() > 0) {
for (int i = 0; i < selectedOnStart.length(); i++) {
MObject item;
selectedOnStart.getDependNode(i, item);
MGlobal::unselect(item);
}
}
MGlobal::displayInfo(MString() + "Disabel IKSolvers");
status = MGlobal::executeCommand("doEnableNodeItems false all;");
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "EnableNodeItems false all failed: " + status.errorString());
}
MGlobal::displayInfo(MString() + "Has disabel IKSolvers");
MObjectArray Objects;
if (selectedOnly) {
// Retrieving the objects we currently have selected
// Loop through or list of selection(s)
for (unsigned int i = 0; i < selectedOnStart.length(); i++) {
MObject object;
selectedOnStart.getDependNode(i, object);
if (object.hasFn(MFn::kMesh)) {
MFnMesh shape(object);
for (unsigned int k = 0; k < shape.parentCount(); k++) {
MFnDependencyNode thisNode(object);
MPlugArray connections;
thisNode.findPlug("inMesh").connectedTo(connections, true, true);
for (unsigned int i = 0; i < connections.length(); i++) {
if (connections[i].node().apiType() == MFn::kSkinClusterFilter) {
MGlobal::select(shape.parent(i), MGlobal::kReplaceList);
MGlobal::displayInfo(MString() + "Moving " + thisNode.name() + " to bindPose.");
status = MGlobal::executeCommand("GoToBindPose;");
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "GoToBindPose: " + status.errorString());
}
MGlobal::displayInfo(MString() + "Has moved " + thisNode.name() + " to bindPose.");
}
}
}
Objects.append(object);
}
}
} else {
// Loop through all nodes in the scene
MItDependencyNodes it(MFn::kMesh);
for (; !it.isDone(); it.next()) {
MObject node = it.thisNode();
MFnDependencyNode thisNode(node);
MPlugArray connections;
thisNode.findPlug("inMesh").connectedTo(connections, true, true);
for (unsigned int i = 0; i < connections.length(); i++) {
if (connections[i].node().apiType() == MFn::kSkinClusterFilter) {
MGlobal::select(node);
MGlobal::displayInfo(MString() + "Moving " + thisNode.name() + " to bindPose.");
MGlobal::executeCommand("GoToBindPose");
MGlobal::displayInfo(MString() + "Has moved " + thisNode.name() + " to bindPose.");
}
}
Objects.append(node);
}
}
GetMeshData(Objects);
WriteMeshData(pathName);
MGlobal::displayInfo(MString() + "Enabling IKSolvers");
status = MGlobal::executeCommand("doEnableNodeItems true all;");
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "doEnableNodeItems true all: " + status.errorString());
}
MGlobal::displayInfo(MString() + "Has enabling IKSolvers");
if (selectedOnStart.length() > 0) {
for (int i = 0; i < selectedOnStart.length(); i++) {
MObject item;
selectedOnStart.getDependNode(i, item);
MGlobal::select(item);
}
}
return true;
}
bool Export::Materials(std::string pathName)
{
if (!GetMaterialData())
return false;
WriteMaterialData(pathName);
return true;
}
bool Export::Animations(std::string pathName, std::vector<AnimationInfo> animInfo)
{
if (MAnimControl::currentTime().unit() != MTime::kNTSCField) {
MGlobal::displayError(MString() + "Please change to 60 FPS under Preferences/Settings!");
return false;
}
if (pathName.empty()) {
MGlobal::displayError(MString() + "Export::Animations() got no pathName. Do not know where to write file");
return false;
}
allBindPoses = m_SkeletonHandler.GetBindPoses();
for (auto clip : animInfo) {
if (!GetAnimationData(clip)) {
MGlobal::displayError(MString() + "Export::Animations() failed to export " + clip.Name.c_str());
return false;
}
}
WriteAnimData(pathName);
return true;
}
bool Export::GetMeshData(MObjectArray object)
{
meshes = m_MeshHandler.GetMeshData(object);
return true;
}
bool Export::GetMaterialData()
{
// Traverse scene and return vector with all materials
AllMaterials = m_MaterialHandler.DoIt(meshes);
return true;
}
bool Export::GetAnimationData(AnimationInfo animInfo)
{
if (animInfo.Name.empty()) {
MGlobal::displayError(MString() + "A clip does not have a name");
return false;
}
if (animInfo.End - animInfo.Start <= 0) {
MGlobal::displayError(MString() + "A clip ends before it starts or contains 0 frames");
return false;
}
allAnimations.push_back(m_SkeletonHandler.GetAnimData(animInfo.Name, animInfo.Start, animInfo.End));
return true;
}
void Export::WriteMeshData(std::string pathName)
{
m_MeshFile.ASCIIFilePath(pathName +"_mesh.txt");
m_MeshFile.binaryFilePath(pathName + ".mesh");
m_MeshFile.OpenFiles();
m_MeshFile.writeToFiles((OutputData*)&meshes);
m_MeshFile.CloseFiles();
}
void Export::WriteAnimData(std::string pathName)
{
if (allBindPoses.size() > 0) {
m_AnimFile.ASCIIFilePath(pathName + "_anim.txt");
m_AnimFile.binaryFilePath(pathName + ".anim");
m_AnimFile.OpenFiles();
int size = allBindPoses.size();
m_AnimFile.writeToFiles(&size);
size = allAnimations.size();
m_AnimFile.writeToFiles(&size);
//print out all bind poses
for (auto aBindPose : allBindPoses) {
m_AnimFile.writeToFiles((OutputData*)&aBindPose);
}
for (auto aAnimation : allAnimations) {
m_AnimFile.writeToFiles((OutputData*)&aAnimation);
}
m_AnimFile.CloseFiles();
} else
MGlobal::displayInfo("Export::WriteAnimData() got called when allBindPoses contained no data, did not write nor created them");
}
void Export::WriteMaterialData(std::string pathName)
{
m_MtrlFile.ASCIIFilePath(pathName +"_mtrl.txt");
m_MtrlFile.binaryFilePath(pathName + ".mtrl");
m_MtrlFile.OpenFiles();
int size = (*AllMaterials).size();
m_MtrlFile.writeToFiles(&size);
for (auto aMaterial : *AllMaterials) {
m_MtrlFile.writeToFiles((OutputData*)&aMaterial);
}
m_MtrlFile.CloseFiles();
}
Export::~Export()
{
/* delete m_MaterialHandler;
delete m_SkeletonHandler;
delete m_MeshHandler;*/
}
+58
View File
@@ -0,0 +1,58 @@
#ifndef Export_Export_h__
#define Export_Export_h__
#include <vector>
#include <string>
#include "MayaIncludes.h"
#include "Material.h"
#include "Mesh.h"
#include "Skeleton.h"
#include "WriteToFile.h"
class Export {
public:
Export();
~Export();
struct AnimationInfo {
std::string Name;
int Start;
int End;
};
bool Meshes(std::string pathName, bool selectedOnly = false);
bool Materials(std::string pathName);
bool Animations(std::string pathName, std::vector<AnimationInfo> animInfo);
private:
bool GetMeshData(MObjectArray object);
bool GetMaterialData();
bool GetAnimationData(AnimationInfo info);
void WriteMeshData(std::string pathName);
void WriteAnimData(std::string pathName);
void WriteMaterialData(std::string pathName);
Material m_MaterialHandler;
Skeleton m_SkeletonHandler;
MeshClass m_MeshHandler;
//File export
WriteToFile m_MeshFile;
WriteToFile m_AnimFile;
WriteToFile m_MtrlFile;
//Mesh Data
Mesh meshes;
//Animation Data
std::vector<BindPoseSkeletonNode> allBindPoses;
std::vector<Animation> allAnimations;
//Material Data
std::vector<MaterialNode>* AllMaterials;
};
#endif
@@ -22,7 +22,7 @@ static const uint qt_meta_data_Menu[] = {
6, // revision 6, // revision
0, // classname 0, // classname
0, 0, // classinfo 0, 0, // classinfo
7, 14, // methods 5, 14, // methods
0, 0, // properties 0, 0, // properties
0, 0, // enums/sets 0, 0, // enums/sets
0, 0, // constructors 0, 0, // constructors
@@ -30,22 +30,19 @@ static const uint qt_meta_data_Menu[] = {
0, // signalCount 0, // signalCount
// slots: signature, parameters, type, tag, flags // slots: signature, parameters, type, tag, flags
14, 6, 5, 5, 0x08, 6, 5, 5, 5, 0x08,
35, 5, 5, 5, 0x08, 30, 5, 5, 5, 0x08,
59, 5, 5, 5, 0x08, 51, 5, 5, 5, 0x08,
75, 5, 5, 5, 0x08, 75, 5, 5, 5, 0x08,
95, 5, 5, 5, 0x08, 91, 5, 5, 5, 0x08,
116, 5, 5, 5, 0x08,
137, 5, 5, 5, 0x08,
0 // eod 0 // eod
}; };
static const char qt_meta_stringdata_Menu[] = { static const char qt_meta_stringdata_Menu[] = {
"Menu\0\0checked\0ExportSelected(bool)\0" "Menu\0\0ExportPathClicked(bool)\0"
"ExportPathClicked(bool)\0ExportAll(bool)\0" "AddClipClicked(bool)\0RemoveClipClicked(bool)\0"
"CancelClicked(bool)\0Button1Clicked(bool)\0" "ExportAll(bool)\0CancelClicked(bool)\0"
"Button2Clicked(bool)\0Button3Clicked(bool)\0"
}; };
void Menu::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) void Menu::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
@@ -54,13 +51,11 @@ void Menu::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void *
Q_ASSERT(staticMetaObject.cast(_o)); Q_ASSERT(staticMetaObject.cast(_o));
Menu *_t = static_cast<Menu *>(_o); Menu *_t = static_cast<Menu *>(_o);
switch (_id) { switch (_id) {
case 0: _t->ExportSelected((*reinterpret_cast< bool(*)>(_a[1]))); break; case 0: _t->ExportPathClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 1: _t->ExportPathClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; case 1: _t->AddClipClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 2: _t->ExportAll((*reinterpret_cast< bool(*)>(_a[1]))); break; case 2: _t->RemoveClipClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 3: _t->CancelClicked((*reinterpret_cast< bool(*)>(_a[1]))); break; case 3: _t->ExportAll((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 4: _t->Button1Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break; case 4: _t->CancelClicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 5: _t->Button2Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
case 6: _t->Button3Clicked((*reinterpret_cast< bool(*)>(_a[1]))); break;
default: ; default: ;
} }
} }
@@ -98,9 +93,9 @@ int Menu::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
if (_id < 0) if (_id < 0)
return _id; return _id;
if (_c == QMetaObject::InvokeMetaMethod) { if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 7) if (_id < 5)
qt_static_metacall(this, _c, _id, _a); qt_static_metacall(this, _c, _id, _a);
_id -= 7; _id -= 5;
} }
return _id; return _id;
} }
@@ -0,0 +1,237 @@
#include "Material.h"
void Material::grabLambertProperties(MaterialNode& material_node, MFnDependencyNode& node)
{
material_node.Name = node.name().asChar();
if (!findColorTexture(material_node, node)) {
node.findPlug("colorR").getValue(material_node.DiffuseColor[0]);
node.findPlug("colorG").getValue(material_node.DiffuseColor[1]);
node.findPlug("colorB").getValue(material_node.DiffuseColor[2]);
}
if (!findIncandescenceTexture(material_node, node)) {
node.findPlug("incandescenceR").getValue(material_node.IncandescenceColor[0]);
node.findPlug("incandescenceG").getValue(material_node.IncandescenceColor[1]);
node.findPlug("incandescenceB").getValue(material_node.IncandescenceColor[2]);
}
if (findNormalTexture(material_node, node)) {
MGlobal::displayWarning(MString() + "Material " + node.name() + " has no normal texture.");
}
}
void Material::grabBlinnProperties(MaterialNode& material_node, MFnDependencyNode& node)
{
if (!findSpecularTexture(material_node, node)) {
node.findPlug("specularColorR").getValue(material_node.SpecularColor[0]);
node.findPlug("specularColorG").getValue(material_node.SpecularColor[1]);
node.findPlug("specularColorB").getValue(material_node.SpecularColor[2]);
}
m_Plug = node.findPlug("reflectivity");
m_Plug.getValue(material_node.ReflectionFactor);
m_Plug = node.findPlug("eccentricity");
float TempEccent;
m_Plug.getValue(TempEccent);
// Blinn works differently from Phong which is used in-game.
// This is some magic numbers and math to make a conversion estimate between the two.
// There is no exact conversion between the two, so there are errors.
// Phong min/max is around Blinn 0.7/0.1
TempEccent = std::max(std::min(TempEccent, 0.7f), 0.1f);
material_node.SpecularExponent = std::max(std::min(((2.66f) + (427.0f) * exp((-14.8f) * TempEccent)), 100.0f), 2.0f);
}
void Material::grabPhongProperties(MaterialNode& material_node, MFnDependencyNode& node)
{
if (!findSpecularTexture(material_node, node)) {
node.findPlug("specularColorR").getValue(material_node.SpecularColor[0]);
node.findPlug("specularColorG").getValue(material_node.SpecularColor[1]);
node.findPlug("specularColorB").getValue(material_node.SpecularColor[2]);
}
m_Plug = node.findPlug("reflectivity");
m_Plug.getValue(material_node.ReflectionFactor);
m_Plug = node.findPlug("cosinePower ");
m_Plug.getValue(material_node.SpecularExponent);
}
bool Material::findColorTexture(MaterialNode& material_node, MFnDependencyNode& node)
{
MPlugArray AllConnections;
m_Plug = node.findPlug("color", true);
m_Plug.connectedTo(AllConnections, true, false);
for (int i = 0; i < AllConnections.length(); i++) {
if (AllConnections[i].node().hasFn(MFn::kFileTexture)) {
MFnDependencyNode TextureNode(AllConnections[i].node());
std::string FullPath = TextureNode.findPlug("fileTextureName").asString().asChar();
m_TexturePaths.push_back(FullPath);
MString workspace;
MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"),
workspace);
FullPath = FullPath.substr(workspace.length());
FullPath = FullPath.substr(FullPath.find_first_of("/") + 1);
material_node.ColorMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size());
material_node.ColorMapFileLength = material_node.ColorMapFile.length() + 1;
// Test
MGlobal::displayInfo(MString() + "getAbsolutePathToResources: " + workspace);
MGlobal::displayInfo(MString() + "Texture file: " + FullPath.c_str());
return true;
}
}
return false;
}
bool Material::findNormalTexture(MaterialNode& material_node, MFnDependencyNode& node)
{
MPlugArray AllConnections;
MPlugArray AllBumpConnections;
m_Plug = node.findPlug("normalCamera", true);
m_Plug.connectedTo(AllConnections, true, false);
for (int i = 0; i < AllConnections.length(); i++) {
if (AllConnections[i].node().apiType() == MFn::kBump) {
MFnDependencyNode BumpNode(AllConnections[i].node());
BumpNode.findPlug("bumpValue").connectedTo(AllBumpConnections, true, false);
for (int j = 0; j < AllBumpConnections.length(); j++) {
if (AllBumpConnections[j].node().hasFn(MFn::kFileTexture)) {
MFnDependencyNode TextureNode(AllBumpConnections[j].node());
std::string FullPath = TextureNode.findPlug("ftn").asString().asChar();
m_TexturePaths.push_back(FullPath);
MString workspace;
MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"),
workspace);
FullPath = FullPath.substr(workspace.length());
FullPath = FullPath.substr(FullPath.find_first_of("/") + 1);
material_node.NormalMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size());
material_node.NormalMapFileLength = material_node.NormalMapFile.length() + 1;
return true;
}
}
}
}
return false;
}
bool Material::findSpecularTexture(MaterialNode& material_node, MFnDependencyNode& node)
{
MPlugArray AllConnections;
m_Plug = node.findPlug("specularColor", true);
m_Plug.connectedTo(AllConnections, true, false);
for (int i = 0; i < AllConnections.length(); i++) {
if (AllConnections[i].node().hasFn(MFn::kFileTexture)) {
MFnDependencyNode TextureNode(AllConnections[i].node());
std::string FullPath = TextureNode.findPlug("ftn").asString().asChar();
m_TexturePaths.push_back(FullPath);
MString workspace;
MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"),
workspace);
FullPath = FullPath.substr(workspace.length());
FullPath = FullPath.substr(FullPath.find_first_of("/") + 1);
material_node.SpecularMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size());
material_node.SpecularMapFileLength = material_node.SpecularMapFile.length() + 1;
return true;
}
}
return false;
}
bool Material::findIncandescenceTexture(MaterialNode& material_node, MFnDependencyNode& node)
{
MPlugArray AllConnections;
m_Plug = node.findPlug("incandescence", true);
m_Plug.connectedTo(AllConnections, true, false);
for (int i = 0; i < AllConnections.length(); i++) {
if (AllConnections[i].node().hasFn(MFn::kFileTexture)) {
MFnDependencyNode TextureNode(AllConnections[i].node());
std::string FullPath = TextureNode.findPlug("ftn").asString().asChar();
m_TexturePaths.push_back(FullPath);
MString workspace;
MStatus status = MGlobal::executeCommand(MString("workspace -q -rd;"),
workspace);
FullPath = FullPath.substr(workspace.length());
FullPath = FullPath.substr(FullPath.find_first_of("/") + 1);
material_node.IncandescenceMapFile = FullPath.erase(FullPath.find_last_of("."), FullPath.find_last_of(".") - FullPath.size());
material_node.IncandescenceMapFileLength = material_node.IncandescenceMapFile.length() + 1;
return true;
}
}
return false;
}
// Returns the absolute path for all textures. Use for copying texture files.
std::vector<std::string>* Material::TexturePaths()
{
return &m_TexturePaths;
}
// Traverse the DAG and grab all the materials
std::vector<MaterialNode>* Material::DoIt(Mesh mesh)
{
// All materials we care about inherit from Lambert
MItDependencyNodes matIt(MFn::kLambert);
m_AllMaterials.clear();
while (!matIt.isDone()) {
MFnDependencyNode MaterialFnDN(matIt.thisNode());
MaterialNode MaterialStorage;
bool meshHasMaterial = false;
//Mesh Indices is a map with <string : MaterialName, vector<int> : indices>
int totalIndices = 0;
for (auto aMeshMaterial : mesh.Indices) {
MGlobal::displayInfo(MString() + "Material: " + aMeshMaterial.first.c_str() + " " + MaterialFnDN.name().asChar());
if (aMeshMaterial.first.compare(MaterialFnDN.name().asChar()) == 0) {
meshHasMaterial = true;
MaterialStorage.IndexStart = totalIndices;
MaterialStorage.IndexEnd = totalIndices + aMeshMaterial.second.size() - 1;
break;
}
totalIndices += aMeshMaterial.second.size();
}
if (meshHasMaterial) {
grabLambertProperties(MaterialStorage, MaterialFnDN);
if (matIt.thisNode().hasFn(MFn::kPhong)) {
grabPhongProperties(MaterialStorage, MaterialFnDN);
} else if (matIt.thisNode().hasFn(MFn::kBlinn)) {
grabBlinnProperties(MaterialStorage, MaterialFnDN);
} else if (matIt.thisNode().hasFn(MFn::kLambert)) {
MaterialStorage.ReflectionFactor = 0.0f;
MaterialStorage.SpecularExponent = 0.0f;
}
m_AllMaterials.push_back(MaterialStorage);
}
matIt.next();
}
return &m_AllMaterials;
}
+115
View File
@@ -0,0 +1,115 @@
#ifndef Material_Material_h__
#define Material_Material_h__
#include <vector>
#include <array>
#include <algorithm>
#include <cmath>
#include <map>
#include "MayaIncludes.h"
#include "OutputData.h"
#include "Mesh.h"
class MaterialNode : public OutputData
{
public:
std::string Name;
float ReflectionFactor;
float SpecularExponent;
float DiffuseColor[3]{ 1.0f, 1.0f, 1.0f };
unsigned int ColorMapFileLength = 0;
std::string ColorMapFile;
float SpecularColor[3]{ 1.0f, 1.0f, 1.0f };
unsigned int SpecularMapFileLength = 0;
std::string SpecularMapFile;
unsigned int NormalMapFileLength = 0;
std::string NormalMapFile;
float IncandescenceColor[3]{ 1.0f, 1.0f, 1.0f };
unsigned int IncandescenceMapFileLength = 0;
std::string IncandescenceMapFile;
unsigned int IndexStart;
unsigned int IndexEnd;
virtual void WriteBinary(std::ostream& out)
{
out.write((char*)&ColorMapFileLength, sizeof(unsigned int));
out.write((char*)&NormalMapFileLength, sizeof(unsigned int));
out.write((char*)&SpecularMapFileLength, sizeof(unsigned int));
out.write((char*)&IncandescenceMapFileLength, sizeof(unsigned int));
out.write((char*)&SpecularExponent, sizeof(float));
out.write((char*)&ReflectionFactor, sizeof(float));
out.write((char*)&DiffuseColor, sizeof(float) * 3);
out.write((char*)&SpecularColor, sizeof(float) * 3);
out.write((char*)&IncandescenceColor, sizeof(float) * 3);
out.write((char*)&IndexStart, sizeof(unsigned int));
out.write((char*)&IndexEnd, sizeof(unsigned int));
out.write(ColorMapFile.c_str(), ColorMapFileLength);
out.write(NormalMapFile.c_str(), NormalMapFileLength);
out.write(SpecularMapFile.c_str(), SpecularMapFileLength);
out.write(IncandescenceMapFile.c_str(), IncandescenceMapFileLength);
}
virtual void WriteASCII(std::ostream& out) const
{
out << "New Material _ not in binary" << endl;
out << "number of indices: " << Name << " _ not in binary" << endl;
out << "ColorMapFile length: " << ColorMapFileLength << endl;
out << "NormalMapFile length: " << NormalMapFileLength << endl;
out << "SpecularMapFile length: " << SpecularMapFileLength << endl;
out << "IncandescenceMapFile length: " << IncandescenceMapFileLength << endl;
out << "SpecularExponent: " << SpecularExponent << endl;
out << "ReflectionFactor: " << ReflectionFactor << endl;
out << "DiffuseColor: " << DiffuseColor[0] << " " << DiffuseColor[1] << " " << DiffuseColor[2] << endl;
out << "SpecularColor: " << SpecularColor[0] << " " << SpecularColor[1] << " " << SpecularColor[2] << endl;
out << "IncandescenceColor: " << IncandescenceColor[0] << " " << IncandescenceColor[1] << " " << IncandescenceColor[2] << endl;
out << "IndexStart: " << IndexStart << endl;
out << "IndexEnd: " << IndexEnd << endl;
if (ColorMapFileLength > 0)
out << "ColorMapFile: " << ColorMapFile << endl;
if (NormalMapFileLength > 0)
out << "NormalMapFile: " << NormalMapFile << endl;
if (SpecularMapFileLength > 0)
out << "SpecularMapFile: " << SpecularMapFile << endl;
if (IncandescenceMapFileLength > 0)
out << "IncandescenceMapFile: " << IncandescenceMapFile << endl;
}
};
class Material
{
public:
Material() {};
~Material() {};
std::vector<MaterialNode>* DoIt(Mesh mesh);
std::vector<std::string>* TexturePaths();
private:
MPlug m_Plug;
std::vector<MaterialNode> m_AllMaterials;
std::vector<std::string> m_TexturePaths;
bool findColorTexture(MaterialNode& material_node, MFnDependencyNode& node);
bool findNormalTexture(MaterialNode& material_node, MFnDependencyNode& node);
bool findSpecularTexture(MaterialNode& material_node, MFnDependencyNode& node);
bool findIncandescenceTexture(MaterialNode& material_node, MFnDependencyNode& node);
void grabLambertProperties(MaterialNode& material_node, MFnDependencyNode& node);
void grabBlinnProperties(MaterialNode& material_node, MFnDependencyNode& node);
void grabPhongProperties(MaterialNode& material_node, MFnDependencyNode& node);
};
#endif // Material_Material_h__
@@ -140,6 +140,7 @@
</DebugInformationFormat> </DebugInformationFormat>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType> <TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<Optimization>Disabled</Optimization>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@@ -152,6 +153,8 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Export.cpp" />
<ClCompile Include="Material.cpp" />
<ClCompile Include="Menu.cpp" /> <ClCompile Include="Menu.cpp" />
<ClCompile Include="GeneratedFiles\Debug\moc_Menu.cpp"> <ClCompile Include="GeneratedFiles\Debug\moc_Menu.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -172,6 +175,9 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="Main.cpp" /> <ClCompile Include="Main.cpp" />
<ClCompile Include="Mesh.cpp" />
<ClCompile Include="Skeleton.cpp" />
<ClCompile Include="WriteToFile.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="MayaExporter.ui"> <CustomBuild Include="MayaExporter.ui">
@@ -194,6 +200,11 @@
</CustomBuild> </CustomBuild>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Export.h" />
<ClInclude Include="Mesh.h" />
<ClInclude Include="OutputData.h" />
<ClInclude Include="Skeleton.h" />
<ClInclude Include="WriteToFile.h" />
<CustomBuild Include="Menu.h"> <CustomBuild Include="Menu.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing Menu.h...</Message> <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing Menu.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
@@ -213,6 +224,7 @@
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs> <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild> </CustomBuild>
<ClInclude Include="GeneratedFiles\ui_MayaExporter.h" /> <ClInclude Include="GeneratedFiles\ui_MayaExporter.h" />
<ClInclude Include="Material.h" />
<ClInclude Include="MayaIncludes.h" /> <ClInclude Include="MayaIncludes.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -50,6 +50,21 @@
<ClCompile Include="Main.cpp"> <ClCompile Include="Main.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Material.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Mesh.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Skeleton.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WriteToFile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Export.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="leeeeel.qrc"> <CustomBuild Include="leeeeel.qrc">
@@ -69,5 +84,23 @@
<ClInclude Include="GeneratedFiles\ui_MayaExporter.h"> <ClInclude Include="GeneratedFiles\ui_MayaExporter.h">
<Filter>Generated Files</Filter> <Filter>Generated Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Material.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Mesh.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Skeleton.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WriteToFile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="OutputData.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Export.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -30,6 +30,21 @@
#include <maya/MItDependencyNodes.h> #include <maya/MItDependencyNodes.h>
#include <maya/MFnNurbsCurve.h> #include <maya/MFnNurbsCurve.h>
#include <maya/MCommandMessage.h> #include <maya/MCommandMessage.h>
#include <maya/MPlug.h>
#include <maya/MAnimControl.h>
#include <maya/MTime.h>
#include <maya/MDataHandle.h>
#include <maya/MTransformationMatrix.h>
#include <maya/MFnMatrixData.h>
#include <maya/MItMeshFaceVertex.h>
#include <maya/MFnSkinCluster.h>
#include <maya/MDagPathArray.h>
#include <maya/MItGeometry.h>
#include <maya/MItMeshVertex.h>
#include <maya/MFnWeightGeometryFilter.h>
#include <maya/MItDependencyGraph.h>
#include <maya/MQuaternion.h>
#include <maya/MFnNumericAttribute.h>
// Wrappers // Wrappers
@@ -58,5 +73,6 @@
#pragma comment(lib,"Foundation.lib") #pragma comment(lib,"Foundation.lib")
#pragma comment(lib,"OpenMaya.lib") #pragma comment(lib,"OpenMaya.lib")
#pragma comment(lib,"OpenMayaUI.lib") #pragma comment(lib,"OpenMayaUI.lib")
#pragma comment (lib, "OpenMayaAnim.lib")
#endif #endif
+145 -165
View File
@@ -10,223 +10,200 @@ Menu::Menu()
Menu::Menu(QDialog* dialog) Menu::Menu(QDialog* dialog)
{ {
// Save the dialog pointer. Needed when the application gets destroyed // Save the dialog pointer. Needed when the application gets destroyed
dialogPointer = dialog; m_DialogPointer = dialog;
// Create QpushButtons & give them names // Create QpushButtons & give them names
exportSelectedButton = new QPushButton("&Export Selected", this); m_BrowseButton = new QPushButton("&...", this);
browseButton = new QPushButton("&...", this); m_ExportAllButton = new QPushButton("&Export", this);
exportAllButton = new QPushButton("&Export All", this); m_CancelButton = new QPushButton("&Cancel", this);
cancelButton = new QPushButton("&Cancel", this); m_AddClipsButton = new QPushButton("&Add Clips", this);
m_RemoveClipsButton = new QPushButton("&Remove Latest Clip", this);
// Option box and checkboxes // Option box and checkboxes
QGroupBox *optionsBox = new QGroupBox(tr("Options")); QGroupBox *optionsBox = new QGroupBox(tr("Options"));
exportAnimationsButton = new QCheckBox(tr("&Export Animations")); m_ExportSelectedButton = new QCheckBox(tr("&Export Selected"));
copyTexturesButton = new QCheckBox(tr("&Copy Textures")); m_ExportAnimationsButton = new QCheckBox(tr("&Export Animations"));
button3 = new QCheckBox(tr("option3")); m_ExportMaterialButton = new QCheckBox(tr("&Export Material"));;
exportAnimationsButton->setChecked(true); m_ExportAnimationsButton->setChecked(true);
copyTexturesButton->setChecked(true); m_ExportMaterialButton->setChecked(true);
QVBoxLayout *vbox = new QVBoxLayout; QVBoxLayout *vbox = new QVBoxLayout;
vbox->addWidget(exportAnimationsButton); vbox->addWidget(m_ExportSelectedButton);
vbox->addWidget(copyTexturesButton); vbox->addWidget(m_ExportAnimationsButton);
vbox->addWidget(button3); vbox->addWidget(m_ExportMaterialButton);
vbox->addStretch(1); vbox->addStretch(1);
optionsBox->setLayout(vbox); optionsBox->setLayout(vbox);
// Connect the buttons with signals & functions // Connect the buttons with signals & functions
connect(exportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(ExportSelected(bool))); connect(m_BrowseButton, SIGNAL(clicked(bool)), this, SLOT(ExportPathClicked(bool)));
connect(browseButton, SIGNAL(clicked(bool)), this, SLOT(ExportPathClicked(bool))); connect(m_ExportAllButton, SIGNAL(clicked(bool)), this, SLOT(ExportAll(bool)));
connect(exportAllButton, SIGNAL(clicked(bool)), this, SLOT(ExportAll(bool))); connect(m_CancelButton, SIGNAL(clicked(bool)), this, SLOT(CancelClicked(bool)));
connect(cancelButton, SIGNAL(clicked(bool)), this, SLOT(CancelClicked(bool))); connect(m_AddClipsButton, SIGNAL(clicked(bool)), this, SLOT(AddClipClicked(bool)));
connect(m_RemoveClipsButton, SIGNAL(clicked(bool)), this, SLOT(RemoveClipClicked(bool)));
connect(exportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(Button1Clicked(bool))); connect(m_ExportSelectedButton, SIGNAL(clicked(bool)), this, SLOT(NULL));
connect(copyTexturesButton, SIGNAL(clicked(bool)), this, SLOT(Button2Clicked(bool))); connect(m_ExportAnimationsButton, SIGNAL(clicked(bool)), this, SLOT(NULL));
connect(button3, SIGNAL(clicked(bool)), this, SLOT(Button3Clicked(bool))); connect(m_ExportMaterialButton, SIGNAL(clicked(bool)), this, SLOT(NULL));
// Creating several layouts, adding widgets & adding them to one layout in the end // Creating several layouts, adding widgets & adding them to one layout in the end
QHBoxLayout* topLayout = new QHBoxLayout; QHBoxLayout* topLayout = new QHBoxLayout;
QVBoxLayout* midLayout = new QVBoxLayout; QVBoxLayout* midLayout = new QVBoxLayout;
QHBoxLayout* botLayout = new QHBoxLayout; QHBoxLayout* botLayout = new QHBoxLayout;
QVBoxLayout* baseLayout = new QVBoxLayout; QVBoxLayout* baseLayout = new QVBoxLayout;
QHBoxLayout* clipButtonLayout = new QHBoxLayout;
QHBoxLayout* startEndLabelLayout = new QHBoxLayout;
m_ClipLayout = new QVBoxLayout;
exportPath = new QLineEdit;
fileDialog = new QFileDialog;
m_ExportPath = new QLineEdit;
m_FileDialog = new QFileDialog;
QString tmpPath("C:/Users/Nickelodion/Desktop/workspace/tacticalZ/assets/models/");
m_ExportPath->setText(tmpPath);
QLabel* exportLabel = new QLabel; QLabel* exportLabel = new QLabel;
exportLabel->setText("Export Path:"); exportLabel->setText("Export Path:");
QLabel* nameLabel = new QLabel;
nameLabel->setText("Name:");
QLabel* startLabel = new QLabel;
startLabel->setText("Start:");
QLabel* endLabel = new QLabel;
endLabel->setText("End:");
//exportLabel->setText("Export Path:");
midLayout->addWidget(optionsBox); midLayout->addWidget(optionsBox);
topLayout->addWidget(exportLabel); topLayout->addWidget(exportLabel);
topLayout->addWidget(exportPath); topLayout->addWidget(m_ExportPath);
topLayout->addWidget(browseButton); topLayout->addWidget(m_BrowseButton);
botLayout->addWidget(exportSelectedButton); botLayout->addWidget(m_ExportAllButton);
botLayout->addWidget(exportAllButton); botLayout->addWidget(m_CancelButton);
botLayout->addWidget(cancelButton);
startEndLabelLayout->addWidget(nameLabel);
startEndLabelLayout->addWidget(startLabel);
startEndLabelLayout->addWidget(endLabel);
clipButtonLayout->addWidget(m_AddClipsButton);
clipButtonLayout->addWidget(m_RemoveClipsButton);
baseLayout->addLayout(topLayout); baseLayout->addLayout(topLayout);
baseLayout->addLayout(midLayout); baseLayout->addLayout(midLayout);
baseLayout->addSpacing(10); baseLayout->addSpacing(10);
baseLayout->addLayout(botLayout); baseLayout->addLayout(botLayout);
baseLayout->addSpacing(10);
baseLayout->addLayout(clipButtonLayout);
baseLayout->addLayout(startEndLabelLayout);
baseLayout->addLayout(m_ClipLayout);
baseLayout->addStretch(); baseLayout->addStretch();
// Set the layout for our window // Set the layout for our window
dialog->setLayout(baseLayout); dialog->setLayout(baseLayout);
} this->AddClipClicked(true);
//for (unsigned int i = 0; i < 3; i++) {
// this->AddClipClicked(true);
//}
void Menu::ExportSelected(bool checked)
{
// Retrieving the objects we currently have selected
MSelectionList selected;
MGlobal::getActiveSelectionList(selected);
// Loop through or list of selection(s)
for (unsigned int i = 0; i < selected.length();i++)
{
MObject object;
selected.getDependNode(i, object);
MFnDependencyNode thisNode(object);
cout << thisNode.name().asChar() << endl;
GetMeshData(object);
}
if (exportPath->text().isEmpty())
cout << "Please select a folder." << endl;
else
cout << exportPath->text().toLocal8Bit().constData() << endl;
} }
void Menu::ExportPathClicked(bool) void Menu::ExportPathClicked(bool)
{ {
// Opens up a file dialog. Save/Changes the name in the exportPath // Opens up a file dialog. Save/Changes the name in the exportPath
fileDialog->setFileMode(QFileDialog::Directory); m_FileDialog->setFileMode(QFileDialog::Directory);
fileDialog->setOption(QFileDialog::ShowDirsOnly); m_FileDialog->setOption(QFileDialog::ShowDirsOnly);
QString fileName = fileDialog->getExistingDirectory(this, "Select", "/home", QFileDialog::ShowDirsOnly); QString fileName = m_FileDialog->getExistingDirectory(this, "Select", "/home", QFileDialog::ShowDirsOnly);
exportPath->setText(fileName); m_ExportPath->setText(fileName);
}
void Menu::AddClipClicked(bool)
{
QHBoxLayout* tempLayout = new QHBoxLayout;
QLineEdit* nameLineEdit = new QLineEdit;
QLineEdit* startLineEdit = new QLineEdit;
QLineEdit* endLineEdit = new QLineEdit;
m_AnimationClipName.push_back(nameLineEdit);
m_StartFrameLines.push_back(startLineEdit);
m_EndFrameLines.push_back(endLineEdit);
tempLayout->addWidget(nameLineEdit);
tempLayout->addWidget(startLineEdit);
tempLayout->addWidget(endLineEdit);
m_ClipLayout->addLayout(tempLayout);
//m_ClipLayout->update();
layouts.push_back(tempLayout);
}
void Menu::RemoveClipClicked(bool)
{
if (m_StartFrameLines.size() > 0) {
QLayoutItem* tempWidget;// = m_ClipLayout->itemAt(0);
for (unsigned int i = 0; i < layouts.size(); i++) {
while ((tempWidget = layouts[layouts.size() - 1]->takeAt(0)) != 0) {
delete tempWidget->widget();
delete tempWidget;
}
}
m_ClipLayout->removeItem(tempWidget);
m_ClipLayout->update();
layouts.pop_back();
m_StartFrameLines.pop_back();
m_EndFrameLines.pop_back();
m_AnimationClipName.pop_back();
}
} }
void Menu::ExportAll(bool) void Menu::ExportAll(bool)
{ {
MDagPath path; if (m_ExportPath->text().isEmpty()) {
MGlobal::displayError(MString() + "Please select a folder.");
// Loop through all nodes in the scene return;
MItDependencyNodes it(MFn::kInvalid); }
for (;!it.isDone();it.next())
{
MObject node = it.thisNode();
if (node.hasFn(MFn::kMesh))
{
MFnDependencyNode thisNode(node);
cout << thisNode.name().asChar() << endl; //Export meshes
GetMeshData(node); if (!m_Export.Meshes(m_ExportPath->text().toLocal8Bit().constData(), m_ExportSelectedButton->isChecked())) {
} MGlobal::displayError(MString() + "Could not export mesh");
} return;
if (exportPath->text().isEmpty()) }
cout << "Please select a folder." << endl;
else if (m_ExportMaterialButton->isChecked()) {
cout << exportPath->text().toLocal8Bit().constData() << endl; if (!m_Export.Materials(m_ExportPath->text().toLocal8Bit().constData())) {
MGlobal::displayError(MString() + "Could not export materials");
return;
}
}
std::vector<Export::AnimationInfo> animations;
for (unsigned int i = 0; i < m_AnimationClipName.size(); i++) {
Export::AnimationInfo thisClip;
thisClip.Name = std::string(m_AnimationClipName[i]->text().toLocal8Bit().constData());
thisClip.Start = m_StartFrameLines[i]->text().toInt();
thisClip.End = m_EndFrameLines[i]->text().toInt();
animations.push_back(thisClip);
}
if (m_ExportAnimationsButton->isChecked()) {
//Export Animations
if (!m_Export.Animations(m_ExportPath->text().toLocal8Bit().constData(), animations)) {
MGlobal::displayError(MString() + "Could not export animations");
return;
}
}
} }
void Menu::CancelClicked(bool) void Menu::CancelClicked(bool)
{ {
dialogPointer->close(); m_DialogPointer->close();
}
void Menu::Button1Clicked(bool)
{
if(exportAnimationsButton->isChecked())
cout << "1 checked!" << endl;
else
cout << "1 unchecked!" << endl;
}
void Menu::Button2Clicked(bool)
{
if (copyTexturesButton->isChecked())
cout << "2 checked!" << endl;
else
cout << "2 unchecked!" << endl;
}
void Menu::Button3Clicked(bool)
{
if (button3->isChecked())
cout << "3 checked!" << endl;
else
cout << "3 unchecked!" << endl;
}
void Menu::GetMeshData(MObject object)
{
// In here, we retrieve triangulated polygons from the mesh
MFnMesh mesh(object);
map<UINT, vector<UINT>> vertexToIndex;
vector<VertexLayout> verticesData;
vector<UINT>indexArray;
MIntArray intdexOffsetVertexCount, vertices, triangleList;
MPointArray dummy;
UINT vertexIndex;
MVector normal;
MPoint pos;
float2 UV;
VertexLayout thisVertex;
for (MItMeshPolygon meshPolyIter(object); !meshPolyIter.isDone(); meshPolyIter.next())
{
vector<UINT> localVertexToGlobalIndex;
meshPolyIter.getVertices(vertices);
meshPolyIter.getTriangles(dummy, triangleList);
UINT indexOffset = verticesData.size();
for (UINT i = 0; i < vertices.length(); i++)
{
vertexIndex = meshPolyIter.vertexIndex(i);
pos = meshPolyIter.point(i);
pos.get(thisVertex.pos);
meshPolyIter.getNormal(i, normal);
thisVertex.normal[0] = normal[0];
thisVertex.normal[1] = normal[1];
thisVertex.normal[2] = normal[2];
meshPolyIter.getUV(i, UV);
thisVertex.uv[0] = UV[0];
thisVertex.uv[1] = UV[1];
verticesData.push_back(thisVertex);
localVertexToGlobalIndex.push_back(vertexIndex);
cout << "Pos: " << thisVertex.pos[0] << "/" << thisVertex.pos[1] << "/" << thisVertex.pos[2] << endl;
cout << "Normals: " << thisVertex.normal[0] << "/" << thisVertex.normal[1] << "/" << thisVertex.normal[2] << endl;
cout << "UV: " << thisVertex.uv[0] << "/" << thisVertex.uv[1] << endl;
}
for (UINT i = 0; i < triangleList.length(); i++)
{
UINT k = 0;
while (localVertexToGlobalIndex[k] != triangleList[i])
k++;
indexArray.push_back(indexOffset + k);
}
}
}
void Menu::exportMaterial(MObject object)
{
MItDependencyNodes matIt(MFn::kLambert);
} }
Menu::~Menu() Menu::~Menu()
@@ -235,5 +212,8 @@ Menu::~Menu()
//delete browseButton; //delete browseButton;
//delete exportPath; //delete exportPath;
//delete fileDialog; //delete fileDialog;
fileDialog->~QFileDialog(); m_FileDialog->~QFileDialog();
//delete m_Export;
//delete MaterialHandler;
} }
+26 -28
View File
@@ -1,10 +1,9 @@
#ifndef BUTTONS_H #ifndef Menu_Menu_h__
#define BUTTONS_H #define Menu_Menu_h__
#include <map> #include <map>
#include <vector> #include <vector>
#include "MayaIncludes.h"
// Qt // Qt
#pragma comment(lib, "QtCore4") #pragma comment(lib, "QtCore4")
#pragma comment(lib, "QtGui4") #pragma comment(lib, "QtGui4")
@@ -30,13 +29,11 @@
#include <QtGui/qfiledialog.h> #include <QtGui/qfiledialog.h>
#include <QtGui/qlineedit.h> #include <QtGui/qlineedit.h>
#include <QtGui/qgroupbox.h> #include <QtGui/qgroupbox.h>
#include <QtGui/qlayoutitem.h>
#include <QtGui/qtabwidget.h>
struct VertexLayout #include "MayaIncludes.h"
{ #include "Export.h"
float pos[3];
float normal[3];
float uv[2];
};
class Menu : public QWidget class Menu : public QWidget
{ {
@@ -45,35 +42,36 @@ public:
Menu(QDialog* dialog); Menu(QDialog* dialog);
~Menu(); ~Menu();
void GetMeshData(MObject object);
void exportMaterial(MObject object);
private slots: private slots:
void ExportSelected(bool checked);
void ExportPathClicked(bool); void ExportPathClicked(bool);
void AddClipClicked(bool);
void RemoveClipClicked(bool);
void ExportAll(bool); void ExportAll(bool);
void CancelClicked(bool); void CancelClicked(bool);
void Button1Clicked(bool);
void Button2Clicked(bool);
void Button3Clicked(bool);
private: private:
Menu(); Menu();
QPushButton* exportSelectedButton; std::vector<QLineEdit*> m_AnimationClipName;
QPushButton* browseButton; std:: vector<QLineEdit*> m_StartFrameLines;
QPushButton* exportAllButton; std::vector<QLineEdit*> m_EndFrameLines;
QPushButton* cancelButton; std::vector<QHBoxLayout*> layouts;
QVBoxLayout* m_ClipLayout;
QCheckBox* exportAnimationsButton; QPushButton* m_BrowseButton = nullptr;
QCheckBox* copyTexturesButton; QPushButton* m_ExportAllButton = nullptr;
QCheckBox* button3; QPushButton* m_CancelButton = nullptr;
QPushButton* m_AddClipsButton = nullptr;
QPushButton* m_RemoveClipsButton = nullptr;
QLineEdit* exportPath; QCheckBox* m_ExportSelectedButton = nullptr;
QFileDialog* fileDialog; QCheckBox* m_ExportAnimationsButton = nullptr;
QDialog* dialogPointer; QCheckBox* m_ExportMaterialButton = nullptr;
QLineEdit* m_ExportPath = nullptr;
QFileDialog* m_FileDialog = nullptr;
QDialog* m_DialogPointer = nullptr;
Export m_Export;
}; };
#endif #endif
+402
View File
@@ -0,0 +1,402 @@
#pragma once
#include "Mesh.h"
using namespace std;
MeshClass::MeshClass()
{
}
std::map<int, MeshClass::WeightInfo> MeshClass::GetWeightData()
{
MS status;
map<int, WeightInfo> weightMap;
MItDependencyNodes it(MFn::kSkinClusterFilter);
while (!it.isDone()) {
MObject object = it.thisNode(&status);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + " it.thisNode() ERROR: " + status.errorString());
break;
}
MFnSkinCluster skinCluster(object, &status);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "skinCluster() ERROR: " + status.errorString());
break;
}
MDagPathArray influences;
unsigned int nrOfInfluences = skinCluster.influenceObjects(influences,&status);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "skinCluster.influenceObjects() ERROR: " + status.errorString());
break;
}
unsigned int index;
index = skinCluster.indexForOutputConnection(0,&status);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "skinCluster.indexForOutputConnection() ERROR: " + status.errorString());
break;
}
MDagPath skinPath;
status = skinCluster.getPathAtIndex(index, skinPath);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "skinCluster.getPathAtIndex() ERROR: " + status.errorString());
break;
}
MItGeometry geomIter(skinPath);
//for (unsigned int i = 0; i < nrOfInfluences; i++) {
// MGlobal::displayInfo(MString() + " Influence object name: " + influences[i].partialPathName().asChar());
//}
WeightInfo weightInfo;
while (!geomIter.isDone()) {
MObject comp = geomIter.component(&status);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "geomIter.component() ERROR: " + status.errorString());
break;
}
MFloatArray weights;
unsigned int influenceCount;
status = skinCluster.getWeights(skinPath, comp, weights, influenceCount);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "skinCluster.getWeights() ERROR: " + status.errorString());
break;
}
MFnDependencyNode test(comp);
unsigned int nrOfWeights = 0;
for (unsigned int j = 0; j < weights.length() && nrOfWeights != 4; j++) {
if (weights[j] > 0.00001) {
weightInfo.BoneWeights[nrOfWeights] = weights[j];
weightInfo.BoneIndices[nrOfWeights] = j;
nrOfWeights++;
}
}
float totalWeight = 0.0f;
for (unsigned int i = 0; i < 4; i++) {
totalWeight += weightInfo.BoneWeights[i];
}
for (unsigned int i = 0; i < 4; i++) {
weightInfo.BoneWeights[i] /= totalWeight;
}
weightMap[geomIter.index()] = weightInfo;
for (unsigned int k = 0; k!=nrOfWeights; k++) {
MGlobal::displayInfo(MString() + "influence: " + weightInfo.BoneIndices[k] + " weight: " + weightInfo.BoneWeights[k]);
}
geomIter.next();
}
it.next();
}
return weightMap;
}
Mesh MeshClass::GetMeshData(MObjectArray object)
{
MS status;
Mesh newMesh;
vector<VertexLayout>& vertexList = newMesh.Vertices;
map<string, vector<int>>& indexLists = newMesh.Indices;
for (int ObjectID = 0; ObjectID < object.length(); ObjectID++) {
if (!object[ObjectID].hasFn(MFn::kMesh))
continue;
MObject node = object[ObjectID];
MFnDependencyNode thisNode(node);
MPlugArray connections;
thisNode.findPlug("inMesh").connectedTo(connections, true, true);
MGlobal::displayInfo(MString() + "inMesh");
bool hasSkin = false;
MPlug weightList, weights;
MObject weightListObject;
for (unsigned int i = 0; i < connections.length(); i++) {
if (connections[i].node().apiType() == MFn::kSkinClusterFilter) {
MFnSkinCluster skinCluster(connections[i].node());
weightList = skinCluster.findPlug("weightList", &status);
weightListObject = weightList.attribute();
weights = skinCluster.findPlug("weights");
hasSkin = true;
break;
}
}
// In here, we retrieve triangulated polygons from the mesh
MFnMesh mesh(object[ObjectID]);
MDagPathArray dagPaths;
status = MDagPath::getAllPathsTo(object[ObjectID], dagPaths);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "MDagPath::getAllPathsTo() ERROR: " + status.errorString());
break;
}
for (int pathID = 0; pathID < dagPaths.length(); pathID++) {
MGlobal::displayInfo(dagPaths[pathID].fullPathName());
MDagPath thisMeshPath(dagPaths[pathID]);
MMatrix transformMatrix = thisMeshPath.inclusiveMatrix(&status);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "thisMeshPath.inclusiveMatrix() ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName());
break;
}
map<unsigned int, vector<unsigned int>> vertexToIndex;;
MIntArray intdexOffsetVertexCount, vertices, triangleList;
MPointArray dummy;
unsigned int vertexIndex;
MVector normal;
MPoint pos;
float2 UV;
double biTangent[3];
double biNormal[3];
MFloatVectorArray Tangents;
MFloatVectorArray biNormals;
MObjectArray shaderList;
MIntArray shaderIndexList;
status = mesh.getConnectedShaders(0, shaderList, shaderIndexList);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "mesh.getConnectedShaders() ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName());
break;
}
if (shaderList.length() == 0) {
MGlobal::displayError(MString() + "Object: \"" + thisMeshPath.fullPathName() + "\" have no material and will not be exported");
break;
}
map<string, vector<int>> materialFaceIDs;
MGlobal::displayInfo(MString() + "shaderIndexList: " + shaderIndexList.length());
MGlobal::displayInfo(MString() + "shaderList: " + shaderList.length());
MPlugArray plugArray;
for (int i = 0; i < shaderIndexList.length(); i++) {
MFnDependencyNode shader(shaderList[shaderIndexList[i]]);
MPlug p_Plug = shader.findPlug("surfaceShader", status);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "shader.findPlug(\"surfaceShader\") ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName());
continue;
}
if (p_Plug.connectedTo(plugArray, true, false, &status)) {
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "p_Plug.connectedTo() ERROR in if: " + status.errorString() + " for " + thisMeshPath.fullPathName());
continue;
}
MFnDependencyNode node = plugArray[0].node();
materialFaceIDs[node.name().asChar()].push_back(i);
}
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "p_Plug.connectedTo() ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName());
continue;
}
}
// map<int, WeightInfo> vertexWeights = GetWeightData();
status = mesh.getTangents(Tangents, MSpace::kObject);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "mesh.getTangents ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName());
continue;
}
status = mesh.getBinormals(biNormals, MSpace::kObject);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "mesh.getBinormals ERROR: " + status.errorString() + " for " + thisMeshPath.fullPathName());
continue;
}
if(Tangents.length() == 0 || biNormals.length() == 0){
MGlobal::displayError(MString() + "Unknown ERROR with " + thisMeshPath.fullPathName());
continue;
}
MItMeshFaceVertex faceVert(object[ObjectID]);
int intDummy = 0;
MItMeshPolygon meshPolyIter(object[ObjectID]);
MFloatPointArray positions;
mesh.getPoints(positions);
for (auto aMaterial : materialFaceIDs) {
for (auto faceID : aMaterial.second) {
vector<array<unsigned int, 2>> localVertexToGlobalIndex;
status = meshPolyIter.setIndex(faceID, intDummy);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + " meshPolyIter.setIndex() ERROR: " + status.errorString() + " for faceID " + faceID + " in mesh " + thisMeshPath.fullPathName());
break;
}
status = meshPolyIter.getVertices(vertices);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + " meshPolyIter.getVertices() ERROR: " + status.errorString() + " for faceID " + faceID + " in mesh " + thisMeshPath.fullPathName());
break;
}
status = meshPolyIter.getTriangles(dummy, triangleList);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + " meshPolyIter.getTriangles() ERROR: " + status.errorString() + " for faceID " + faceID + " in mesh " + thisMeshPath.fullPathName());
break;
}
//MGlobal::displayInfo("Befor Second Loop");
for (unsigned int i = 0; i < vertices.length(); i++) {
VertexLayout thisVertex;
vertexIndex = meshPolyIter.vertexIndex(i, &status);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + " meshPolyIter.vertexIndex() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName());
break;
}
status = faceVert.setIndex(meshPolyIter.index(), i, intDummy, intDummy);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "faceVert.setIndex() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName());
break;
}
//MGlobal::displayInfo("In Second Loop");
//pos = faceVert.position(MSpace::kTransform);
//mesh.getPoint(vertexIndex, pos, MSpace::kPostTransform);
pos = positions[vertexIndex];
pos = pos * transformMatrix;
if (abs(pos.x) > 0.0001)
thisVertex.Pos[0] = pos.x;
if (abs(pos.y) > 0.0001)
thisVertex.Pos[1] = pos.y;
if (abs(pos.z) > 0.0001)
thisVertex.Pos[2] = pos.z;
status = faceVert.getNormal(normal, MSpace::kObject);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "faceVert.getNormal() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName());
break;
}
if (abs(normal[0]) > 0.0001)
thisVertex.Normal[0] = normal[0];
if (abs(normal[1]) > 0.0001)
thisVertex.Normal[1] = normal[1];
if (abs(normal[2]) > 0.0001)
thisVertex.Normal[2] = normal[2];
MFloatVector Tangent = Tangents[faceVert.tangentId()];
//MVector tmp = faceVert.getTangent(MSpace::kObject, NULL);
//tmp.get(biTangent);
if (abs(Tangent[0]) > 0.0001)
thisVertex.Tangent[0] = Tangent[0];
if (abs(Tangent[1]) > 0.0001)
thisVertex.Tangent[1] = Tangent[1];
if (abs(Tangent[2]) > 0.0001)
thisVertex.Tangent[2] = Tangent[2];
MFloatVector biNormal = biNormals[faceVert.tangentId()];
//faceVert.getBinormal().get(biNormal);
if (abs(biNormal[0]) > 0.0001)
thisVertex.BiNormal[0] = biNormal[0];
if (abs(biNormal[1]) > 0.0001)
thisVertex.BiNormal[1] = biNormal[1];
if (abs(biNormal[2]) > 0.0001)
thisVertex.BiNormal[2] = biNormal[2];
status = faceVert.getUV(UV);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + " faceVert.getUV() ERROR: " + status.errorString() + "for local vertex " + i + " in " + faceID + " in mesh " + thisMeshPath.fullPathName());
break;
}
thisVertex.Uv[0] = UV[0];
thisVertex.Uv[1] = UV[1];
if (hasSkin) {
float totalWeight = 0.0f;
unsigned int totalBones = 0;
MIntArray jointIDs /* ??? */;
weights.selectAncestorLogicalIndex(vertexIndex, weightListObject);
weights.getExistingArrayAttributeIndices(jointIDs);
for (unsigned int i = 0; i < jointIDs.length() && i < 4; i++) {
if (weights[i].asFloat() > 0.001f) {
thisVertex.BoneIndices[totalBones] = jointIDs[i];
thisVertex.BoneWeights[totalBones] = weights[i].asFloat();
totalWeight = totalWeight + weights[i].asFloat();
totalBones++;
}
}
for (unsigned int i = 0; i < 4; i++) {
thisVertex.BoneWeights[i] = thisVertex.BoneWeights[i] / totalWeight;
}
}
//float totalWeight = thisVertex.BoneWeights[0] + thisVertex.BoneWeights[1] + thisVertex.BoneWeights[2] + thisVertex.BoneWeights[3];
//if (totalWeight > 0.0001f) {
// thisVertex.BoneWeights[0] /= totalWeight;
// thisVertex.BoneWeights[1] /= totalWeight;
// thisVertex.BoneWeights[2] /= totalWeight;
// thisVertex.BoneWeights[3] /= totalWeight;
//}
std::vector<VertexLayout>::iterator it = std::find(vertexList.begin(), vertexList.end(), thisVertex);
array<unsigned int, 2> tmp;
if (it != vertexList.end()) {
tmp[0] = vertexIndex;
tmp[1] = it - vertexList.begin();
localVertexToGlobalIndex.push_back(tmp);
} else {
tmp[0] = vertexIndex;
tmp[1] = vertexList.size();
localVertexToGlobalIndex.push_back(tmp);
vertexList.push_back(thisVertex);
}
//MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1]: " + localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1][0] + " " + localVertexToGlobalIndex[localVertexToGlobalIndex.size()-1][1]);
//cout << "Pos: " << thisVertex.Pos[0] << "/" << thisVertex.Pos[1] << "/" << thisVertex.Pos[2] << endl;
//cout << "Normals: " << thisVertex.Normal[0] << "/" << thisVertex.Normal[1] << "/" << thisVertex.Normal[2] << endl;
//cout << "Bi-Normals: " << thisVertex.BiNormal[0] << "/" << thisVertex.BiNormal[1] << "/" << thisVertex.BiNormal[2] << endl;
//cout << "Bi-Tangents: " << thisVertex.BiTangent[0] << "/" << thisVertex.BiTangent[1] << "/" << thisVertex.BiTangent[2] << endl;
//cout << "UV: " << thisVertex.Uv[0] << "/" << thisVertex.Uv[1] << endl;
}
for (unsigned int i = 0; i < triangleList.length(); i++) {
unsigned int k = 0;
if (localVertexToGlobalIndex.size() > 0) {
//MGlobal::displayInfo(MString() + "triangleList[i] : " + triangleList[i]);
while (localVertexToGlobalIndex[k][0] != triangleList[i] && k < localVertexToGlobalIndex.size()) {
k++;
}
//MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[k] : " + localVertexToGlobalIndex[k][0] + " " + localVertexToGlobalIndex[k][1]);
indexLists[aMaterial.first.c_str()].push_back(localVertexToGlobalIndex[k][1]);
}
}
}
// MGlobal::displayInfo( MString() + "localVertexToGlobalIndex.size(): " + localVertexToGlobalIndex.size());
// if (localVertexToGlobalIndex.size() > 0) {
// MGlobal::displayInfo(MString() + "triangleList.length(): " + triangleList.length());
// for (unsigned int i = triangleList.length() - 1; i >= 0; i--) {
// MGlobal::displayInfo(MString() + "i: " + i);
// unsigned int k = localVertexToGlobalIndex.size() - 1;
// MGlobal::displayInfo(MString() + "triangleList[i] : " + triangleList[i]);
// while (localVertexToGlobalIndex[k] != triangleList[i] && k >= 0) {
// MGlobal::displayInfo(MString() + "k: " + k);
// k--;
// }
// MGlobal::displayInfo(MString() + "localVertexToGlobalIndex[k] : " + localVertexToGlobalIndex[k]);
// indexList.push_back(indexOffset + k);
// }
// }
}
}
}
int totalIndices = 0;
for (auto aList : newMesh.Indices) {
totalIndices += aList.second.size();
}
newMesh.NumIndices = totalIndices;
newMesh.NumVertices = newMesh.Vertices.size();
return newMesh;
}
MeshClass::~MeshClass()
{
}
+117
View File
@@ -0,0 +1,117 @@
#ifndef Mesh_Mesh_h__
#define Mesh_Mesh_h__
#include <map>
#include <vector>
#include <array>
#include "OutputData.h"
#include "MayaIncludes.h"
class VertexLayout : public OutputData
{
public:
float Pos[3]{ 0 };
float Normal[3]{ 0 };
float Tangent[3]{ 0 };
float BiNormal[3]{ 0 };
float Uv[2]{ 0 };
float BoneIndices[4]{ 0 };
float BoneWeights[4]{ 0 };
virtual void WriteBinary(std::ostream& out)
{
out.write((char*)&Pos, sizeof(float) * 3);
out.write((char*)&Normal, sizeof(float) * 3);
out.write((char*)&Tangent, sizeof(float) * 3);
out.write((char*)&BiNormal, sizeof(float) * 3);
out.write((char*)&Uv, sizeof(float) * 2);
out.write((char*)&BoneIndices, sizeof(float) * 4);
out.write((char*)&BoneWeights, sizeof(float) * 4);
}
virtual void WriteASCII(std::ostream& out) const
{
out << Pos[0] << " " << Pos[1] << " " << Pos[2] << endl;
out << Normal[0] << " " << Normal[1] << " " << Normal[2] << endl;
out << Tangent[0] << " " << Tangent[1] << " " << Tangent[2] << endl;
out << BiNormal[0] << " " << BiNormal[1] << " " << BiNormal[2] << endl;
out << Uv[0] << " " << Uv[1] << endl;
out << BoneIndices[0] << " " << BoneIndices[1] << " " << BoneIndices[2] << " " << BoneIndices[3] << endl;
out << BoneWeights[0] << " " << BoneWeights[1] << " " << BoneWeights[2] << " " << BoneWeights[3] << endl;
}
bool operator==(const VertexLayout& right)
{
return
this->Pos[0] == right.Pos[0] && this->Pos[1] == right.Pos[1] && this->Pos[2] == right.Pos[2] &&
this->Normal[0] == right.Normal[0] && this->Normal[1] == right.Normal[1] && this->Normal[2] == right.Normal[2] &&
this->Tangent[0] == right.Tangent[0] && this->Tangent[1] == right.Tangent[1] && this->Tangent[2] == right.Tangent[2] &&
this->BiNormal[0] == right.BiNormal[0] && this->BiNormal[1] == right.BiNormal[1] && this->BiNormal[2] == right.BiNormal[2] &&
this->Uv[0] == right.Uv[0] && this->Uv[1] == right.Uv[1] &&
this->BoneIndices[0] == right.BoneIndices[0] && this->BoneIndices[1] == right.BoneIndices[1] && this->BoneIndices[2] == right.BoneIndices[2] && this->BoneIndices[3] == right.BoneIndices[3] &&
this->BoneWeights[0] == right.BoneWeights[0] && this->BoneWeights[1] == right.BoneWeights[1] && this->BoneWeights[2] == right.BoneWeights[2] && this->BoneWeights[3] == right.BoneWeights[3]
;
}
};
class Mesh : public OutputData {
public:
unsigned int NumVertices;
unsigned int NumIndices;
std::vector<VertexLayout> Vertices;
std::map<std::string, std::vector<int>> Indices;
virtual void WriteBinary(std::ostream& out)
{
out.write((char*)&NumVertices, sizeof(int));
out.write((char*)&NumIndices, sizeof(int));
for (auto aVertex : Vertices) {
aVertex.WriteBinary(out);
}
for (auto aIndex : Indices) {
//for (std::map<std::string, std::vector<int>>::reverse_iterator aIndex = Indices.rbegin(); aIndex != Indices.rend(); aIndex++){
//out.write((char*)(*aIndex).second.data(), sizeof(int) * (*aIndex).second.size());
out.write((char*)aIndex.second.data(), sizeof(int) * aIndex.second.size());
}
}
virtual void WriteASCII(std::ostream& out) const
{
out << "New Mesh _ not in binary" << endl;
out << "Number of vertices: " << NumVertices << endl;
out << "number of indices: " << NumIndices << endl;
int vertexNumber = 0;
for (auto aVertex : Vertices) {
out << "New vertex number: " << vertexNumber << " _ not in binary" << endl;
aVertex.WriteASCII(out);
vertexNumber++;
}
out << "New vertex Triangels: " << NumIndices/3 << " _ not in binary" << endl;
for (auto aIndexList : Indices) {
out << "Using Material: " << aIndexList.first << " _ not in binary" << endl;
for (int i = 0; i < aIndexList.second.size(); i += 3) {
out << aIndexList.second[i] << " " << aIndexList.second[i+1] << " " << aIndexList.second[i + 2] << endl;
}
}
}
};
class MeshClass
{
public:
MeshClass();
Mesh GetMeshData(MObjectArray Object);
~MeshClass();
private:
struct WeightInfo {
float BoneIndices[4] = { 0 };
float BoneWeights[4] = { 0 };
};
std::map<int, WeightInfo> GetWeightData();
};
#endif
@@ -0,0 +1,23 @@
#ifndef OutputData_OutputData_h__
#define OutputData_OutputData_h__
#include <fstream>
//template <typename T>
class OutputData
{
public://std::ostream& out, const OutputData& obj
//OutputData(T& object)
// : m_Object(object)
//{};
friend std::ostream& operator<<(std::ostream& out, const OutputData& obj)
{
obj.WriteASCII(out);
return out;
};
virtual void WriteBinary(std::ostream& out) = 0;
virtual void WriteASCII(std::ostream& out) const = 0;
//T& m_Object = nullptr;
};
#endif
@@ -0,0 +1,342 @@
#include "Skeleton.h"
//std::vector<SkeletonNode> Skeleton::DoIt()
//{
// std::vector<SkeletonNode> m_AllSkeletons;
//
// MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint);
// SkeletonNode SkeletonStorage;
//
// while (!jointIt.isDone()) {
// MFnTransform TransformNode(jointIt.currentItem());
// Joint NewJoint;
//
// if (MFnDependencyNode(TransformNode.parent(0)).name() == "world") {
// if (SkeletonStorage.Joints.size() != 0) {
// m_AllSkeletons.push_back(SkeletonStorage);
//
// SkeletonStorage.Joints.clear();
// SkeletonStorage.Name.clear();
// }
//
// SkeletonStorage.Name = TransformNode.name().asChar();
//
// //NewJoint.ParentIndex = -1; // This joint is root
// }
//
// //NewJoint.Name = TransformNode.name().asChar();
//
// MMatrix Matrix = TransformNode.transformationMatrix();
//
// //double tmp[3];
// //((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp);
// //NewJoint.Rotation[0] = tmp[0];
// //NewJoint.Rotation[1] = tmp[1];
// //NewJoint.Rotation[2] = tmp[2];
// //((MTransformationMatrix)Matrix).getScale(tmp, MSpace::Space::kTransform);
// //NewJoint.Scale[0] = tmp[0];
// //NewJoint.Scale[1] = tmp[1];
// //NewJoint.Scale[2] = tmp[2];
// //((MTransformationMatrix)Matrix).getTranslation(MSpace::Space::kTransform).get(tmp);
// //NewJoint.Translation[0] = tmp[0];
// //NewJoint.Translation[1] = tmp[1];
// //NewJoint.Translation[2] = tmp[2];
//
// for (int i = 0; i < 4; i++) {
// for (int j = 0; j < 4; j++) {
// NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j];
// }
// }
//
// SkeletonStorage.Joints.push_back(NewJoint);
//
// jointIt.next();
// }
//
// m_AllSkeletons.push_back(SkeletonStorage);
//
// return m_AllSkeletons;
//}
std::string attr[9] = { "scaleX", "scaleY", "scaleZ", "translateX", "translateY", "translateZ", "rotateX", "rotateY", "rotateZ" };
Animation Skeleton::GetAnimData(std::string animationName, int startFrame, int endFrame)
{
MStatus status;
std::vector<MObject> animatedJoints;
std::vector<MObject> m_Hierarchy;
Animation returnData;
double oneDivSixty = 1 / 60.0;
returnData.Name = animationName;
returnData.nameLength = animationName.size() + 1;
returnData.Duration = (endFrame - startFrame) * oneDivSixty;
MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint);
while (!jointIt.isDone())
{
m_Hierarchy.push_back(jointIt.item());
MFnDependencyNode depNode(jointIt.item());
for (int i = 0; i < 9; i++)
{
MStatus tmp;
MPlug plug = depNode.findPlug(attr[i].c_str(), &tmp);
MPlugArray connections;
plug.connectedTo(connections, true, false, 0);
for (int j = 0; j != connections.length(); j++) {
MObject connected = connections[j].node();
if (connected.hasFn(MFn::kAnimCurve)) {
MFnAnimCurve jointAnim(connected);
unsigned int startKeyFrameIndex = jointAnim.findClosest(MTime(startFrame, MTime::kNTSCField), &tmp);
if (tmp == MStatus::kFailure)
MGlobal::displayInfo(MString() + "Fail :c");
if (startFrame * oneDivSixty <= jointAnim.time(startKeyFrameIndex).value() && jointAnim.time(startKeyFrameIndex).value() <= endFrame * oneDivSixty) {
animatedJoints.push_back(jointIt.item());
i = 9;
break;
}
unsigned int endKeyFrameIndex = jointAnim.findClosest(MTime(endFrame, MTime::kNTSCField));
MGlobal::displayInfo(MString() + startKeyFrameIndex + " " + endKeyFrameIndex);
if (startFrame * oneDivSixty <= jointAnim.time(endKeyFrameIndex).value() && jointAnim.time(endKeyFrameIndex).value() <= endFrame * oneDivSixty || endKeyFrameIndex - startKeyFrameIndex > 0) {
animatedJoints.push_back(jointIt.item());
i = 9;
break;
}
MFnTransform MayaJoint(jointIt.item());
MPlug BindPose = MayaJoint.findPlug("bindPose");
MDataHandle DataHandle;
BindPose.getValue(DataHandle);
MFnMatrixData MartixFn(DataHandle.data());
MMatrix BindPoseMatrix = MartixFn.matrix();
if (!BindPoseMatrix.isEquivalent(MayaJoint.transformationMatrix()))
{
MGlobal::displayError(MString() + animationName.c_str() + " is using " + MayaJoint.name() + " that is not in bind pose nor is it key framed in the animation, the exported animation will NOT correspond to the animation in Maya");
}
}
}
}
jointIt.next();
}
int currentFrame = startFrame;
while (currentFrame != endFrame + 1) { // ANDREAS
Animation::Keyframe thisKeyFrame;
thisKeyFrame.Index = currentFrame - startFrame;
thisKeyFrame.Time = thisKeyFrame.Index * oneDivSixty;
MAnimControl::setCurrentTime(MTime(currentFrame, MTime::kNTSCField));
MTime time = MAnimControl::currentTime();
for (auto aJoint : animatedJoints){
MFnTransform thisJoint(aJoint);
Animation::Keyframe::JointProperty joint;
auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), thisJoint.object());
if (it != m_Hierarchy.end()) {
joint.ID = it - m_Hierarchy.begin();
}
else {
MGlobal::displayError(MString() + "Could not find joint ID for: " + thisJoint.name());
}
MTransformationMatrix Matrix = thisJoint.transformation();
MPlug BindPose = thisJoint.findPlug("bindPose");
MDataHandle DataHandle;
BindPose.getValue(DataHandle);
MFnMatrixData MartixFn(DataHandle.data());
MMatrix BindPoseMatrix = MartixFn.matrix();
Matrix = Matrix.asMatrix();
MObject jointOrientObj = thisJoint.attribute("jointOrient");
MFnNumericAttribute jointOrient(jointOrientObj);
double jointOrientDouble[3];
jointOrient.getDefault(jointOrientDouble[0], jointOrientDouble[1], jointOrientDouble[2]);
//MGlobal::displayError(MString() + "Joint Matrix: ");
//MGlobal::displayError(MString() + Matrix.asMatrix()[0][0] + " " + Matrix.asMatrix()[0][1] + " " + Matrix.asMatrix()[0][2] + " " + Matrix.asMatrix()[0][3]);
//MGlobal::displayError(MString() + Matrix.asMatrix()[1][0] + " " + Matrix.asMatrix()[1][1] + " " + Matrix.asMatrix()[1][2] + " " + Matrix.asMatrix()[1][3]);
//MGlobal::displayError(MString() + Matrix.asMatrix()[2][0] + " " + Matrix.asMatrix()[2][1] + " " + Matrix.asMatrix()[2][2] + " " + Matrix.asMatrix()[2][3]);
//MGlobal::displayError(MString() + Matrix.asMatrix()[3][0] + " " + Matrix.asMatrix()[3][1] + " " + Matrix.asMatrix()[3][2] + " " + Matrix.asMatrix()[3][3]);
MEulerRotation joEuler(jointOrientDouble[0], jointOrientDouble[1], jointOrientDouble[2]);
MQuaternion jo = joEuler.asQuaternion();
double tmp[4];
Matrix.getRotationQuaternion(tmp[0], tmp[1], tmp[2], tmp[3]);
MQuaternion rotation(tmp);
rotation = rotation * jo;
rotation.get(tmp);
joint.Rotation[0] = tmp[0];
joint.Rotation[1] = tmp[1];
joint.Rotation[2] = tmp[2];
joint.Rotation[3] = tmp[3];
Matrix.getTranslation(MSpace::kTransform).get(tmp);
joint.Position[0] = tmp[0];
joint.Position[1] = tmp[1];
joint.Position[2] = tmp[2];
Matrix.getScale(tmp, MSpace::kTransform);
joint.Scale[0] = tmp[0];
joint.Scale[1] = tmp[1];
joint.Scale[2] = tmp[2];
thisKeyFrame.JointProperties.push_back(joint);
}
returnData.Keyframes.push_back(thisKeyFrame);
currentFrame++;
}
returnData.NumKeyFrames = returnData.Keyframes.size();
returnData.NumberOfJoints = animatedJoints.size();
return returnData;
}
std::vector<BindPoseSkeletonNode> Skeleton::GetBindPoses()
{
MStatus status;
std::vector<BindPoseSkeletonNode> m_AllSkeletons;
std::vector<MObject> m_Hierarchy;
MItDag jointIt(MItDag::TraversalType::kDepthFirst, MFn::kJoint);
BindPoseSkeletonNode SkeletonStorage;
while (!jointIt.isDone()) {
MFnTransform MayaJoint(jointIt.currentItem());
BindPoseSkeletonNode::BindPoseJoint NewJoint;
if (MFnDependencyNode(MayaJoint.parent(0)).name() == "world") {
if (SkeletonStorage.Joints.size() != 0) {
m_AllSkeletons.push_back(SkeletonStorage);
SkeletonStorage.Joints.clear();
SkeletonStorage.Name.clear();
}
SkeletonStorage.Name = std::string(MayaJoint.name().asChar());
NewJoint.ParentID = -1; // This joint is root
}
else {
auto it = std::find(m_Hierarchy.begin(), m_Hierarchy.end(), MayaJoint.parent(0));
if (it != m_Hierarchy.end()) {
NewJoint.ParentID = it - m_Hierarchy.begin();
}
else {
MGlobal::displayError(MString() + "Could not find joint parent for: " + MayaJoint.name());
}
}
m_Hierarchy.push_back(MayaJoint.object());
MPlug BindPose = MayaJoint.findPlug("bindPose", &status);
if (status != MS::kSuccess) {
MGlobal::displayError(MString() + "Could not find bindPose plug: " + status.errorString());
}
MDataHandle DataHandle;
BindPose.getValue(DataHandle);
MFnMatrixData MartixFn(DataHandle.data());
MMatrix Matrix = MartixFn.matrix();
MVector tmp = MayaJoint.transformation().getTranslation(MSpace::kObject);
MGlobal::displayError(MString() + "translation befor: " + tmp[0] + " " + tmp[1] + " " + tmp[2]);
//Matrix[3][0] *= -1;
//Matrix[3][2] *= -1;
//Matrix[3][1] *= -1;
double test[3];
MayaJoint.transformation().getScale(test, MSpace::kObject);
MGlobal::displayError(MString() + "scale: " + test[0] + " " + test[1] + " " + test[2]);
MTransformationMatrix::RotationOrder order = MTransformationMatrix::RotationOrder::kXYZ;
MayaJoint.transformation().getRotation(test, order);
MGlobal::displayError(MString() + "rotation: " + test[0] + " " + test[1] + " " + test[2]);
//----- test
//MDataHandle DataHandle;
//MObject jointObject(jointIt.currentItem());
//MFnDependencyNode jointDependNode(jointObject);
//MPlug worldMatrixArray(jointObject, jointDependNode.attribute("worldMatrix"));
//MMatrix Matrix;
//for (int i = 0; i < worldMatrixArray.numElements(); i++) {
// MPlugArray connections;
// MPlug element = worldMatrixArray[i];
// unsigned int logicalIndex = element.logicalIndex();
// MItDependencyGraph it(element, MFn::kSkinClusterFilter);
// for (; !it.isDone(); it.next()) {
// MFnSkinCluster skinCluster(it.thisNode());
// MPlug bindPreMatrixArrayPlug =
// skinCluster.findPlug("bindPreMatrix", &status);
// if (status != MS::kSuccess) {
// MGlobal::displayError(MString() + "Could not find bindPreMatrix plug: " + status.errorString());
// break;
// }
// MPlug bindPreMatrixPlug =
// bindPreMatrixArrayPlug.elementByLogicalIndex(logicalIndex);
// MObject dataObject;
// bindPreMatrixPlug.getValue(dataObject);
// MFnMatrixData matDataFn(dataObject);
// MMatrix invMat = matDataFn.matrix();
// Matrix = invMat.inverse();
// }
//}
//----- end test
Matrix = Matrix.inverse();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
NewJoint.OffsetMatrix[i][j] = Matrix.matrix[i][j];
}
}
NewJoint.Name = MayaJoint.name().asChar();
NewJoint.NameLength = MayaJoint.name().length() + 1;
NewJoint.ID = SkeletonStorage.Joints.size();
//double tmp[3];
//((MTransformationMatrix)Matrix).eulerRotation().asVector().get(tmp);
//NewJoint.Rotation[0] = tmp[0];
//NewJoint.Rotation[1] = tmp[1];
//NewJoint.Rotation[2] = tmp[2];
//((MTransformationMatrix)Matrix).getScale(tmp, MSpace::Space::kTransform);
//NewJoint.Scale[0] = tmp[0];
//NewJoint.Scale[1] = tmp[1];
//NewJoint.Scale[2] = tmp[2];
//((MTransformationMatrix)Matrix).getTranslation(MSpace::Space::kTransform).get(tmp);
//NewJoint.Translation[0] = tmp[0];
//NewJoint.Translation[1] = tmp[1];
//NewJoint.Translation[2] = tmp[2];
SkeletonStorage.Joints.push_back(NewJoint);
SkeletonStorage.numBones++;
jointIt.next();
}
m_AllSkeletons.push_back(SkeletonStorage);
return m_AllSkeletons;
}
+129
View File
@@ -0,0 +1,129 @@
#ifndef Skeleton_Skeleton_h__
#define Skeleton_Skeleton_h__
#include <vector>
#include <array>
#include <algorithm>
#include "MayaIncludes.h"
#include "OutputData.h"
class Animation : public OutputData {
public:
struct Keyframe
{
struct JointProperty
{
int ID = 0;
float Position[3]{ 0 };
float Rotation[4]{ 0 };
float Scale[3]{ 0 };
};
int Index = 0;
float Time = 0;
std::vector<JointProperty> JointProperties;
};
std::string Name;
int nameLength = 0;
float Duration = 0;
int NumKeyFrames = 0;
int NumberOfJoints = 0;
std::vector<Keyframe> Keyframes;
virtual void WriteBinary(std::ostream& out)
{
out.write((char*)&nameLength, sizeof(int));
out.write(Name.c_str(), Name.size() + 1);
out.write((char*)&Duration, sizeof(float));
out.write((char*)&NumKeyFrames, sizeof(int));
out.write((char*)&NumberOfJoints, sizeof(int));
//Här under loopas alla key frames igenom
for (auto aKeyframe : Keyframes) {
out.write((char*)&aKeyframe.Index, sizeof(int));
out.write((char*)&aKeyframe.Time, sizeof(float));
for (auto aJoint : aKeyframe.JointProperties) {
out.write((char*)&aJoint.ID, sizeof(int));
out.write((char*)aJoint.Position, sizeof(float) * 3);
out.write((char*)aJoint.Rotation, sizeof(float) * 4);
out.write((char*)aJoint.Scale, sizeof(float) * 3);
}
}
}
virtual void WriteASCII(std::ostream& out) const
{
out << "Animation Name: " << Name << endl;
out << "Duration: " << Duration << endl;
out << "Number of KeyFrames: " << NumKeyFrames << endl;
out << "Number of Joints: " << NumberOfJoints << endl;
for (auto aKeyframe : Keyframes) {
out << "Frame: " << aKeyframe.Index << endl;
out << "Time: " << aKeyframe.Time << endl;
for (auto aJoint : aKeyframe.JointProperties) {
out << "Joint ID: " << aJoint.ID << endl;
out << aJoint.Position[0] << " " << aJoint.Position[1] << " " << aJoint.Position[2] << endl;
out << aJoint.Rotation[0] << " " << aJoint.Rotation[1] << " " << aJoint.Rotation[2] << " " << aJoint.Rotation[3] << endl;
out << aJoint.Scale[0] << " " << aJoint.Scale[1] << " " << aJoint.Scale[2] << endl;
}
}
}
};
class BindPoseSkeletonNode : public OutputData {
public:
struct BindPoseJoint
{
int NameLength;
std::string Name;
float OffsetMatrix[4][4]{ 0 };
int ID = 0;
int ParentID = 0;
};
int numBones = 0;
std::string Name;
std::vector<BindPoseJoint> Joints;
virtual void WriteBinary(std::ostream& out)
{
out.write((char*)&numBones, sizeof(int));
for (auto Joint:Joints)
{
out.write((char*)&Joint.NameLength, sizeof(int));
out.write(Joint.Name.c_str(), Joint.Name.size() + 1);
out.write((char*)&Joint.OffsetMatrix, sizeof(float) * 4 * 4);
out.write((char*)&Joint.ID, sizeof(int));
out.write((char*)&Joint.ParentID, sizeof(int));
}
}
virtual void WriteASCII(std::ostream& out) const
{
out << "Bind Pose: " << Name << " _ not in binary" << endl;
out << "numberOfBones: " << numBones << endl;
for (auto Joint : Joints)
{
out << "Joint NameLength " << Joint.NameLength << endl;
out << "Joint name " << Joint.Name << endl;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++){
out << Joint.OffsetMatrix[i][j] << " ";
}
out << endl;
}
out << Joint.ID << endl;
out << Joint.ParentID << endl;
}
};
};
class Skeleton {
public:
//std::vector<SkeletonNode> DoIt();
Animation GetAnimData(std::string animationName, int startFrame, int endFrame);
std::vector<BindPoseSkeletonNode> GetBindPoses();
private:
};
#endif //Skeleton_Skeleton_h__
@@ -0,0 +1,41 @@
#include "WriteToFile.h"
WriteToFile::~WriteToFile()
{
CloseFiles();
}
bool WriteToFile::binaryFilePath(string filePathAndFileName)
{
binFileName = filePathAndFileName;
ofstream binFile(filePathAndFileName, ofstream::binary);
if (!binFile)
return false;
return true;
}
bool WriteToFile::ASCIIFilePath(string filePathAndFileName)
{
ASCIIFileName = filePathAndFileName;
ofstream ASCIIFile(filePathAndFileName);
if (!ASCIIFile)
return false;
return true;
}
void WriteToFile::OpenFiles()
{
if (binFile) {
binFile.open(binFileName, ofstream::binary);
}
if (ASCIIFile){
ASCIIFile.open(ASCIIFileName);
ASCIIFile << std::fixed << std::setprecision(3);
}
}
void WriteToFile::CloseFiles()
{
binFile.close();
ASCIIFile.close();
}
@@ -0,0 +1,64 @@
#ifndef WriteToFile_WriteToFile_h__
#define WriteToFile_WriteToFile_h__
#include "MayaIncludes.h"
#include "OutputData.h"
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
class WriteToFile
{
public:
~WriteToFile();
bool binaryFilePath(string filePathAndFileName);
bool ASCIIFilePath(string filePathAndFileName);
void writeToFiles(OutputData* toWrite, unsigned int numOfElementToWrite = 1, unsigned int startIndex = 0)
{
MGlobal::displayInfo("WriteToFile::writeToFiles(OutputData*)");
if (ASCIIFile.is_open())
{
for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++)
ASCIIFile << toWrite[i] << endl;
}
if (binFile.is_open())
{
for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++)
toWrite[i].WriteBinary(binFile);
}
}
template <typename T>
void writeToFiles(T* toWrite, unsigned int numOfElementToWrite = 1, unsigned int startIndex = 0)
{
MGlobal::displayInfo("WriteToFile::writeToFiles(T*) - Template T");
if (ASCIIFile.is_open()) {
for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++)
ASCIIFile << toWrite[i] << endl;
}
if (binFile.is_open()) {
for (unsigned int i = startIndex; i < numOfElementToWrite + startIndex; i++)
binFile.write((char*)toWrite, sizeof(T));
}
}
void OpenFiles();
void CloseFiles();
private:
string binFileName;
string ASCIIFileName;
ofstream binFile;
ofstream ASCIIFile;
};
#endif