From f0ad28bac4dbe03a4b13f42f549c77b0e20cc085 Mon Sep 17 00:00:00 2001 From: stiffly Date: Wed, 6 Jan 2016 11:39:32 +0100 Subject: [PATCH 1/7] Removed some comments. Basically did nothing --- include/Engine/Network/Network.h | 1 + src/Engine/Input/InputProxy.cpp | 4 ++-- src/Engine/Network/Client.cpp | 14 +++++--------- src/Engine/Network/Server.cpp | 8 ++++++-- src/Game/Game.cpp | 7 +------ 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 0f7baefe..c5107b2b 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -14,6 +14,7 @@ public: virtual ~Network() { }; virtual void Start(World* m_world, EventBroker *eventBroker) = 0; virtual void Update() = 0; + virtual void Close() = 0; }; #endif \ No newline at end of file diff --git a/src/Engine/Input/InputProxy.cpp b/src/Engine/Input/InputProxy.cpp index c3e4d669..ad589df3 100644 --- a/src/Engine/Input/InputProxy.cpp +++ b/src/Engine/Input/InputProxy.cpp @@ -62,7 +62,7 @@ void InputProxy::Process() e.Command = command; e.Value = currentValue; m_EventBroker->Publish(e); - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + //LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); m_LastCommandValues[command] = currentValue; } } @@ -78,7 +78,7 @@ void InputProxy::Process() } //e.Value = std::max(-1.f, std::min(e.Value, 1.f)); m_EventBroker->Publish(e); - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + //LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); } m_CommandQueue.clear(); } diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 5c7e9c8f..a417c4e5 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -17,7 +17,7 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) Client::~Client() { - + m_EventBroker->Unsubscribe(m_EInputCommand); } void Client::Start(World* world, EventBroker* eventBroker) @@ -27,14 +27,10 @@ void Client::Start(World* world, EventBroker* eventBroker) m_World = world; // Subscribe to events - m_EInputCommand = decltype(m_EInputCommand)(std::bind(&Client::OnInputCommand, this, std::placeholders::_1)); - m_EventBroker->Subscribe(m_EInputCommand); + //m_EInputCommand = decltype(m_EInputCommand)(std::bind(&Client::OnInputCommand, this, std::placeholders::_1)); + //m_EventBroker->Subscribe(m_EInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand); - - //while (m_PlayerName.size() > 7) { - // LOG_INFO("Please enter your name (No longer than 7 characters):"); - // std::cin >> m_PlayerName; - //} m_Socket.connect(m_ReceiverEndpoint); LOG_INFO("I am client. BIP BOP"); } @@ -73,7 +69,7 @@ void Client::readFromServer() void Client::sendSnapshotToServer() { - // Reset previouse key state in snapshot. + // Reset previous key state in snapshot. m_NextSnapshot.InputForward = ""; m_NextSnapshot.InputRight = ""; diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 261583cc..c53dce8f 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -4,7 +4,9 @@ Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::a { } Server::~Server() -{ } +{ + +} void Server::Start(World* world, EventBroker* eventBroker) @@ -25,6 +27,8 @@ void Server::Update() void Server::Close() { m_ThreadIsRunning = false; + m_Socket.close(); + } void Server::readFromClients() @@ -271,7 +275,7 @@ void Server::parseConnect(Packet& packet) m_StopTimes[i] = std::clock(); - LOG_INFO("Player \"%s\" connected on IP: %s", m_PlayerDefinitions[i].Name, m_PlayerDefinitions[i].Endpoint.address().to_string()); + LOG_INFO("Player \"%s\" connected on IP: %s", m_PlayerDefinitions[i].Name.c_str(), m_PlayerDefinitions[i].Endpoint.address().to_string().c_str()); Packet packet(MessageType::Connect, m_SendPacketID); packet.WritePrimitive(i); // Player ID diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index c66d2641..bf08d340 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -144,10 +144,5 @@ void Game::networkFunction() m_ClientOrServer = new Server(); } m_ClientOrServer->Start(m_World, m_EventBroker); - // I don't think we are reaching this part of the code right now. - // ~Game() is not called if the game is exited by closing console windows - // When server or client is done set it to false. - //m_IsClientOrServer = false; - // Destroy it - //delete m_ClientOrServer; + } \ No newline at end of file From 6c13916eec56406e8267c832bac156022e4a677e Mon Sep 17 00:00:00 2001 From: Jocke Date: Wed, 6 Jan 2016 13:49:54 +0100 Subject: [PATCH 2/7] Removed unnecessary code. --- src/Engine/Network/Client.cpp | 9 ++++----- src/Engine/Network/Server.cpp | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index a417c4e5..f01509b4 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -42,11 +42,10 @@ void Client::Update() void Client::Close() { - if (m_WasStarted) { - disconnect(); - m_ThreadIsRunning = false; - m_EventBroker->Unsubscribe(m_EInputCommand); - } + disconnect(); + m_ThreadIsRunning = false; + m_Socket.close(); + m_EventBroker->Unsubscribe(m_EInputCommand); } void Client::readFromServer() diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index c53dce8f..bedbf954 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -28,7 +28,6 @@ void Server::Close() { m_ThreadIsRunning = false; m_Socket.close(); - } void Server::readFromClients() From b37ffc74494125b907cd2705da2428c6840aa95c Mon Sep 17 00:00:00 2001 From: Jocke Date: Mon, 11 Jan 2016 14:34:04 +0100 Subject: [PATCH 3/7] WIP Model component not working. --- include/Engine/Core/World.h | 2 + include/Engine/Network/Packet.h | 6 +- include/Engine/Network/Server.h | 1 + src/Engine/Collision/Collision.cpp | 36 ++++---- src/Engine/Core/World.cpp | 8 +- src/Engine/Network/Client.cpp | 68 +++++++++------ src/Engine/Network/Packet.cpp | 23 ++++-- src/Engine/Network/Server.cpp | 127 +++++++++++++++++++++++++---- 8 files changed, 204 insertions(+), 67 deletions(-) diff --git a/include/Engine/Core/World.h b/include/Engine/Core/World.h index 0a121728..c066933a 100644 --- a/include/Engine/Core/World.h +++ b/include/Engine/Core/World.h @@ -22,6 +22,8 @@ public: void RegisterComponent(ComponentInfo& ci); // Attach a component to an entity and fill it with default values ComponentWrapper AttachComponent(EntityID entity, std::string componentType); + // Check if world has an entity + bool HasEntity(EntityID entity); // Check if an entity has a component bool HasComponent(EntityID entity, std::string componentType) const; // Get a component of an entity diff --git a/include/Engine/Network/Packet.h b/include/Engine/Network/Packet.h index daf39962..76cf2cba 100644 --- a/include/Engine/Network/Packet.h +++ b/include/Engine/Network/Packet.h @@ -14,8 +14,9 @@ public: Packet(MessageType type, unsigned int& packetID); // Used to create packet from already existing data buffer. Packet(char* data, const int sizeOfPacket); - ~Packet(); + void Init(MessageType type, unsigned int& packetID); + // Add primitive types like int, float, char... template void WritePrimitive(T val) @@ -23,6 +24,7 @@ public: // Check if we are trying to add more than the package can fit. if (m_MaxPacketSize < m_Offset + sizeof(T)) { LOG_WARNING("Packet AddPrimitive(): You are trying to add more than we have allocated for!"); + return; } memcpy(m_Data + m_Offset, &val, sizeof(T)); m_Offset += sizeof(T); @@ -50,6 +52,8 @@ public: int Size() { return m_Offset; }; char* Data() { return m_Data; }; + unsigned int DataReadSize() { return m_ReturnDataOffset; } + unsigned int MaxSize() { return m_MaxPacketSize; } private: char* m_Data; diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 5c1ac1fb..af454bc1 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -67,6 +67,7 @@ private: void moveMessageHead(char*& data, size_t& length, size_t stepSize); void broadcast(std::string message); void broadcast(Packet& packet); + //void parseShitTest(Packet& packet); // Remove this when network is working void sendSnapshot(); void sendPing(); void checkForTimeOuts(); diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index c4af6258..a767ee95 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -245,23 +245,29 @@ bool attachAABBComponentFromModel(World* world, EntityID id) bool GetEntityBox(World* world, ComponentWrapper& AABBComponent, AABB& outBox) { - ComponentWrapper& cTrans = world->GetComponent(AABBComponent.EntityID, "Transform"); - ComponentWrapper model = world->GetComponent(AABBComponent.EntityID, "Model"); - Model* modelRes = ResourceManager::Load(model["Resource"]); - outBox.CreateFromCenter(AABBComponent["BoxCenter"], AABBComponent["BoxSize"]); - glm::vec3 mini = outBox.MinCorner(); - glm::vec3 maxi = outBox.MaxCorner(); + if (world->HasComponent(AABBComponent.EntityID, "Transform") && world->HasComponent(AABBComponent.EntityID, "Model")) + { + ComponentWrapper& cTrans = world->GetComponent(AABBComponent.EntityID, "Transform"); + ComponentWrapper model = world->GetComponent(AABBComponent.EntityID, "Model"); + if(AABBComponent.EntityID == 3); + std::string checkPath = model["Resource"]; + Model* modelRes = ResourceManager::Load(model["Resource"]); + outBox.CreateFromCenter(AABBComponent["BoxCenter"], AABBComponent["BoxSize"]); + glm::vec3 mini = outBox.MinCorner(); + glm::vec3 maxi = outBox.MaxCorner(); - if (modelRes == nullptr) { - return false; + if (modelRes == nullptr) { + return false; + } + glm::mat4 modelMatrix = modelRes->m_Matrix * + glm::translate(glm::mat4(), (glm::vec3)cTrans["Position"]) * + glm::scale((glm::vec3)cTrans["Scale"]); + + outBox = AABB(modelMatrix * glm::vec4(mini.x, mini.y, mini.z, 1), + modelMatrix * glm::vec4(maxi.x, maxi.y, maxi.z, 1)); + return true; } - glm::mat4 modelMatrix = modelRes->m_Matrix * - glm::translate(glm::mat4(), (glm::vec3)cTrans["Position"]) * - glm::scale((glm::vec3)cTrans["Scale"]); - - outBox = AABB(modelMatrix * glm::vec4(mini.x, mini.y, mini.z, 1), - modelMatrix * glm::vec4(maxi.x, maxi.y, maxi.z, 1)); - return true; + return false; } bool GetEntityBox(World* world, EntityID entity, AABB& outBox, bool forceBoxFromModel) diff --git a/src/Engine/Core/World.cpp b/src/Engine/Core/World.cpp index c94cb8b3..faddeb83 100644 --- a/src/Engine/Core/World.cpp +++ b/src/Engine/Core/World.cpp @@ -80,7 +80,13 @@ ComponentWrapper World::AttachComponent(EntityID entity, std::string componentTy return c; } -bool World::HasComponent(EntityID entity, std::string componentType) const +bool World::HasEntity(EntityID entity) +{ + return m_EntityParents.find(entity) != m_EntityParents.end(); +} + + +bool World::HasComponent(EntityID entity, std::string componentType) { ComponentPool* pool = m_ComponentPools.at(componentType); return pool->KnowsEntity(entity); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index f01509b4..08f68f98 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -50,7 +50,7 @@ void Client::Close() void Client::readFromServer() { - if (m_Socket.available()) { + while (m_Socket.available()) { bytesRead = receive(readBuf, INPUTSIZE); if (bytesRead > 0) { Packet packet(readBuf, bytesRead); @@ -60,7 +60,7 @@ void Client::readFromServer() std::clock_t currentTime = std::clock(); if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { if (isConnected()) { - sendSnapshotToServer(); + //sendSnapshotToServer(); } previousSnapshotMessage = currentTime; } @@ -120,6 +120,8 @@ void Client::parseMessageType(Packet& packet) // Read packet ID m_PreviousPacketID = m_PacketID; // Set previous packet id m_PacketID = packet.ReadPrimitive(); //Read new packet id + if (m_PacketID <= m_PreviousPacketID) + return; //IdentifyPacketLoss(); switch (static_cast(messageType)) { @@ -181,33 +183,45 @@ void Client::parseEventMessage(Packet& packet) void Client::parseSnapshot(Packet& packet) { - std::string tempName; - for (size_t i = 0; i < MAXCONNECTIONS; i++) { - // We're checking for empty name for now. This might not be the best way, - // but it is to avoid sending redundant data. - tempName = packet.ReadString(); - - - // Apply the position data read to the player entity - // New player connected on the server side - if (m_PlayerDefinitions[i].Name == "" && tempName != "") { - m_PlayerDefinitions[i].Name = tempName; - m_PlayerDefinitions[i].EntityID = createPlayer(); - } else if (m_PlayerDefinitions[i].Name != "" && tempName == "") { - // Someone disconnected - // TODO: Insert code here - break; - } else if (m_PlayerDefinitions[i].Name == "" && tempName == "") { - // Not a connected player - break; - } - if (m_PlayerDefinitions[i].EntityID != -1) { - - // Move player to server position - int dataSize = m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform").Info.Meta.Stride; - memcpy(m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform").Data, packet.ReadData(dataSize), dataSize); + std::string componentType = packet.ReadString(); + //LOG_INFO("A snapshot was parsed. first component type is: %s", componentType.c_str()); + int stride = packet.ReadPrimitive(); + int nrOfComponents = (packet.Size() - packet.DataReadSize()) / (stride + sizeof(EntityID)); + if (componentType == "Model") + return; + for (size_t i = 0; i < nrOfComponents; i++) { + EntityID entityID = packet.ReadPrimitive(); + //ComponentWrapper model = m_World->GetComponent(entityID, "Model"); + //std::string checkPath = model["Resource"]; + // Check if entity exists + if (m_World->HasEntity(entityID)) { + // check if component exists + if (m_World->HasComponent(entityID, componentType)) { + //Copy data to component + memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); + } else { + // If component doesen't exist + // Create component + m_World->AttachComponent(entityID, componentType); + // Copy data to newly created component + memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); + } + } else { + // If entity dosen't exist + EntityID newEntityID = m_World->CreateEntity(); + // Check if EntityIDs are out of sync + if (newEntityID != entityID) { + LOG_INFO("Client::parseSnapshot(Packet& packet): Newly created EntityID is not the same as the one sent by server \ + EntityIDs are out of sync"); + } + m_World->AttachComponent(newEntityID, componentType); + // Copy data to newly created component + memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); } + //ComponentWrapper model2 = m_World->GetComponent(entityID, "Model"); + //std::string checkPath2 = model2["Resource"]; } + } int Client::receive(char* data, size_t length) diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index 52b15065..86a91f5d 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -3,13 +3,7 @@ Packet::Packet(MessageType type, unsigned int& packetID) { m_Data = new char[m_MaxPacketSize]; - // Create message header - // Add message type - int messageType = static_cast(type); - Packet::WritePrimitive(messageType); - packetID = packetID % 1000; // Packet id modulos - Packet::WritePrimitive(packetID); - packetID++; + Init(type, packetID); } // Create message @@ -28,12 +22,26 @@ Packet::~Packet() delete[] m_Data; } +void Packet::Init(MessageType type, unsigned int & packetID) +{ + m_ReturnDataOffset = 0; + m_Offset = 0; + // Create message header + // Add message type + int messageType = static_cast(type); + Packet::WritePrimitive(messageType); + packetID = packetID % 1000; // Packet id modulos + Packet::WritePrimitive(packetID); + packetID++; +} + void Packet::WriteString(std::string str) { // Message, add one extra byte for null terminator int sizeOfString = str.size() + 1; if (m_Offset + sizeOfString > m_MaxPacketSize) { LOG_WARNING("Package::WriteString(): Data size in packet exceeded maximum package size.\n"); + return; } memcpy(m_Data + m_Offset, str.data(), sizeOfString * sizeof(char)); m_Offset += sizeOfString * sizeof(char); @@ -43,6 +51,7 @@ void Packet::WriteData(char * data, int sizeOfData) { if (m_Offset + sizeOfData > m_MaxPacketSize) { LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size.\n"); + return; } memcpy(m_Data + m_Offset, data, sizeOfData); m_Offset += sizeOfData; diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index bedbf954..791f5a42 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -4,7 +4,7 @@ Server::Server() : m_Socket(m_IOService, boost::asio::ip::udp::endpoint(boost::a { } Server::~Server() -{ +{ } @@ -36,7 +36,7 @@ void Server::readFromClients() // program crashed if it executed m_Socket.available() // when closing the program. - if (m_Socket.available()) { + while (m_Socket.available()) { try { bytesRead = receive(readBuffer, INPUTSIZE); Packet packet(readBuffer, bytesRead); @@ -61,7 +61,7 @@ void Server::readFromClients() // Time out logic if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { - checkForTimeOuts(); + //checkForTimeOuts(); timOutTimer = currentTime; } } @@ -152,32 +152,127 @@ void Server::broadcast(Packet& packet) } } } +// +//void Server::parseShitTest(Packet& packet) +//{ +// packet.ReadPrimitive(); // MessageType +// packet.ReadPrimitive(); // Packet ID +// +// std::string componentType = packet.ReadString(); +// //LOG_INFO("A snapshot was parsed. first component type is: %s", componentType.c_str()); +// int stride = packet.ReadPrimitive(); +// int nrOfComponents = (packet.Size() - packet.DataReadSize()) / (stride + sizeof(EntityID)); +// //if (componentType == "Model") +// // return; +// for (size_t i = 0; i < nrOfComponents; i++) { +// EntityID entityID = packet.ReadPrimitive(); +// ComponentWrapper model = m_World->GetComponent(entityID, "Model"); +// std::string checkPath = model["Resource"]; +// // Check if entity exists +// if (m_World->HasEntity(entityID)) { +// // check if component exists +// if (m_World->HasComponent(entityID, componentType)) { +// //Copy data to component +// memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); +// } else { +// // If component doesen't exist +// // Create component +// m_World->AttachComponent(entityID, componentType); +// // Copy data to newly created component +// memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); +// } +// } else { +// // If entity dosen't exist +// EntityID newEntityID = m_World->CreateEntity(); +// // Check if EntityIDs are out of sync +// if (newEntityID != entityID) { +// LOG_INFO("Client::parseSnapshot(Packet& packet): Newly created EntityID is not the same as the one sent by server \ +// EntityIDs are out of sync"); +// } +// m_World->AttachComponent(newEntityID, componentType); +// // Copy data to newly created component +// memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); +// } +// ComponentWrapper model2 = m_World->GetComponent(entityID, "Model"); +// std::string checkPath2 = model2["Resource"]; +// } +//} void Server::sendSnapshot() { - Packet packet(MessageType::Snapshot, m_SendPacketID); - for (size_t i = 0; i < MAXCONNECTIONS; i++) { - - // Send an empty name if there is no player connected on this position. - packet.WriteString(m_PlayerDefinitions[i].Name); - - if (m_PlayerDefinitions[i].EntityID == -1) { - continue; + // Should time this + std::unordered_map worldComponentPools = m_World->GetComponentPools(); + for (auto it : worldComponentPools) { + Packet packet(MessageType::Snapshot, m_SendPacketID); + std::string componentType = it.first; + //if (componentType != "Model") + // continue; + ComponentPool* componentPool = it.second; + ComponentInfo componentInfo = componentPool->ComponentInfo(); + packet.WriteString(componentInfo.Name); + packet.WritePrimitive(componentInfo.Meta.Stride); + for (auto componentWrapper : *componentPool) { + if (packet.Size() + componentInfo.Meta.Stride >= packet.MaxSize()) { + broadcast(packet); + //parseShitTest(packet); + // Packet destructor is called (which is what we want). + packet.Init(MessageType::Snapshot, m_SendPacketID); + // Add Component header + packet.WriteString(componentInfo.Name); + packet.WritePrimitive(componentInfo.Meta.Stride); + } + // Component data + packet.WritePrimitive(componentWrapper.EntityID); + packet.WriteData(componentWrapper.Data, componentWrapper.Info.Meta.Stride); } - // Pack transfrom component into data packet - auto transform = m_World->GetComponent(m_PlayerDefinitions[i].EntityID, "Transform"); - packet.WriteData(transform.Data, transform.Info.Meta.Stride); + broadcast(packet); } - broadcast(packet); } +//void Server::sendSnapshot() +//{ +// // Should time this +// std::unordered_map worldComponentPools = m_World->GetComponentPools(); +// for (auto it : worldComponentPools) { +// Packet packet(MessageType::Snapshot, m_SendPacketID); +// std::string componentType = it.first; +// ComponentPool* componentPool = it.second; +// ComponentInfo componentInfo = componentPool->ComponentInfo(); +// if (componentInfo.Name != "Transform") +// continue; +// packet.WriteString(componentInfo.Name); +// packet.WritePrimitive(componentInfo.Meta.Stride); +// auto componentWrapper = *componentPool->begin(); +// packet.WritePrimitive(componentWrapper.EntityID); +// packet.WriteData(componentWrapper.Data, componentWrapper.Info.Meta.Stride); +// +// for (auto componentWrapper : *componentPool) { +// //// When packet is full send it +// //if (packet.Size() + componentInfo.Meta.Stride >= packet.MaxSize()) { +// // broadcast(packet); +// // // Packet destructor is called (which is what we want). +// // packet.Init(MessageType::Snapshot, m_SendPacketID); +// // // Add Component header +// // packet.WriteString(componentInfo.Name); +// // packet.WritePrimitive(componentInfo.Meta.Stride); +// +// //} +// //// Component data +// //packet.WritePrimitive(componentWrapper.EntityID); +// //packet.WriteData(componentWrapper.Data, componentWrapper.Info.Meta.Stride); +// broadcast(packet); +// } +// broadcast(packet); +// } +//} + void Server::sendPing() { // Prints connected players ping for (size_t i = 0; i < MAXCONNECTIONS; i++) { if (m_PlayerDefinitions[i].Endpoint.address() != boost::asio::ip::address()) { int ping = 1000 * (m_StopTimes[i] - m_StartPingTime) / static_cast(CLOCKS_PER_SEC); - LOG_INFO("%i: Player %i's ping: %i", m_PacketID, i, ping); + LOG_INFO("Last packetID received %i: Player %i's ping: %i", m_PacketID, i, ping); } } From 236230d12c77473c22aeef9df7fdc8fc750a33b6 Mon Sep 17 00:00:00 2001 From: Jocke Date: Tue, 12 Jan 2016 12:00:19 +0100 Subject: [PATCH 4/7] Packets now dynamically allocates more memory when they need it. Increased local receive buffer for Client and Server() and removed the magic number that was used In Server.h and Client.h (char readBuffer[INPUTSIZE] = { 0 }). Packets start size has now been increased to 512 bytes. Changed ComponentInfo::FieldsInOrder to store strings instead of pointers. Removed HasEntity() and are now using ValidEntity() instead. --- include/Engine/Core/ComponentInfo.h | 3 +- include/Engine/Core/World.h | 2 - include/Engine/Network/Client.h | 5 +- include/Engine/Network/Network.h | 2 +- include/Engine/Network/Packet.h | 9 +- include/Engine/Network/Server.h | 3 +- src/Engine/Collision/Collision.cpp | 392 ++++++++++----------- src/Engine/Core/EntityFilePreprocessor.cpp | 3 +- src/Engine/Core/World.cpp | 8 +- src/Engine/Network/Client.cpp | 53 +-- src/Engine/Network/Packet.cpp | 32 +- src/Engine/Network/Server.cpp | 119 +------ src/Game/Game.cpp | 32 +- 13 files changed, 307 insertions(+), 356 deletions(-) diff --git a/include/Engine/Core/ComponentInfo.h b/include/Engine/Core/ComponentInfo.h index abf4ff15..985a057e 100644 --- a/include/Engine/Core/ComponentInfo.h +++ b/include/Engine/Core/ComponentInfo.h @@ -14,6 +14,7 @@ struct ComponentInfo struct Field_t { + std::string Name; std::string Type; unsigned int Offset; unsigned int Stride; @@ -21,7 +22,7 @@ struct ComponentInfo std::string Name; std::unordered_map Fields; - std::vector FieldsInOrder; + std::vector FieldsInOrder; Meta_t Meta; std::shared_ptr Defaults = nullptr; }; diff --git a/include/Engine/Core/World.h b/include/Engine/Core/World.h index c066933a..0a121728 100644 --- a/include/Engine/Core/World.h +++ b/include/Engine/Core/World.h @@ -22,8 +22,6 @@ public: void RegisterComponent(ComponentInfo& ci); // Attach a component to an entity and fill it with default values ComponentWrapper AttachComponent(EntityID entity, std::string componentType); - // Check if world has an entity - bool HasEntity(EntityID entity); // Check if an entity has a component bool HasComponent(EntityID entity, std::string componentType) const; // Get a component of an entity diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index 95888b1f..b7bd9b38 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -32,7 +32,7 @@ private: // Sending message to server logic int bytesRead = -1; - char readBuf[1024] = { 0 }; + char readBuf[INPUTSIZE] = { 0 }; int snapshotInterval = 33; std::clock_t previousSnapshotMessage = std::clock(); @@ -59,7 +59,7 @@ private: // Private member functions void readFromServer(); void sendSnapshotToServer(); - int receive(char* data, size_t length); + int receive(char* data, size_t length); void send(Packet& packet); void connect(); void disconnect(); @@ -67,6 +67,7 @@ private: void moveMessageHead(char*& data, size_t& length, size_t stepSize); void parseMessageType(Packet& packet); void parseEventMessage(Packet& packet); + void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType); void parseConnect(Packet& packet); void parsePing(); void parseServerPing(); diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index c5107b2b..8a50f061 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -6,7 +6,7 @@ #include "Network/Packet.h" #define MAXCONNECTIONS 8 -#define INPUTSIZE 128 +#define INPUTSIZE 4097 class Network { diff --git a/include/Engine/Network/Packet.h b/include/Engine/Network/Packet.h index 76cf2cba..112ebe34 100644 --- a/include/Engine/Network/Packet.h +++ b/include/Engine/Network/Packet.h @@ -23,8 +23,8 @@ public: { // Check if we are trying to add more than the package can fit. if (m_MaxPacketSize < m_Offset + sizeof(T)) { - LOG_WARNING("Packet AddPrimitive(): You are trying to add more than we have allocated for!"); - return; + LOG_WARNING("Packet AddPrimitive(): You are trying to add more than we have allocated for! New size is %i bytes\n", m_MaxPacketSize*2); + resizeData(); } memcpy(m_Data + m_Offset, &val, sizeof(T)); m_Offset += sizeof(T); @@ -43,7 +43,7 @@ public: return returnValue; } // Add a string to the message - void WriteString(std::string str); + void WriteString(const std::string& str); // Add data to the message void WriteData(char* data, int sizeOfData); // Pops the first element as if it was a string. @@ -59,7 +59,8 @@ private: char* m_Data; unsigned int m_ReturnDataOffset = 0; int m_Offset = 0; - unsigned int m_MaxPacketSize = 128; + unsigned int m_MaxPacketSize = 512; + void resizeData(); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index af454bc1..58ee2631 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -30,7 +30,7 @@ private: PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; // Sending messages to client logic - char readBuffer[1024] = { 0 }; + char readBuffer[INPUTSIZE] = { 0 }; int bytesRead = 0; // time for previouse message std::clock_t previousePingMessage = std::clock(); @@ -67,7 +67,6 @@ private: void moveMessageHead(char*& data, size_t& length, size_t stepSize); void broadcast(std::string message); void broadcast(Packet& packet); - //void parseShitTest(Packet& packet); // Remove this when network is working void sendSnapshot(); void sendPing(); void checkForTimeOuts(); diff --git a/src/Engine/Collision/Collision.cpp b/src/Engine/Collision/Collision.cpp index a767ee95..620e9639 100644 --- a/src/Engine/Collision/Collision.cpp +++ b/src/Engine/Collision/Collision.cpp @@ -8,196 +8,196 @@ namespace Collision { - //note: this one hasnt been delta adjusted like RayVsAABB has - bool RayAABBIntr(const Ray& ray, const AABB& box) - { - glm::vec3 w = 75.0f * ray.Direction(); - glm::vec3 v = glm::abs(w); - glm::vec3 c = ray.Origin() - box.Center() + w; - glm::vec3 half = box.HalfSize(); +//note: this one hasnt been delta adjusted like RayVsAABB has +bool RayAABBIntr(const Ray& ray, const AABB& box) +{ + glm::vec3 w = 75.0f * ray.Direction(); + glm::vec3 v = glm::abs(w); + glm::vec3 c = ray.Origin() - box.Center() + w; + glm::vec3 half = box.HalfSize(); - if (abs(c.x) > v.x + half.x) { - return false; - } - if (abs(c.y) > v.y + half.y) { - return false; - } - if (abs(c.z) > v.z + half.z) { - return false; - } - - if (abs(c.y*w.z - c.z*w.y) > half.y*v.z + half.z*v.y) { - return false; - } - if (abs(c.x*w.z - c.z*w.x) > half.x*v.z + half.z*v.x) { - return false; - } - return !(abs(c.x*w.y - c.y*w.x) > half.x*v.y + half.y*v.x); + if (abs(c.x) > v.x + half.x) { + return false; } - - bool RayVsAABB(const Ray& ray, const AABB& box) - { - float dummy; - return RayVsAABB(ray, box, dummy); + if (abs(c.y) > v.y + half.y) { + return false; } - - bool RayVsAABB(const Ray& ray, const AABB& box, float& outDistance) - { - glm::vec3 invdir = 1.0f / ray.Direction(); - glm::vec3 origin = ray.Origin(); - - float t1 = (box.MinCorner().x - origin.x)*invdir.x; - float t2 = (box.MaxCorner().x - origin.x)*invdir.x; - float t3 = (box.MinCorner().y - origin.y)*invdir.y; - float t4 = (box.MaxCorner().y - origin.y)*invdir.y; - float t5 = (box.MinCorner().z - origin.z)*invdir.z; - float t6 = (box.MaxCorner().z - origin.z)*invdir.z; - - float tmin = std::max(std::max(std::min(t1, t2), std::min(t3, t4)), std::min(t5, t6)); - float tmax = std::min(std::min(std::max(t1, t2), std::max(t3, t4)), std::max(t5, t6)); - - //if (tmax < 0 || tmin > tmax) - //if tmin,tmax are almost the same (i.e. hitting exactly in the corner) then tmin might be slightly - //greater than tmax becuase of floating-precision problems. fixed by adding a small delta to tmax - if (tmax < 0 || tmin>(tmax + 0.0001f)) - return false; - - outDistance = (tmin > 0) ? tmin : tmax; - return true; - } - - bool AABBVsAABB(const AABB& a, const AABB& b) - { - const glm::vec3& aCenter = a.Center(); - const glm::vec3& bCenter = b.Center(); - const glm::vec3& aHSize = a.HalfSize(); - const glm::vec3& bHSize = b.HalfSize(); - //Test will probably exit because of the X and Z axes more often, so test them first. - if (abs(aCenter[0] - bCenter[0]) > (aHSize[0] + bHSize[0])) { - return false; - } - if (abs(aCenter[2] - bCenter[2]) > (aHSize[2] + bHSize[2])) { - return false; - } - return (abs(aCenter[1] - bCenter[1]) <= (aHSize[1] + bHSize[1])); - } - - bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation) - { - minimumTranslation = glm::vec3(0, 0, 0); - const glm::vec3& aMax = a.MaxCorner(); - const glm::vec3& bMax = b.MaxCorner(); - const glm::vec3& aMin = a.MinCorner(); - const glm::vec3& bMin = b.MinCorner(); - const glm::vec3& bSize = b.Size(); - const glm::vec3& aSize = a.Size(); - float minOffset = INFINITY; - float off; - auto axisesIntersecting = glm::tvec3(false, false, false); - for (int i = 0; i < 3; ++i) { - off = bMax[i] - aMin[i]; - if (off > 0 && off < bSize[i] + aSize[i]) { - if (off < minOffset) { - minimumTranslation = glm::vec3(); - minimumTranslation[i] = minOffset = off; - } - axisesIntersecting[i] = true; - } - off = aMax[i] - bMin[i]; - if (off > 0 && off < bSize[i] + aSize[i]) { - if (off < minOffset) { - minOffset = off; - minimumTranslation = glm::vec3(); - minimumTranslation[i] = -off; - } - axisesIntersecting[i] = true; - } - } - return glm::all(axisesIntersecting); - } - - bool RayVsModel(const Ray& ray, - const std::vector& modelVertices, - const std::vector& modelIndices) - { - for (int i = 0; i < modelIndices.size(); ++i) { - glm::vec3 v0 = modelVertices[modelIndices[i]].Position; - glm::vec3 e1 = modelVertices[modelIndices[++i]].Position - v0; //v1 - v0 - glm::vec3 e2 = modelVertices[modelIndices[++i]].Position - v0; //v2 - v0 - glm::vec3 m = ray.Origin() - v0; - glm::vec3 MxE1 = glm::cross(m, e1); - glm::vec3 DxE2 = glm::cross(ray.Direction(), e2); - float DetInv = glm::dot(e1, DxE2); - if (std::abs(DetInv) < FLT_EPSILON) { - continue; - } - DetInv = 1.0f / DetInv; - float u = glm::dot(m, DxE2) * DetInv; - float v = glm::dot(ray.Direction(), MxE1) * DetInv; - //u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem - if ((u + 0.001f) < 0 || (v + 0.001f) < 0 || 1 < u + v) { - continue; - } - //Here, u and v are positive, u+v <= 1, and if distance is positive - triangle is hit. - if (0 <= glm::dot(e2, MxE1) * DetInv) { - return true; - } - } + if (abs(c.z) > v.z + half.z) { return false; } - bool RayVsModel(const Ray& ray, - const std::vector& modelVertices, - const std::vector& modelIndices, - float& outDistance, - float& outUCoord, - float& outVCoord) - { - outDistance = INFINITY; - bool hit = false; - for (int i = 0; i < modelIndices.size(); ++i) { - glm::vec3 v0 = modelVertices[modelIndices[i]].Position; - glm::vec3 e1 = modelVertices[modelIndices[++i]].Position - v0; //v1 - v0 - glm::vec3 e2 = modelVertices[modelIndices[++i]].Position - v0; //v2 - v0 - glm::vec3 m = ray.Origin() - v0; - glm::vec3 MxE1 = glm::cross(m, e1); - glm::vec3 DxE2 = glm::cross(ray.Direction(), e2);//pVec - float DetInv = glm::dot(e1, DxE2); - if (std::abs(DetInv) < FLT_EPSILON) { - continue; - } - DetInv = 1.0f / DetInv; - float dist = glm::dot(e2, MxE1) * DetInv; - if (dist >= outDistance) { - continue; - } - float u = glm::dot(m, DxE2) * DetInv; - float v = glm::dot(ray.Direction(), MxE1) * DetInv; + if (abs(c.y*w.z - c.z*w.y) > half.y*v.z + half.z*v.y) { + return false; + } + if (abs(c.x*w.z - c.z*w.x) > half.x*v.z + half.z*v.x) { + return false; + } + return !(abs(c.x*w.y - c.y*w.x) > half.x*v.y + half.y*v.x); +} - //u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem - //If u and v are positive, u+v <= 1, dist is positive, and less than closest. - if (0 <= (u + 0.001f) && 0 <= (v + 0.001f) && u + v <= 1 && 0 <= dist) { - outDistance = dist; - outUCoord = u; - outVCoord = v; - hit = true; +bool RayVsAABB(const Ray& ray, const AABB& box) +{ + float dummy; + return RayVsAABB(ray, box, dummy); +} + +bool RayVsAABB(const Ray& ray, const AABB& box, float& outDistance) +{ + glm::vec3 invdir = 1.0f / ray.Direction(); + glm::vec3 origin = ray.Origin(); + + float t1 = (box.MinCorner().x - origin.x)*invdir.x; + float t2 = (box.MaxCorner().x - origin.x)*invdir.x; + float t3 = (box.MinCorner().y - origin.y)*invdir.y; + float t4 = (box.MaxCorner().y - origin.y)*invdir.y; + float t5 = (box.MinCorner().z - origin.z)*invdir.z; + float t6 = (box.MaxCorner().z - origin.z)*invdir.z; + + float tmin = std::max(std::max(std::min(t1, t2), std::min(t3, t4)), std::min(t5, t6)); + float tmax = std::min(std::min(std::max(t1, t2), std::max(t3, t4)), std::max(t5, t6)); + + //if (tmax < 0 || tmin > tmax) + //if tmin,tmax are almost the same (i.e. hitting exactly in the corner) then tmin might be slightly + //greater than tmax becuase of floating-precision problems. fixed by adding a small delta to tmax + if (tmax < 0 || tmin>(tmax + 0.0001f)) + return false; + + outDistance = (tmin > 0) ? tmin : tmax; + return true; +} + +bool AABBVsAABB(const AABB& a, const AABB& b) +{ + const glm::vec3& aCenter = a.Center(); + const glm::vec3& bCenter = b.Center(); + const glm::vec3& aHSize = a.HalfSize(); + const glm::vec3& bHSize = b.HalfSize(); + //Test will probably exit because of the X and Z axes more often, so test them first. + if (abs(aCenter[0] - bCenter[0]) > (aHSize[0] + bHSize[0])) { + return false; + } + if (abs(aCenter[2] - bCenter[2]) > (aHSize[2] + bHSize[2])) { + return false; + } + return (abs(aCenter[1] - bCenter[1]) <= (aHSize[1] + bHSize[1])); +} + +bool AABBVsAABB(const AABB& a, const AABB& b, glm::vec3& minimumTranslation) +{ + minimumTranslation = glm::vec3(0, 0, 0); + const glm::vec3& aMax = a.MaxCorner(); + const glm::vec3& bMax = b.MaxCorner(); + const glm::vec3& aMin = a.MinCorner(); + const glm::vec3& bMin = b.MinCorner(); + const glm::vec3& bSize = b.Size(); + const glm::vec3& aSize = a.Size(); + float minOffset = INFINITY; + float off; + auto axisesIntersecting = glm::tvec3(false, false, false); + for (int i = 0; i < 3; ++i) { + off = bMax[i] - aMin[i]; + if (off > 0 && off < bSize[i] + aSize[i]) { + if (off < minOffset) { + minimumTranslation = glm::vec3(); + minimumTranslation[i] = minOffset = off; } + axisesIntersecting[i] = true; + } + off = aMax[i] - bMin[i]; + if (off > 0 && off < bSize[i] + aSize[i]) { + if (off < minOffset) { + minOffset = off; + minimumTranslation = glm::vec3(); + minimumTranslation[i] = -off; + } + axisesIntersecting[i] = true; } - return hit; } + return glm::all(axisesIntersecting); +} - bool RayVsModel(const Ray& ray, - const std::vector& modelVertices, - const std::vector& modelIndices, - glm::vec3& outHitPosition) - { - float u; - float v; - float dist; - bool hit = RayVsModel(ray, modelVertices, modelIndices, dist, u, v); - outHitPosition = ray.Origin() + dist * ray.Direction(); - return hit; +bool RayVsModel(const Ray& ray, + const std::vector& modelVertices, + const std::vector& modelIndices) +{ + for (int i = 0; i < modelIndices.size(); ++i) { + glm::vec3 v0 = modelVertices[modelIndices[i]].Position; + glm::vec3 e1 = modelVertices[modelIndices[++i]].Position - v0; //v1 - v0 + glm::vec3 e2 = modelVertices[modelIndices[++i]].Position - v0; //v2 - v0 + glm::vec3 m = ray.Origin() - v0; + glm::vec3 MxE1 = glm::cross(m, e1); + glm::vec3 DxE2 = glm::cross(ray.Direction(), e2); + float DetInv = glm::dot(e1, DxE2); + if (std::abs(DetInv) < FLT_EPSILON) { + continue; + } + DetInv = 1.0f / DetInv; + float u = glm::dot(m, DxE2) * DetInv; + float v = glm::dot(ray.Direction(), MxE1) * DetInv; + //u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem + if ((u + 0.001f) < 0 || (v + 0.001f) < 0 || 1 < u + v) { + continue; + } + //Here, u and v are positive, u+v <= 1, and if distance is positive - triangle is hit. + if (0 <= glm::dot(e2, MxE1) * DetInv) { + return true; + } } + return false; +} + +bool RayVsModel(const Ray& ray, + const std::vector& modelVertices, + const std::vector& modelIndices, + float& outDistance, + float& outUCoord, + float& outVCoord) +{ + outDistance = INFINITY; + bool hit = false; + for (int i = 0; i < modelIndices.size(); ++i) { + glm::vec3 v0 = modelVertices[modelIndices[i]].Position; + glm::vec3 e1 = modelVertices[modelIndices[++i]].Position - v0; //v1 - v0 + glm::vec3 e2 = modelVertices[modelIndices[++i]].Position - v0; //v2 - v0 + glm::vec3 m = ray.Origin() - v0; + glm::vec3 MxE1 = glm::cross(m, e1); + glm::vec3 DxE2 = glm::cross(ray.Direction(), e2);//pVec + float DetInv = glm::dot(e1, DxE2); + if (std::abs(DetInv) < FLT_EPSILON) { + continue; + } + DetInv = 1.0f / DetInv; + float dist = glm::dot(e2, MxE1) * DetInv; + if (dist >= outDistance) { + continue; + } + float u = glm::dot(m, DxE2) * DetInv; + float v = glm::dot(ray.Direction(), MxE1) * DetInv; + + //u,v can be very close to 0 but still negative sometimes. added a deltafactor to compensate for that problem + //If u and v are positive, u+v <= 1, dist is positive, and less than closest. + if (0 <= (u + 0.001f) && 0 <= (v + 0.001f) && u + v <= 1 && 0 <= dist) { + outDistance = dist; + outUCoord = u; + outVCoord = v; + hit = true; + } + } + return hit; +} + +bool RayVsModel(const Ray& ray, + const std::vector& modelVertices, + const std::vector& modelIndices, + glm::vec3& outHitPosition) +{ + float u; + float v; + float dist; + bool hit = RayVsModel(ray, modelVertices, modelIndices, dist, u, v); + outHitPosition = ray.Origin() + dist * ray.Direction(); + return hit; +} bool IsSameBoxProbably(const AABB& first, const AABB& second, const float epsilon) { @@ -245,29 +245,23 @@ bool attachAABBComponentFromModel(World* world, EntityID id) bool GetEntityBox(World* world, ComponentWrapper& AABBComponent, AABB& outBox) { - if (world->HasComponent(AABBComponent.EntityID, "Transform") && world->HasComponent(AABBComponent.EntityID, "Model")) - { - ComponentWrapper& cTrans = world->GetComponent(AABBComponent.EntityID, "Transform"); - ComponentWrapper model = world->GetComponent(AABBComponent.EntityID, "Model"); - if(AABBComponent.EntityID == 3); - std::string checkPath = model["Resource"]; - Model* modelRes = ResourceManager::Load(model["Resource"]); - outBox.CreateFromCenter(AABBComponent["BoxCenter"], AABBComponent["BoxSize"]); - glm::vec3 mini = outBox.MinCorner(); - glm::vec3 maxi = outBox.MaxCorner(); + ComponentWrapper& cTrans = world->GetComponent(AABBComponent.EntityID, "Transform"); + ComponentWrapper model = world->GetComponent(AABBComponent.EntityID, "Model"); + Model* modelRes = ResourceManager::Load(model["Resource"]); + outBox.CreateFromCenter(AABBComponent["BoxCenter"], AABBComponent["BoxSize"]); + glm::vec3 mini = outBox.MinCorner(); + glm::vec3 maxi = outBox.MaxCorner(); - if (modelRes == nullptr) { - return false; - } - glm::mat4 modelMatrix = modelRes->m_Matrix * - glm::translate(glm::mat4(), (glm::vec3)cTrans["Position"]) * - glm::scale((glm::vec3)cTrans["Scale"]); - - outBox = AABB(modelMatrix * glm::vec4(mini.x, mini.y, mini.z, 1), - modelMatrix * glm::vec4(maxi.x, maxi.y, maxi.z, 1)); - return true; + if (modelRes == nullptr) { + return false; } - return false; + glm::mat4 modelMatrix = modelRes->m_Matrix * + glm::translate(glm::mat4(), (glm::vec3)cTrans["Position"]) * + glm::scale((glm::vec3)cTrans["Scale"]); + + outBox = AABB(modelMatrix * glm::vec4(mini.x, mini.y, mini.z, 1), + modelMatrix * glm::vec4(maxi.x, maxi.y, maxi.z, 1)); + return true; } bool GetEntityBox(World* world, EntityID entity, AABB& outBox, bool forceBoxFromModel) diff --git a/src/Engine/Core/EntityFilePreprocessor.cpp b/src/Engine/Core/EntityFilePreprocessor.cpp index 83e2fe28..ca445042 100644 --- a/src/Engine/Core/EntityFilePreprocessor.cpp +++ b/src/Engine/Core/EntityFilePreprocessor.cpp @@ -144,10 +144,11 @@ void EntityFilePreprocessor::parseComponentInfo() } auto& field = compInfo.Fields[name]; + field.Name = name; field.Type = type; field.Offset = fieldOffset; field.Stride = stride; - compInfo.FieldsInOrder.push_back(&field); + compInfo.FieldsInOrder.push_back(name); fieldOffset += stride; } diff --git a/src/Engine/Core/World.cpp b/src/Engine/Core/World.cpp index faddeb83..c94cb8b3 100644 --- a/src/Engine/Core/World.cpp +++ b/src/Engine/Core/World.cpp @@ -80,13 +80,7 @@ ComponentWrapper World::AttachComponent(EntityID entity, std::string componentTy return c; } -bool World::HasEntity(EntityID entity) -{ - return m_EntityParents.find(entity) != m_EntityParents.end(); -} - - -bool World::HasComponent(EntityID entity, std::string componentType) +bool World::HasComponent(EntityID entity, std::string componentType) const { ComponentPool* pool = m_ComponentPools.at(componentType); return pool->KnowsEntity(entity); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 08f68f98..e682297e 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -27,8 +27,6 @@ void Client::Start(World* world, EventBroker* eventBroker) m_World = world; // Subscribe to events - //m_EInputCommand = decltype(m_EInputCommand)(std::bind(&Client::OnInputCommand, this, std::placeholders::_1)); - //m_EventBroker->Subscribe(m_EInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Client::OnInputCommand); m_Socket.connect(m_ReceiverEndpoint); @@ -74,7 +72,6 @@ void Client::sendSnapshotToServer() auto player = m_World->GetComponent(m_PlayerDefinitions[m_PlayerID].EntityID, "Player"); - // See if any movement keys are down // We dont care if it's overwritten by later // if statement. Watcha gonna do, right! @@ -181,47 +178,53 @@ void Client::parseEventMessage(Packet& packet) } } +void Client::updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType) +{ + for (auto field : componentInfo.FieldsInOrder) { + ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(field); + if (fieldInfo.Type == "string") { + std::string& value = packet.ReadString(); + m_World->GetComponent(entityID, componentType)[fieldInfo.Name] = value; + } else { + memcpy(m_World->GetComponent(entityID, componentType).Data + fieldInfo.Offset, packet.ReadData(fieldInfo.Stride), fieldInfo.Stride); + } + } +} + +// Field parse void Client::parseSnapshot(Packet& packet) { std::string componentType = packet.ReadString(); - //LOG_INFO("A snapshot was parsed. first component type is: %s", componentType.c_str()); - int stride = packet.ReadPrimitive(); - int nrOfComponents = (packet.Size() - packet.DataReadSize()) / (stride + sizeof(EntityID)); - if (componentType == "Model") - return; - for (size_t i = 0; i < nrOfComponents; i++) { + while (packet.DataReadSize() < packet.Size()) { EntityID entityID = packet.ReadPrimitive(); - //ComponentWrapper model = m_World->GetComponent(entityID, "Model"); - //std::string checkPath = model["Resource"]; - // Check if entity exists - if (m_World->HasEntity(entityID)) { - // check if component exists + ComponentInfo componentInfo = m_World->GetComponents(componentType)->ComponentInfo(); + if (m_World->ValidEntity(entityID)) { if (m_World->HasComponent(entityID, componentType)) { - //Copy data to component - memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); + // If the entity and the component exists update it + updateFields(packet, componentInfo, entityID, componentType); + // if entity exists but not the component } else { - // If component doesen't exist // Create component m_World->AttachComponent(entityID, componentType); // Copy data to newly created component - memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); + updateFields(packet, componentInfo, entityID, componentType); } + // If the entity dosent exist nor the component } else { + //Create Entity // If entity dosen't exist EntityID newEntityID = m_World->CreateEntity(); // Check if EntityIDs are out of sync if (newEntityID != entityID) { - LOG_INFO("Client::parseSnapshot(Packet& packet): Newly created EntityID is not the same as the one sent by server \ - EntityIDs are out of sync"); + 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 - memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); + updateFields(packet, componentInfo, newEntityID, componentType); } - //ComponentWrapper model2 = m_World->GetComponent(entityID, "Model"); - //std::string checkPath2 = model2["Resource"]; } - } int Client::receive(char* data, size_t length) @@ -234,7 +237,7 @@ int Client::receive(char* data, size_t length) 0, error); if (error) { - //LOG_ERROR("receive: %s", error.message().c_str()); + LOG_ERROR("receive: %s", error.message().c_str()); } return bytesReceived; diff --git a/src/Engine/Network/Packet.cpp b/src/Engine/Network/Packet.cpp index 86a91f5d..2b2c7938 100644 --- a/src/Engine/Network/Packet.cpp +++ b/src/Engine/Network/Packet.cpp @@ -35,13 +35,13 @@ void Packet::Init(MessageType type, unsigned int & packetID) packetID++; } -void Packet::WriteString(std::string str) +void Packet::WriteString(const std::string& str) { // Message, add one extra byte for null terminator int sizeOfString = str.size() + 1; if (m_Offset + sizeOfString > m_MaxPacketSize) { - LOG_WARNING("Package::WriteString(): Data size in packet exceeded maximum package size.\n"); - return; + LOG_WARNING("Package::WriteString(): Data size in packet exceeded maximum package size. New size is %i bytes\n", m_MaxPacketSize*2); + resizeData(); } memcpy(m_Data + m_Offset, str.data(), sizeOfString * sizeof(char)); m_Offset += sizeOfString * sizeof(char); @@ -50,8 +50,8 @@ void Packet::WriteString(std::string str) void Packet::WriteData(char * data, int sizeOfData) { if (m_Offset + sizeOfData > m_MaxPacketSize) { - LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size.\n"); - return; + LOG_WARNING("Packet::WriteData(): Data size in packet exceeded maximum packet size. New size is %i bytes\n", m_MaxPacketSize*2); + resizeData(); } memcpy(m_Data + m_Offset, data, sizeOfData); m_Offset += sizeOfData; @@ -78,4 +78,24 @@ char * Packet::ReadData(int SizeOfData) unsigned int oldReturnDataOffset = m_ReturnDataOffset; m_ReturnDataOffset += SizeOfData; return (m_Data + oldReturnDataOffset); -} \ No newline at end of file +} + +void Packet::resizeData() +{ + + // Allocate memory to store our data in + char* holdData = new char[m_MaxPacketSize]; + // Copy our data to the newly allocated memory + memcpy(holdData, m_Data, m_Offset); + // Increase max packet size + m_MaxPacketSize = m_MaxPacketSize * 2; + // Delete our data + delete m_Data; + // Allocate twice the memory we had before + m_Data = new char[m_MaxPacketSize]; + // Copy our data to new location + memcpy(m_Data, holdData, m_Offset); + // Delete the memory allocated to hold our data + // while we resized the old data container. + delete holdData; +} diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 791f5a42..837a77d6 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -32,10 +32,6 @@ void Server::Close() void Server::readFromClients() { - // m_ThreadIsRunning might be unnecessary but the - // program crashed if it executed m_Socket.available() - // when closing the program. - while (m_Socket.available()) { try { bytesRead = receive(readBuffer, INPUTSIZE); @@ -44,7 +40,6 @@ void Server::readFromClients() } catch (const std::exception& err) { //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); } - } std::clock_t currentTime = std::clock(); // Send snapshot @@ -111,7 +106,7 @@ int Server::receive(char * data, size_t length) void Server::send(Packet& packet, int playerID) { - m_Socket.send_to( + int bytesSent = m_Socket.send_to( boost::asio::buffer(packet.Data(), packet.Size()), m_PlayerDefinitions[playerID].Endpoint, 0); @@ -152,120 +147,35 @@ void Server::broadcast(Packet& packet) } } } -// -//void Server::parseShitTest(Packet& packet) -//{ -// packet.ReadPrimitive(); // MessageType -// packet.ReadPrimitive(); // Packet ID -// -// std::string componentType = packet.ReadString(); -// //LOG_INFO("A snapshot was parsed. first component type is: %s", componentType.c_str()); -// int stride = packet.ReadPrimitive(); -// int nrOfComponents = (packet.Size() - packet.DataReadSize()) / (stride + sizeof(EntityID)); -// //if (componentType == "Model") -// // return; -// for (size_t i = 0; i < nrOfComponents; i++) { -// EntityID entityID = packet.ReadPrimitive(); -// ComponentWrapper model = m_World->GetComponent(entityID, "Model"); -// std::string checkPath = model["Resource"]; -// // Check if entity exists -// if (m_World->HasEntity(entityID)) { -// // check if component exists -// if (m_World->HasComponent(entityID, componentType)) { -// //Copy data to component -// memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); -// } else { -// // If component doesen't exist -// // Create component -// m_World->AttachComponent(entityID, componentType); -// // Copy data to newly created component -// memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); -// } -// } else { -// // If entity dosen't exist -// EntityID newEntityID = m_World->CreateEntity(); -// // Check if EntityIDs are out of sync -// if (newEntityID != entityID) { -// LOG_INFO("Client::parseSnapshot(Packet& packet): Newly created EntityID is not the same as the one sent by server \ -// EntityIDs are out of sync"); -// } -// m_World->AttachComponent(newEntityID, componentType); -// // Copy data to newly created component -// memcpy(m_World->GetComponent(entityID, componentType).Data, packet.ReadData(stride), stride); -// } -// ComponentWrapper model2 = m_World->GetComponent(entityID, "Model"); -// std::string checkPath2 = model2["Resource"]; -// } -//} +// Send snapshot fields void Server::sendSnapshot() { // Should time this std::unordered_map worldComponentPools = m_World->GetComponentPools(); - for (auto it : worldComponentPools) { + for (auto& it : worldComponentPools) { Packet packet(MessageType::Snapshot, m_SendPacketID); std::string componentType = it.first; - //if (componentType != "Model") - // continue; ComponentPool* componentPool = it.second; ComponentInfo componentInfo = componentPool->ComponentInfo(); packet.WriteString(componentInfo.Name); - packet.WritePrimitive(componentInfo.Meta.Stride); - for (auto componentWrapper : *componentPool) { - if (packet.Size() + componentInfo.Meta.Stride >= packet.MaxSize()) { - broadcast(packet); - //parseShitTest(packet); - // Packet destructor is called (which is what we want). - packet.Init(MessageType::Snapshot, m_SendPacketID); - // Add Component header - packet.WriteString(componentInfo.Name); - packet.WritePrimitive(componentInfo.Meta.Stride); - } - // Component data + + for (auto& componentWrapper : *componentPool) { packet.WritePrimitive(componentWrapper.EntityID); - packet.WriteData(componentWrapper.Data, componentWrapper.Info.Meta.Stride); + for (auto& componentField : componentWrapper.Info.FieldsInOrder) { + ComponentInfo::Field_t fieldInfo = componentInfo.Fields.at(componentField); + if (fieldInfo.Type == "string") { + std::string& value = componentWrapper[componentField]; + packet.WriteString(value); + } else { + packet.WriteData(componentWrapper.Data + fieldInfo.Offset, fieldInfo.Stride); + } + } } broadcast(packet); } } -//void Server::sendSnapshot() -//{ -// // Should time this -// std::unordered_map worldComponentPools = m_World->GetComponentPools(); -// for (auto it : worldComponentPools) { -// Packet packet(MessageType::Snapshot, m_SendPacketID); -// std::string componentType = it.first; -// ComponentPool* componentPool = it.second; -// ComponentInfo componentInfo = componentPool->ComponentInfo(); -// if (componentInfo.Name != "Transform") -// continue; -// packet.WriteString(componentInfo.Name); -// packet.WritePrimitive(componentInfo.Meta.Stride); -// auto componentWrapper = *componentPool->begin(); -// packet.WritePrimitive(componentWrapper.EntityID); -// packet.WriteData(componentWrapper.Data, componentWrapper.Info.Meta.Stride); -// -// for (auto componentWrapper : *componentPool) { -// //// When packet is full send it -// //if (packet.Size() + componentInfo.Meta.Stride >= packet.MaxSize()) { -// // broadcast(packet); -// // // Packet destructor is called (which is what we want). -// // packet.Init(MessageType::Snapshot, m_SendPacketID); -// // // Add Component header -// // packet.WriteString(componentInfo.Name); -// // packet.WritePrimitive(componentInfo.Meta.Stride); -// -// //} -// //// Component data -// //packet.WritePrimitive(componentWrapper.EntityID); -// //packet.WriteData(componentWrapper.Data, componentWrapper.Info.Meta.Stride); -// broadcast(packet); -// } -// broadcast(packet); -// } -//} - void Server::sendPing() { // Prints connected players ping @@ -275,7 +185,6 @@ void Server::sendPing() LOG_INFO("Last packetID received %i: Player %i's ping: %i", m_PacketID, i, ping); } } - // Create ping message Packet packet(MessageType::ServerPing, m_SendPacketID); packet.WriteString("Ping from server"); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index bf08d340..718c74c6 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -77,6 +77,8 @@ Game::Game(int argc, char* argv[]) networkFunction(); } m_LastTime = glfwGetTime(); + // For testing + debugInitialize(); } Game::~Game() @@ -113,7 +115,8 @@ void Game::Tick() if (m_IsClientOrServer) { m_ClientOrServer->Update(); } - + // For testing + debugTick(dt); // Iterate through systems and update world! m_SystemPipeline->Update(m_World, dt); m_Renderer->Update(dt); @@ -132,6 +135,33 @@ void Game::debugTick(double dt) m_EventBroker->Process(); } +// For testing +bool Game::debugOnInputCommand(const Events::InputCommand& e) +{ + if (e.Command == "SwitchToServer" && e.Value > 0) { + m_ClientOrServer->Close(); // memory leak for now, use delete when it works + //delete m_ClientOrServer; + m_ClientOrServer = new Server(); + LOG_INFO("Switching to server"); + m_ClientOrServer->Start(m_World, m_EventBroker); + } else if (e.Command == "SwitchToClient" && e.Value > 0) { + m_ClientOrServer->Close(); // memory leak for now, use delete when it works + //delete m_ClientOrServer; + m_ClientOrServer = new Client(m_Config); + m_ClientOrServer->Start(m_World, m_EventBroker); + LOG_INFO("Switching to client"); + } + + return false; +} + +// For testing +void Game::debugInitialize() +{ + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); +} + + void Game::networkFunction() { bool isServer = m_Config->Get("Networking.IsServer", false); From 56ac592d6d8355e1a25c1c2cf01b74fb979243b4 Mon Sep 17 00:00:00 2001 From: Jocke Date: Tue, 12 Jan 2016 14:16:01 +0100 Subject: [PATCH 5/7] Removed debug code from Game.cpp --- src/Game/Game.cpp | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 718c74c6..c84c556b 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -77,8 +77,6 @@ Game::Game(int argc, char* argv[]) networkFunction(); } m_LastTime = glfwGetTime(); - // For testing - debugInitialize(); } Game::~Game() @@ -115,8 +113,6 @@ void Game::Tick() if (m_IsClientOrServer) { m_ClientOrServer->Update(); } - // For testing - debugTick(dt); // Iterate through systems and update world! m_SystemPipeline->Update(m_World, dt); m_Renderer->Update(dt); @@ -135,33 +131,6 @@ void Game::debugTick(double dt) m_EventBroker->Process(); } -// For testing -bool Game::debugOnInputCommand(const Events::InputCommand& e) -{ - if (e.Command == "SwitchToServer" && e.Value > 0) { - m_ClientOrServer->Close(); // memory leak for now, use delete when it works - //delete m_ClientOrServer; - m_ClientOrServer = new Server(); - LOG_INFO("Switching to server"); - m_ClientOrServer->Start(m_World, m_EventBroker); - } else if (e.Command == "SwitchToClient" && e.Value > 0) { - m_ClientOrServer->Close(); // memory leak for now, use delete when it works - //delete m_ClientOrServer; - m_ClientOrServer = new Client(m_Config); - m_ClientOrServer->Start(m_World, m_EventBroker); - LOG_INFO("Switching to client"); - } - - return false; -} - -// For testing -void Game::debugInitialize() -{ - EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); -} - - void Game::networkFunction() { bool isServer = m_Config->Get("Networking.IsServer", false); From 228439953843aecc18c177d0cf63d55786b09ca0 Mon Sep 17 00:00:00 2001 From: Jocke Date: Tue, 12 Jan 2016 17:47:03 +0100 Subject: [PATCH 6/7] Removed Close method from Client, Server and Network. Removed legacy variable m_ThreadIsRunning in Client.h and Server.h. Removed m_EventBroker->Unsubscribe(m_EInputCommand) in Client destructor. --- include/Engine/Network/Client.h | 2 -- include/Engine/Network/Network.h | 1 - include/Engine/Network/Server.h | 5 ----- src/Engine/Network/Client.cpp | 9 --------- src/Engine/Network/Server.cpp | 6 ------ 5 files changed, 23 deletions(-) diff --git a/include/Engine/Network/Client.h b/include/Engine/Network/Client.h index b7bd9b38..a5488210 100644 --- a/include/Engine/Network/Client.h +++ b/include/Engine/Network/Client.h @@ -23,7 +23,6 @@ public: ~Client(); void Start(World* world, EventBroker* eventBroker) override; void Update() override; - void Close(); private: // Assio UDP logic boost::asio::ip::udp::endpoint m_ReceiverEndpoint; @@ -49,7 +48,6 @@ private: // Network logic PlayerDefinition m_PlayerDefinitions[MAXCONNECTIONS]; SnapshotDefinitions m_NextSnapshot; - bool m_ThreadIsRunning = true; double m_DurationOfPingTime; std::clock_t m_StartPingTime; // Use to check if we should send disconnect message diff --git a/include/Engine/Network/Network.h b/include/Engine/Network/Network.h index 8a50f061..cb86b941 100644 --- a/include/Engine/Network/Network.h +++ b/include/Engine/Network/Network.h @@ -14,7 +14,6 @@ public: virtual ~Network() { }; virtual void Start(World* m_world, EventBroker *eventBroker) = 0; virtual void Update() = 0; - virtual void Close() = 0; }; #endif \ No newline at end of file diff --git a/include/Engine/Network/Server.h b/include/Engine/Network/Server.h index 58ee2631..893eed0b 100644 --- a/include/Engine/Network/Server.h +++ b/include/Engine/Network/Server.h @@ -20,8 +20,6 @@ public: ~Server(); void Start(World* m_world, EventBroker *eventBroker) override; void Update() override; - void Close(); - private: // UDP logic boost::asio::ip::udp::endpoint m_ReceiverEndpoint; @@ -55,9 +53,6 @@ private: unsigned int m_PacketID; unsigned int m_PreviousPacketID; unsigned int m_SendPacketID; - - // Close logic - bool m_ThreadIsRunning = true; // Private member functions int receive(char* data, size_t length); diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index e682297e..b8849ed0 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -17,7 +17,6 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService) Client::~Client() { - m_EventBroker->Unsubscribe(m_EInputCommand); } void Client::Start(World* world, EventBroker* eventBroker) @@ -38,14 +37,6 @@ void Client::Update() readFromServer(); } -void Client::Close() -{ - disconnect(); - m_ThreadIsRunning = false; - m_Socket.close(); - m_EventBroker->Unsubscribe(m_EInputCommand); -} - void Client::readFromServer() { while (m_Socket.available()) { diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 837a77d6..07fed65b 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -24,12 +24,6 @@ void Server::Update() readFromClients(); } -void Server::Close() -{ - m_ThreadIsRunning = false; - m_Socket.close(); -} - void Server::readFromClients() { while (m_Socket.available()) { From 627108c6ee9bdace4dfbc2aff2e69ed89fa25681 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 14 Jan 2016 18:04:13 +0100 Subject: [PATCH 7/7] Fixes for #30 # Conflicts: # src/Game/Game.cpp --- include/Engine/Core/Transform.h | 57 ++---------- include/Engine/Rendering/RenderSystem.h | 10 +- src/Engine/Core/Transform.cpp | 52 +++++++++++ src/Engine/Editor/EditorSystem.cpp | 3 + src/Engine/Rendering/PickingPass.cpp | 6 +- src/Engine/Rendering/RenderSystem.cpp | 118 +++++++++++------------- src/Game/Game.cpp | 4 +- 7 files changed, 126 insertions(+), 124 deletions(-) create mode 100644 src/Engine/Core/Transform.cpp diff --git a/include/Engine/Core/Transform.h b/include/Engine/Core/Transform.h index c43e4386..474a7bdb 100644 --- a/include/Engine/Core/Transform.h +++ b/include/Engine/Core/Transform.h @@ -4,59 +4,14 @@ #include "../GLM.h" #include "World.h" -static class Transform +namespace Transform { -public: - static glm::vec3 AbsolutePosition(World* world, EntityID entity) - { - glm::vec3 position; - while (entity != EntityID_Invalid) { - ComponentWrapper transform = world->GetComponent(entity, "Transform"); - EntityID parent = world->GetParent(entity); - position += AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"]; - entity = parent; - } +glm::vec3 AbsolutePosition(World* world, EntityID entity); +glm::quat AbsoluteOrientation(World* world, EntityID entity); +glm::vec3 AbsoluteScale(World* world, EntityID entity); +glm::mat4 ModelMatrix(EntityID entity, World* world); - return position; - }; - - static glm::quat AbsoluteOrientation(World* world, EntityID entity) - { - glm::quat orientation; - - while (entity != EntityID_Invalid) { - ComponentWrapper transform = world->GetComponent(entity, "Transform"); - orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation; - entity = world->GetParent(entity); - } - - return orientation; - }; - - static glm::vec3 AbsoluteScale(World* world, EntityID entity) - { - glm::vec3 scale(1.f); - - while (entity != EntityID_Invalid) { - ComponentWrapper transform = world->GetComponent(entity, "Transform"); - scale *= (glm::vec3)transform["Scale"]; - entity = world->GetParent(entity); - } - - return scale; - }; - - static glm::mat4 ModelMatrix(EntityID entity, World* world) - { - glm::vec3 position = Transform::AbsolutePosition(world, entity); - glm::quat orientation = Transform::AbsoluteOrientation(world, entity); - glm::vec3 scale = Transform::AbsoluteScale(world, entity); - - glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale); - return modelMatrix; - } - -}; +} #endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderSystem.h b/include/Engine/Rendering/RenderSystem.h index 93e7233f..efe3b88c 100644 --- a/include/Engine/Rendering/RenderSystem.h +++ b/include/Engine/Rendering/RenderSystem.h @@ -14,22 +14,24 @@ #include "ModelJob.h" #include "Renderer.h" #include "../Core/Transform.h" +#include "DebugCameraInputController.h" class RenderSystem : public ImpureSystem { public: RenderSystem(EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame); + ~RenderSystem(); virtual void Update(World* world, double dt) override; private: World* m_World = nullptr; - const IRenderer* m_Renderer = nullptr; + const IRenderer* m_Renderer; RenderFrame* m_RenderFrame; bool m_SwitchCamera = false; - Camera* m_Camera = nullptr; - Camera* m_DefaultCamera = nullptr; + Camera* m_Camera; + DebugCameraInputController* m_DebugCameraInputController; std::list m_CameraComponents; @@ -41,8 +43,6 @@ private: void updateCamera(World* world, double dt); void updateProjectionMatrix(ComponentWrapper& cameraComponent); - glm::mat4 m_ViewMatrix; - glm::mat4 m_ProjectionMatrix; void fillModels(std::list>& jobs, World* world); diff --git a/src/Engine/Core/Transform.cpp b/src/Engine/Core/Transform.cpp new file mode 100644 index 00000000..cbc405a3 --- /dev/null +++ b/src/Engine/Core/Transform.cpp @@ -0,0 +1,52 @@ +#include "Core/Transform.h" + +glm::vec3 Transform::AbsolutePosition(World* world, EntityID entity) +{ + glm::vec3 position; + + while (entity != EntityID_Invalid) { + ComponentWrapper transform = world->GetComponent(entity, "Transform"); + EntityID parent = world->GetParent(entity); + position += Transform::AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"]; + entity = parent; + } + + return position; +} + +glm::quat Transform::AbsoluteOrientation(World* world, EntityID entity) +{ + glm::quat orientation; + + while (entity != EntityID_Invalid) { + ComponentWrapper transform = world->GetComponent(entity, "Transform"); + orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation; + entity = world->GetParent(entity); + } + + return orientation; +} + +glm::vec3 Transform::AbsoluteScale(World* world, EntityID entity) +{ + glm::vec3 scale(1.f); + + while (entity != EntityID_Invalid) { + ComponentWrapper transform = world->GetComponent(entity, "Transform"); + scale *= (glm::vec3)transform["Scale"]; + entity = world->GetParent(entity); + } + + return scale; +} + +glm::mat4 Transform::ModelMatrix(EntityID entity, World* world) +{ + glm::vec3 position = Transform::AbsolutePosition(world, entity); + glm::quat orientation = Transform::AbsoluteOrientation(world, entity); + glm::vec3 scale = Transform::AbsoluteScale(world, entity); + + glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale); + return modelMatrix; +} + diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index de57c705..94e848c0 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -124,6 +124,9 @@ bool EditorSystem::OnMouseMove(const Events::MouseMove& e) if (m_Selection == 0) { return false; } + if (m_Camera == nullptr) { + return false; + } auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); glm::vec3 widgetOrientation = widgetTransform["Orientation"]; diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index aa42a961..6800df1d 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -109,7 +109,7 @@ void PickingPass::ClearPicking() { m_PickingColorsToEntity.clear(); m_EntityColors.clear(); - m_ColorCounter[0] = 0; + m_ColorCounter[0] = 1; m_ColorCounter[1] = 0; m_PickingBuffer.Bind(); @@ -138,10 +138,10 @@ PickData PickingPass::Pick(glm::vec2 screenCoord) pickInfo = it->second; } else { pickData.Entity = EntityID_Invalid; + return pickData; } - pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, resolution, pickInfo.Camera->ProjectionMatrix(), pickInfo.Camera->ViewMatrix()); - + pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, resolution, pickInfo.Camera->ProjectionMatrix(), pickInfo.Camera->ViewMatrix()); pickData.Entity = pickInfo.Entity; pickData.Camera = pickInfo.Camera; pickData.World = pickInfo.World; diff --git a/src/Engine/Rendering/RenderSystem.cpp b/src/Engine/Rendering/RenderSystem.cpp index d6cdb9b3..1f2bac9d 100644 --- a/src/Engine/Rendering/RenderSystem.cpp +++ b/src/Engine/Rendering/RenderSystem.cpp @@ -1,5 +1,4 @@ #include "Rendering/RenderSystem.h" -#include "Rendering/DebugCameraInputController.h" RenderSystem::RenderSystem(EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame) :ImpureSystem(eventBrokerer) { @@ -8,11 +7,14 @@ RenderSystem::RenderSystem(EventBroker* eventBrokerer, const IRenderer* renderer EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera); EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand); - m_DefaultCamera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f); - m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10)); - if (m_Camera == nullptr) { - m_Camera = m_DefaultCamera; - } + m_Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f); + m_DebugCameraInputController = new DebugCameraInputController(eventBrokerer, -1); +} + +RenderSystem::~RenderSystem() +{ + delete m_Camera; + delete m_DebugCameraInputController; } bool RenderSystem::OnSetCamera(const Events::SetCamera &event) @@ -54,14 +56,11 @@ void RenderSystem::switchCamera(EntityID entity) void RenderSystem::updateProjectionMatrix(ComponentWrapper& cameraComponent) { double fov = cameraComponent["FOV"]; - double aspectRatio = m_Renderer->Resolution().Width / m_Renderer->Resolution().Height; + double aspectRatio = (float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height; double nearClip = cameraComponent["NearClip"]; double farClip = cameraComponent["FarClip"]; - double fovY = atan(tan(glm::radians(fov)/2.0) * aspectRatio) * 2.0; - m_ProjectionMatrix = glm::perspective(fovY, aspectRatio, nearClip, farClip); - - m_Camera->SetFOV(fovY); + m_Camera->SetFOV(glm::radians(fov)); m_Camera->SetAspectRatio(aspectRatio); m_Camera->SetNearClip(nearClip); m_Camera->SetFarClip(farClip); @@ -129,66 +128,61 @@ void RenderSystem::Update(World* world, double dt) void RenderSystem::updateCamera(World* world, double dt) { - - static DebugCameraInputController firstPersonInputController(m_EventBroker, -1); - - if (m_SwitchCamera) { - auto cameras = world->GetComponents("Camera"); - for (auto it = cameras->begin(); it != cameras->end(); it++) { - if ((*it).EntityID == m_CurrentCamera) { - it++; - if (it != cameras->end()) { - switchCamera((*it).EntityID); - } else { - switchCamera((*cameras->begin()).EntityID); - } - break; + if (m_SwitchCamera) { + auto cameras = world->GetComponents("Camera"); + for (auto it = cameras->begin(); it != cameras->end(); it++) { + if ((*it).EntityID == m_CurrentCamera) { + it++; + if (it != cameras->end()) { + switchCamera((*it).EntityID); + } else { + switchCamera((*cameras->begin()).EntityID); } + break; } + } + ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); + ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); + + m_DebugCameraInputController->SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"])); + m_DebugCameraInputController->SetPosition(cameraTransform["Position"]); + } + + if (m_World->ValidEntity(m_CurrentCamera)) { + if (world->HasComponent(m_CurrentCamera, "Camera") && world->HasComponent(m_CurrentCamera, "Transform")) { ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); - firstPersonInputController.SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"])); - firstPersonInputController.SetPosition(cameraTransform["Position"]); - - } + m_DebugCameraInputController->Update(dt); + (glm::vec3&)cameraTransform["Orientation"] = glm::eulerAngles(m_DebugCameraInputController->Orientation()); + (glm::vec3&)cameraTransform["Position"] = m_DebugCameraInputController->Position(); + + glm::vec3 position = Transform::AbsolutePosition(world, m_CurrentCamera); + glm::quat orientation = Transform::AbsoluteOrientation(world, m_CurrentCamera); + + m_Camera->SetPosition(position); + m_Camera->SetOrientation(orientation); + + updateProjectionMatrix(cameraComponent); + + } + } else { + m_Camera = m_Camera; + + auto cameras = world->GetComponents("Camera"); + if (cameras != nullptr) { + if (cameras->begin() != cameras->end()) { + ComponentWrapper& cameraC = *cameras->begin(); + switchCamera(cameraC.EntityID); - if (m_World->ValidEntity(m_CurrentCamera)) { - if (world->HasComponent(m_CurrentCamera, "Camera") && world->HasComponent(m_CurrentCamera, "Transform")) { ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); - firstPersonInputController.Update(dt); - (glm::vec3&)cameraTransform["Orientation"] = glm::eulerAngles(firstPersonInputController.Orientation()); - (glm::vec3&)cameraTransform["Position"] = firstPersonInputController.Position(); - - glm::vec3 position = Transform::AbsolutePosition(world, m_CurrentCamera); - glm::quat orientation = Transform::AbsoluteOrientation(world, m_CurrentCamera); - - m_Camera->SetPosition(position); - m_Camera->SetOrientation(orientation); - - updateProjectionMatrix(cameraComponent); - - } - } else { - m_Camera = m_DefaultCamera; - - auto cameras = world->GetComponents("Camera"); - if (cameras != nullptr) { - if (cameras->begin() != cameras->end()) { - ComponentWrapper& cameraC = *cameras->begin(); - switchCamera(cameraC.EntityID); - - ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera"); - ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform"); - - firstPersonInputController.SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"])); - firstPersonInputController.SetPosition(cameraTransform["Position"]); - } + m_DebugCameraInputController->SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"])); + m_DebugCameraInputController->SetPosition(cameraTransform["Position"]); } } + } - m_Camera->UpdateViewMatrix(); -} - + m_Camera->UpdateViewMatrix(); +} \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 1cfb95e0..ba660a7d 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -31,6 +31,7 @@ Game::Game(int argc, char* argv[]) )); m_Renderer->Initialize(); //m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get("Video.FOV", 90.f))); + m_RenderFrame = new RenderFrame(); // Create input manager m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker); @@ -55,8 +56,6 @@ Game::Game(int argc, char* argv[]) fp.MergeEntities(m_World); } - m_RenderFrame = new RenderFrame(); - // Create system pipeline m_SystemPipeline = new SystemPipeline(m_EventBroker); @@ -72,7 +71,6 @@ Game::Game(int argc, char* argv[]) ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); - ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame);